1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef GIN_CONVERTER_H_
6 #define GIN_CONVERTER_H_
11 #include "base/logging.h"
12 #include "base/strings/string_piece.h"
13 #include "gin/gin_export.h"
14 #include "v8/include/v8.h"
18 template<typename KeyType
>
19 bool SetProperty(v8::Isolate
* isolate
,
20 v8::Local
<v8::Object
> object
,
22 v8::Local
<v8::Value
> value
) {
23 auto maybe
= object
->Set(isolate
->GetCurrentContext(), key
, value
);
24 return !maybe
.IsNothing() && maybe
.FromJust();
28 struct ToV8ReturnsMaybe
{
29 static const bool value
= false;
32 template<typename T
, typename Enable
= void>
36 struct GIN_EXPORT Converter
<bool> {
37 static v8::Local
<v8::Value
> ToV8(v8::Isolate
* isolate
,
39 static bool FromV8(v8::Isolate
* isolate
,
40 v8::Local
<v8::Value
> val
,
45 struct GIN_EXPORT Converter
<int32_t> {
46 static v8::Local
<v8::Value
> ToV8(v8::Isolate
* isolate
,
48 static bool FromV8(v8::Isolate
* isolate
,
49 v8::Local
<v8::Value
> val
,
54 struct GIN_EXPORT Converter
<uint32_t> {
55 static v8::Local
<v8::Value
> ToV8(v8::Isolate
* isolate
,
57 static bool FromV8(v8::Isolate
* isolate
,
58 v8::Local
<v8::Value
> val
,
63 struct GIN_EXPORT Converter
<int64_t> {
64 // Warning: JavaScript cannot represent 64 integers precisely.
65 static v8::Local
<v8::Value
> ToV8(v8::Isolate
* isolate
,
67 static bool FromV8(v8::Isolate
* isolate
,
68 v8::Local
<v8::Value
> val
,
73 struct GIN_EXPORT Converter
<uint64_t> {
74 // Warning: JavaScript cannot represent 64 integers precisely.
75 static v8::Local
<v8::Value
> ToV8(v8::Isolate
* isolate
,
77 static bool FromV8(v8::Isolate
* isolate
,
78 v8::Local
<v8::Value
> val
,
83 struct GIN_EXPORT Converter
<float> {
84 static v8::Local
<v8::Value
> ToV8(v8::Isolate
* isolate
,
86 static bool FromV8(v8::Isolate
* isolate
,
87 v8::Local
<v8::Value
> val
,
92 struct GIN_EXPORT Converter
<double> {
93 static v8::Local
<v8::Value
> ToV8(v8::Isolate
* isolate
,
95 static bool FromV8(v8::Isolate
* isolate
,
96 v8::Local
<v8::Value
> val
,
101 struct GIN_EXPORT Converter
<base::StringPiece
> {
102 // This crashes when val.size() > v8::String::kMaxLength.
103 static v8::Local
<v8::Value
> ToV8(v8::Isolate
* isolate
,
104 const base::StringPiece
& val
);
105 // No conversion out is possible because StringPiece does not contain storage.
109 struct GIN_EXPORT Converter
<std::string
> {
110 // This crashes when val.size() > v8::String::kMaxLength.
111 static v8::Local
<v8::Value
> ToV8(v8::Isolate
* isolate
,
112 const std::string
& val
);
113 static bool FromV8(v8::Isolate
* isolate
,
114 v8::Local
<v8::Value
> val
,
119 struct GIN_EXPORT Converter
<v8::Local
<v8::Function
> > {
120 static bool FromV8(v8::Isolate
* isolate
,
121 v8::Local
<v8::Value
> val
,
122 v8::Local
<v8::Function
>* out
);
126 struct GIN_EXPORT Converter
<v8::Local
<v8::Object
> > {
127 static v8::Local
<v8::Value
> ToV8(v8::Isolate
* isolate
,
128 v8::Local
<v8::Object
> val
);
129 static bool FromV8(v8::Isolate
* isolate
,
130 v8::Local
<v8::Value
> val
,
131 v8::Local
<v8::Object
>* out
);
135 struct GIN_EXPORT Converter
<v8::Local
<v8::ArrayBuffer
> > {
136 static v8::Local
<v8::Value
> ToV8(v8::Isolate
* isolate
,
137 v8::Local
<v8::ArrayBuffer
> val
);
138 static bool FromV8(v8::Isolate
* isolate
,
139 v8::Local
<v8::Value
> val
,
140 v8::Local
<v8::ArrayBuffer
>* out
);
144 struct GIN_EXPORT Converter
<v8::Local
<v8::External
> > {
145 static v8::Local
<v8::Value
> ToV8(v8::Isolate
* isolate
,
146 v8::Local
<v8::External
> val
);
147 static bool FromV8(v8::Isolate
* isolate
,
148 v8::Local
<v8::Value
> val
,
149 v8::Local
<v8::External
>* out
);
153 struct GIN_EXPORT Converter
<v8::Local
<v8::Value
> > {
154 static v8::Local
<v8::Value
> ToV8(v8::Isolate
* isolate
,
155 v8::Local
<v8::Value
> val
);
156 static bool FromV8(v8::Isolate
* isolate
,
157 v8::Local
<v8::Value
> val
,
158 v8::Local
<v8::Value
>* out
);
162 struct Converter
<std::vector
<T
> > {
163 static v8::MaybeLocal
<v8::Value
> ToV8(v8::Local
<v8::Context
> context
,
164 const std::vector
<T
>& val
) {
165 v8::Isolate
* isolate
= context
->GetIsolate();
166 v8::Local
<v8::Array
> result(
167 v8::Array::New(isolate
, static_cast<int>(val
.size())));
168 for (uint32_t i
= 0; i
< val
.size(); ++i
) {
169 auto maybe
= result
->Set(context
, i
, Converter
<T
>::ToV8(isolate
, val
[i
]));
170 if (maybe
.IsNothing() || !maybe
.FromJust())
171 return v8::MaybeLocal
<v8::Value
>();
176 static bool FromV8(v8::Isolate
* isolate
,
177 v8::Local
<v8::Value
> val
,
178 std::vector
<T
>* out
) {
182 std::vector
<T
> result
;
183 v8::Local
<v8::Array
> array(v8::Local
<v8::Array
>::Cast(val
));
184 uint32_t length
= array
->Length();
185 for (uint32_t i
= 0; i
< length
; ++i
) {
186 v8::Local
<v8::Value
> v8_item
;
187 if (!array
->Get(isolate
->GetCurrentContext(), i
).ToLocal(&v8_item
))
190 if (!Converter
<T
>::FromV8(isolate
, v8_item
, &item
))
192 result
.push_back(item
);
201 struct ToV8ReturnsMaybe
<std::vector
<T
>> {
202 static const bool value
= true;
205 // Convenience functions that deduce T.
207 v8::Local
<v8::Value
> ConvertToV8(v8::Isolate
* isolate
, T input
) {
208 return Converter
<T
>::ToV8(isolate
, input
);
212 v8::MaybeLocal
<v8::Value
> ConvertToV8(v8::Local
<v8::Context
> context
, T input
) {
213 return Converter
<T
>::ToV8(context
, input
);
216 template<typename T
, bool = ToV8ReturnsMaybe
<T
>::value
> struct ToV8Traits
;
218 template <typename T
>
219 struct ToV8Traits
<T
, true> {
220 static bool TryConvertToV8(v8::Isolate
* isolate
,
222 v8::Local
<v8::Value
>* output
) {
223 auto maybe
= ConvertToV8(isolate
->GetCurrentContext(), input
);
226 *output
= maybe
.ToLocalChecked();
231 template <typename T
>
232 struct ToV8Traits
<T
, false> {
233 static bool TryConvertToV8(v8::Isolate
* isolate
,
235 v8::Local
<v8::Value
>* output
) {
236 *output
= ConvertToV8(isolate
, input
);
241 template <typename T
>
242 bool TryConvertToV8(v8::Isolate
* isolate
,
244 v8::Local
<v8::Value
>* output
) {
245 return ToV8Traits
<T
>::TryConvertToV8(isolate
, input
, output
);
248 // This crashes when input.size() > v8::String::kMaxLength.
249 GIN_EXPORT
inline v8::Local
<v8::String
> StringToV8(
250 v8::Isolate
* isolate
,
251 const base::StringPiece
& input
) {
252 return ConvertToV8(isolate
, input
).As
<v8::String
>();
255 // This crashes when input.size() > v8::String::kMaxLength.
256 GIN_EXPORT
v8::Local
<v8::String
> StringToSymbol(v8::Isolate
* isolate
,
257 const base::StringPiece
& val
);
260 bool ConvertFromV8(v8::Isolate
* isolate
, v8::Local
<v8::Value
> input
,
262 return Converter
<T
>::FromV8(isolate
, input
, result
);
265 GIN_EXPORT
std::string
V8ToString(v8::Local
<v8::Value
> value
);
269 #endif // GIN_CONVERTER_H_