1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file.
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#ifndef GIN_CONVERTER_H_
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#define GIN_CONVERTER_H_
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <string>
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <vector>
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/strings/string_piece.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "gin/gin_export.h"
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "v8/include/v8.h"
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace gin {
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template<typename T, typename Enable = void>
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)struct Converter {};
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)template<>
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct GIN_EXPORT Converter<bool> {
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    bool val);
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static bool FromV8(v8::Isolate* isolate,
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     v8::Handle<v8::Value> val,
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     bool* out);
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)template<>
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct GIN_EXPORT Converter<int32_t> {
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    int32_t val);
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static bool FromV8(v8::Isolate* isolate,
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     v8::Handle<v8::Value> val,
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     int32_t* out);
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)template<>
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct GIN_EXPORT Converter<uint32_t> {
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    uint32_t val);
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static bool FromV8(v8::Isolate* isolate,
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     v8::Handle<v8::Value> val,
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     uint32_t* out);
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)template<>
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct GIN_EXPORT Converter<int64_t> {
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Warning: JavaScript cannot represent 64 integers precisely.
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    int64_t val);
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static bool FromV8(v8::Isolate* isolate,
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     v8::Handle<v8::Value> val,
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     int64_t* out);
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)template<>
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct GIN_EXPORT Converter<uint64_t> {
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Warning: JavaScript cannot represent 64 integers precisely.
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    uint64_t val);
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static bool FromV8(v8::Isolate* isolate,
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     v8::Handle<v8::Value> val,
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     uint64_t* out);
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)template<>
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct GIN_EXPORT Converter<float> {
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                    float val);
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static bool FromV8(v8::Isolate* isolate,
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     v8::Handle<v8::Value> val,
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     float* out);
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template<>
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct GIN_EXPORT Converter<double> {
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    double val);
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static bool FromV8(v8::Isolate* isolate,
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     v8::Handle<v8::Value> val,
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     double* out);
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)template<>
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct GIN_EXPORT Converter<base::StringPiece> {
87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                    const base::StringPiece& val);
89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // No conversion out is possible because StringPiece does not contain storage.
90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)};
91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template<>
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct GIN_EXPORT Converter<std::string> {
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    const std::string& val);
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static bool FromV8(v8::Isolate* isolate,
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     v8::Handle<v8::Value> val,
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     std::string* out);
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)template<>
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct GIN_EXPORT Converter<v8::Handle<v8::Function> > {
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static bool FromV8(v8::Isolate* isolate,
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     v8::Handle<v8::Value> val,
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     v8::Handle<v8::Function>* out);
106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)template<>
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct GIN_EXPORT Converter<v8::Handle<v8::Object> > {
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    v8::Handle<v8::Object> val);
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static bool FromV8(v8::Isolate* isolate,
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     v8::Handle<v8::Value> val,
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     v8::Handle<v8::Object>* out);
115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)template<>
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct GIN_EXPORT Converter<v8::Handle<v8::ArrayBuffer> > {
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    v8::Handle<v8::ArrayBuffer> val);
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static bool FromV8(v8::Isolate* isolate,
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     v8::Handle<v8::Value> val,
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     v8::Handle<v8::ArrayBuffer>* out);
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)template<>
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct GIN_EXPORT Converter<v8::Handle<v8::External> > {
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    v8::Handle<v8::External> val);
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static bool FromV8(v8::Isolate* isolate,
131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     v8::Handle<v8::Value> val,
132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     v8::Handle<v8::External>* out);
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)template<>
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct GIN_EXPORT Converter<v8::Handle<v8::Value> > {
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    v8::Handle<v8::Value> val);
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static bool FromV8(v8::Isolate* isolate,
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     v8::Handle<v8::Value> val,
141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     v8::Handle<v8::Value>* out);
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)template<typename T>
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)struct Converter<std::vector<T> > {
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    const std::vector<T>& val) {
148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    v8::Handle<v8::Array> result(
149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        v8::Array::New(isolate, static_cast<int>(val.size())));
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    for (size_t i = 0; i < val.size(); ++i) {
151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      result->Set(static_cast<int>(i), Converter<T>::ToV8(isolate, val[i]));
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return result;
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static bool FromV8(v8::Isolate* isolate,
157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     v8::Handle<v8::Value> val,
158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     std::vector<T>* out) {
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!val->IsArray())
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return false;
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    std::vector<T> result;
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    v8::Handle<v8::Array> array(v8::Handle<v8::Array>::Cast(val));
164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    uint32_t length = array->Length();
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    for (uint32_t i = 0; i < length; ++i) {
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      T item;
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      if (!Converter<T>::FromV8(isolate, array->Get(i), &item))
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        return false;
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      result.push_back(item);
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    out->swap(result);
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return true;
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Convenience functions that deduce T.
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)template<typename T>
179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)v8::Handle<v8::Value> ConvertToV8(v8::Isolate* isolate, T input) {
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return Converter<T>::ToV8(isolate, input);
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)GIN_EXPORT inline v8::Handle<v8::String> StringToV8(
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    v8::Isolate* isolate,
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::StringPiece& input) {
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return ConvertToV8(isolate, input).As<v8::String>();
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)GIN_EXPORT v8::Handle<v8::String> StringToSymbol(v8::Isolate* isolate,
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                 const base::StringPiece& val);
191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)template<typename T>
193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool ConvertFromV8(v8::Isolate* isolate, v8::Handle<v8::Value> input,
194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                   T* result) {
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return Converter<T>::FromV8(isolate, input, result);
196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)GIN_EXPORT std::string V8ToString(v8::Handle<v8::Value> value);
199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace gin
201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif  // GIN_CONVERTER_H_
203