// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ppapi/c/pp_var.h"
#include "ppapi/shared_impl/private/ppb_char_set_shared.h"
#include "ppapi/thunk/thunk.h"
#include "ppapi/thunk/enter.h"

namespace ppapi {
namespace thunk {

namespace {

char* UTF16ToCharSetDeprecated(PP_Instance instance,
                               const uint16_t* utf16, uint32_t utf16_len,
                               const char* output_char_set,
                               PP_CharSet_ConversionError on_error,
                               uint32_t* output_length) {
  // We validate the instance just to make sure we can make changes in the
  // future and assume people pass proper instances.
  EnterInstance enter(instance);
  if (enter.failed())
    return NULL;

  return PPB_CharSet_Shared::UTF16ToCharSetDeprecated(
      utf16, utf16_len, output_char_set, on_error, output_length);
}

PP_Bool UTF16ToCharSet(const uint16_t utf16[],
                       uint32_t utf16_len,
                       const char* output_char_set,
                       PP_CharSet_Trusted_ConversionError on_error,
                       char* output_buffer,
                       uint32_t* output_length) {
  // This interface is a bit odd because it contains a function
  // (GetDefaultCharSet) that must be called on the instance object and
  // proxied, but the rest of the functions are implemented in the plugin
  // process by just calling base functions.
  //
  // We could have PPB_Instance_API functions for the two charset conversion
  // functions, and then have the instance impl and proxy call through to the
  // shared_impl. That would be more consistent, and we may want to do that if
  // this file is autogenerated in the future. For now, however, it's less code
  // to just call the shared_impl code directly here.
  return PPB_CharSet_Shared::UTF16ToCharSet(
      utf16, utf16_len, output_char_set, on_error,
      output_buffer, output_length);
}

uint16_t* CharSetToUTF16Deprecated(PP_Instance instance,
                                   const char* input, uint32_t input_len,
                                   const char* input_char_set,
                                   PP_CharSet_ConversionError on_error,
                                   uint32_t* output_length) {
  // We validate the instance just to make sure we can make changes in the
  // future and assume people pass proper instances.
  EnterInstance enter(instance);
  if (enter.failed())
    return NULL;

  return PPB_CharSet_Shared::CharSetToUTF16Deprecated(
      input, input_len, input_char_set, on_error, output_length);
}

PP_Bool CharSetToUTF16(const char* input,
                       uint32_t input_len,
                       const char* input_char_set,
                       PP_CharSet_Trusted_ConversionError on_error,
                       uint16_t* output_buffer,
                       uint32_t* output_utf16_length) {
  return PPB_CharSet_Shared::CharSetToUTF16(
      input, input_len, input_char_set, on_error,
      output_buffer, output_utf16_length);
}

PP_Var GetDefaultCharSet(PP_Instance instance) {
  EnterInstance enter(instance);
  if (enter.failed())
    return PP_MakeUndefined();
  return enter.functions()->GetDefaultCharSet(instance);
}

const PPB_CharSet_Dev g_ppb_char_set_thunk = {
  &UTF16ToCharSetDeprecated,
  &CharSetToUTF16Deprecated,
  &GetDefaultCharSet
};

const PPB_CharSet_Trusted_1_0 g_ppb_char_set_trusted_thunk = {
  &UTF16ToCharSet,
  &CharSetToUTF16,
  &GetDefaultCharSet
};

}  // namespace

const PPB_CharSet_Dev_0_4* GetPPB_CharSet_Dev_0_4_Thunk() {
  return &g_ppb_char_set_thunk;
}

const PPB_CharSet_Trusted_1_0* GetPPB_CharSet_Trusted_1_0_Thunk() {
  return &g_ppb_char_set_trusted_thunk;
}

}  // namespace thunk
}  // namespace ppapi
