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