15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/private/ppb_char_set_shared.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/icu_string_conversions.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/dev/ppb_memory_dev.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/thunk/thunk.h" 12ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "third_party/icu/source/common/unicode/ucnv.h" 13ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "third_party/icu/source/common/unicode/ucnv_cb.h" 14ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "third_party/icu/source/common/unicode/ucnv_err.h" 15ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "third_party/icu/source/common/unicode/ustring.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ppapi { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_CharSet_Trusted_ConversionError DeprecatedToConversionError( 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_CharSet_ConversionError on_error) { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (on_error) { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_CHARSET_CONVERSIONERROR_SKIP: 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_CHARSET_TRUSTED_CONVERSIONERROR_SKIP; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_CHARSET_CONVERSIONERROR_SUBSTITUTE: 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_CHARSET_TRUSTED_CONVERSIONERROR_SUBSTITUTE; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_CHARSET_CONVERSIONERROR_FAIL: 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_CHARSET_TRUSTED_CONVERSIONERROR_FAIL; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Converts the given PP error handling behavior to the version in base, 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// placing the result in |*result| and returning true on success. Returns false 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// if the enum is invalid. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PPToBaseConversionError(PP_CharSet_Trusted_ConversionError on_error, 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::OnStringConversionError::Type* result) { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (on_error) { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_CHARSET_TRUSTED_CONVERSIONERROR_FAIL: 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = base::OnStringConversionError::FAIL; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_CHARSET_TRUSTED_CONVERSIONERROR_SKIP: 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = base::OnStringConversionError::SKIP; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_CHARSET_TRUSTED_CONVERSIONERROR_SUBSTITUTE: 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = base::OnStringConversionError::SUBSTITUTE; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The "substitution" behavior of this function does not match the 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// implementation in base, so we partially duplicate the code from 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// icu_string_conversions.cc with the correct error handling setup required 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// by the PPAPI interface. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)char* PPB_CharSet_Shared::UTF16ToCharSetDeprecated( 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint16_t* utf16, 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t utf16_len, 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* output_char_set, 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_CharSet_ConversionError deprecated_on_error, 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t* output_length) { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *output_length = 0; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_CharSet_Trusted_ConversionError on_error = DeprecatedToConversionError( 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deprecated_on_error); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Compute required length. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t required_length = 0; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UTF16ToCharSet(utf16, utf16_len, output_char_set, on_error, NULL, 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &required_length); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Our output is null terminated, so need one more byte. 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* ret_buf = static_cast<char*>( 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thunk::GetPPB_Memory_Dev_0_1_Thunk()->MemAlloc(required_length + 1)); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do the conversion into the buffer. 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Bool result = UTF16ToCharSet(utf16, utf16_len, output_char_set, on_error, 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret_buf, &required_length); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == PP_FALSE) { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thunk::GetPPB_Memory_Dev_0_1_Thunk()->MemFree(ret_buf); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret_buf[required_length] = 0; // Null terminate. 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *output_length = required_length; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ret_buf; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Bool PPB_CharSet_Shared::UTF16ToCharSet( 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint16_t utf16[], 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t utf16_len, 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* output_char_set, 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_CharSet_Trusted_ConversionError on_error, 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* output_buffer, 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t* output_length) { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!utf16 || !output_char_set || !output_length) { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *output_length = 0; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_FALSE; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UErrorCode status = U_ZERO_ERROR; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UConverter* converter = ucnv_open(output_char_set, &status); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!U_SUCCESS(status)) { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *output_length = 0; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_FALSE; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Setup our error handler. 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (on_error) { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_CHARSET_CONVERSIONERROR_FAIL: 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ucnv_setFromUCallBack(converter, UCNV_FROM_U_CALLBACK_STOP, 0, 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, NULL, &status); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_CHARSET_CONVERSIONERROR_SKIP: 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ucnv_setFromUCallBack(converter, UCNV_FROM_U_CALLBACK_SKIP, 0, 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, NULL, &status); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_CHARSET_CONVERSIONERROR_SUBSTITUTE: { 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ICU sets the substitution char for some character sets (like latin1) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to be the ASCII "substitution character" (26). We want to use '?' 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // instead for backwards-compat with Windows behavior. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char subst_chars[32]; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int8_t subst_chars_len = 32; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ucnv_getSubstChars(converter, subst_chars, &subst_chars_len, &status); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (subst_chars_len == 1 && subst_chars[0] == 26) { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Override to the question mark character if possible. When using 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // setSubstString, the input is a Unicode character. The function will 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // try to convert it to the destination character set and fail if that 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // can not be converted to the destination character set. 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We just ignore any failure. If the dest char set has no 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // representation for '?', then we'll just stick to the ICU default 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // substitution character. 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UErrorCode subst_status = U_ZERO_ERROR; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UChar question_mark = '?'; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ucnv_setSubstString(converter, &question_mark, 1, &subst_status); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ucnv_setFromUCallBack(converter, UCNV_FROM_U_CALLBACK_SUBSTITUTE, 0, 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, NULL, &status); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *output_length = 0; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ucnv_close(converter); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_FALSE; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ucnv_fromUChars returns required size not including terminating null. 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *output_length = static_cast<uint32_t>(ucnv_fromUChars( 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) converter, output_buffer, output_buffer ? *output_length : 0, 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<const UChar*>(utf16), utf16_len, &status)); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ucnv_close(converter); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (status == U_BUFFER_OVERFLOW_ERROR) { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't treat this as a fatal error since we need to return the string 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // size. 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_TRUE; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (!U_SUCCESS(status)) { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *output_length = 0; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_FALSE; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_TRUE; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint16_t* PPB_CharSet_Shared::CharSetToUTF16Deprecated( 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* input, 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t input_len, 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* input_char_set, 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_CharSet_ConversionError deprecated_on_error, 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t* output_length) { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *output_length = 0; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_CharSet_Trusted_ConversionError on_error = DeprecatedToConversionError( 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deprecated_on_error); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Compute required length. 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t required_length = 0; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CharSetToUTF16(input, input_len, input_char_set, on_error, NULL, 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &required_length); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Our output is null terminated, so need one more byte. 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16_t* ret_buf = static_cast<uint16_t*>( 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thunk::GetPPB_Memory_Dev_0_1_Thunk()->MemAlloc( 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (required_length + 1) * sizeof(uint16_t))); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do the conversion into the buffer. 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Bool result = CharSetToUTF16(input, input_len, input_char_set, on_error, 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret_buf, &required_length); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == PP_FALSE) { 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thunk::GetPPB_Memory_Dev_0_1_Thunk()->MemFree(ret_buf); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret_buf[required_length] = 0; // Null terminate. 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *output_length = required_length; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ret_buf; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Bool PPB_CharSet_Shared::CharSetToUTF16( 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* input, 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t input_len, 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* input_char_set, 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_CharSet_Trusted_ConversionError on_error, 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16_t* output_buffer, 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t* output_utf16_length) { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!input || !input_char_set || !output_utf16_length) { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *output_utf16_length = 0; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_FALSE; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::OnStringConversionError::Type base_on_error; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!PPToBaseConversionError(on_error, &base_on_error)) { 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *output_utf16_length = 0; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_FALSE; // Invalid enum value. 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We can convert this call to the implementation in base to avoid code 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // duplication, although this does introduce an extra copy of the data. 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::string16 output; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!base::CodepageToUTF16(std::string(input, input_len), input_char_set, 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base_on_error, &output)) { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *output_utf16_length = 0; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_FALSE; 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (output_buffer) { 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(output_buffer, output.c_str(), 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::min(*output_utf16_length, static_cast<uint32_t>(output.size())) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sizeof(uint16_t)); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *output_utf16_length = static_cast<uint32_t>(output.size()); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_TRUE; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ppapi 240