blob: 12348e2d852724dccd90d04f0cd2dbe1103ca91f [file] [log] [blame]
[email protected]a22998a2013-11-10 05:00:501// 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.
4
5#ifndef GIN_CONVERTER_H_
6#define GIN_CONVERTER_H_
7
8#include <string>
9#include <vector>
10
bashidbd2ef9bb2015-06-02 01:39:3211#include "base/logging.h"
[email protected]b520e132013-11-29 03:21:4812#include "base/strings/string_piece.h"
[email protected]48c21632013-12-12 21:32:3413#include "gin/gin_export.h"
[email protected]a22998a2013-11-10 05:00:5014#include "v8/include/v8.h"
15
16namespace gin {
17
bashidbd2ef9bb2015-06-02 01:39:3218template<typename KeyType>
19bool SetProperty(v8::Isolate* isolate,
20 v8::Local<v8::Object> object,
21 KeyType key,
22 v8::Local<v8::Value> value) {
rdevlin.cronin415b73b2015-11-13 01:14:4723 auto maybe =
24 object->DefineOwnProperty(isolate->GetCurrentContext(), key, value);
bashidbd2ef9bb2015-06-02 01:39:3225 return !maybe.IsNothing() && maybe.FromJust();
26}
27
28template<typename T>
29struct ToV8ReturnsMaybe {
30 static const bool value = false;
31};
32
[email protected]cf76c84a2013-12-06 14:07:0733template<typename T, typename Enable = void>
[email protected]a22998a2013-11-10 05:00:5034struct Converter {};
35
36template<>
[email protected]48c21632013-12-12 21:32:3437struct GIN_EXPORT Converter<bool> {
deepak.sfaaa1b62015-04-30 07:30:4838 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:5039 bool val);
[email protected]7618ebbb2013-11-27 03:38:2640 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4841 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:5042 bool* out);
43};
44
45template<>
[email protected]48c21632013-12-12 21:32:3446struct GIN_EXPORT Converter<int32_t> {
deepak.sfaaa1b62015-04-30 07:30:4847 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:5048 int32_t val);
[email protected]7618ebbb2013-11-27 03:38:2649 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4850 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:5051 int32_t* out);
52};
53
54template<>
[email protected]48c21632013-12-12 21:32:3455struct GIN_EXPORT Converter<uint32_t> {
deepak.sfaaa1b62015-04-30 07:30:4856 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:5057 uint32_t val);
[email protected]7618ebbb2013-11-27 03:38:2658 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4859 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:5060 uint32_t* out);
61};
62
63template<>
[email protected]48c21632013-12-12 21:32:3464struct GIN_EXPORT Converter<int64_t> {
[email protected]e87f3122013-11-12 00:41:2765 // Warning: JavaScript cannot represent 64 integers precisely.
deepak.sfaaa1b62015-04-30 07:30:4866 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]e87f3122013-11-12 00:41:2767 int64_t val);
[email protected]7618ebbb2013-11-27 03:38:2668 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4869 v8::Local<v8::Value> val,
[email protected]e87f3122013-11-12 00:41:2770 int64_t* out);
71};
72
73template<>
[email protected]48c21632013-12-12 21:32:3474struct GIN_EXPORT Converter<uint64_t> {
[email protected]e87f3122013-11-12 00:41:2775 // Warning: JavaScript cannot represent 64 integers precisely.
deepak.sfaaa1b62015-04-30 07:30:4876 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]e87f3122013-11-12 00:41:2777 uint64_t val);
[email protected]7618ebbb2013-11-27 03:38:2678 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4879 v8::Local<v8::Value> val,
[email protected]e87f3122013-11-12 00:41:2780 uint64_t* out);
81};
82
83template<>
[email protected]d73341d12013-12-21 00:48:4684struct GIN_EXPORT Converter<float> {
deepak.sfaaa1b62015-04-30 07:30:4885 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]d73341d12013-12-21 00:48:4686 float val);
87 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4888 v8::Local<v8::Value> val,
[email protected]d73341d12013-12-21 00:48:4689 float* out);
90};
91
92template<>
[email protected]48c21632013-12-12 21:32:3493struct GIN_EXPORT Converter<double> {
deepak.sfaaa1b62015-04-30 07:30:4894 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:5095 double val);
[email protected]7618ebbb2013-11-27 03:38:2696 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4897 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:5098 double* out);
99};
100
101template<>
[email protected]48c21632013-12-12 21:32:34102struct GIN_EXPORT Converter<base::StringPiece> {
bashidbd2ef9bb2015-06-02 01:39:32103 // This crashes when val.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48104 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]b520e132013-11-29 03:21:48105 const base::StringPiece& val);
106 // No conversion out is possible because StringPiece does not contain storage.
107};
108
109template<>
[email protected]48c21632013-12-12 21:32:34110struct GIN_EXPORT Converter<std::string> {
bashidbd2ef9bb2015-06-02 01:39:32111 // This crashes when val.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48112 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:50113 const std::string& val);
[email protected]7618ebbb2013-11-27 03:38:26114 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48115 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:50116 std::string* out);
117};
118
119template<>
deepak.sfaaa1b62015-04-30 07:30:48120struct GIN_EXPORT Converter<v8::Local<v8::Function> > {
[email protected]7618ebbb2013-11-27 03:38:26121 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48122 v8::Local<v8::Value> val,
123 v8::Local<v8::Function>* out);
[email protected]a22998a2013-11-10 05:00:50124};
125
126template<>
deepak.sfaaa1b62015-04-30 07:30:48127struct GIN_EXPORT Converter<v8::Local<v8::Object> > {
128 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
129 v8::Local<v8::Object> val);
[email protected]7618ebbb2013-11-27 03:38:26130 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48131 v8::Local<v8::Value> val,
132 v8::Local<v8::Object>* out);
[email protected]a22998a2013-11-10 05:00:50133};
134
[email protected]97f21ca2013-11-17 17:46:07135template<>
deepak.sfaaa1b62015-04-30 07:30:48136struct GIN_EXPORT Converter<v8::Local<v8::ArrayBuffer> > {
137 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
138 v8::Local<v8::ArrayBuffer> val);
[email protected]7618ebbb2013-11-27 03:38:26139 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48140 v8::Local<v8::Value> val,
141 v8::Local<v8::ArrayBuffer>* out);
[email protected]ec95fdf2013-11-24 19:10:11142};
143
144template<>
deepak.sfaaa1b62015-04-30 07:30:48145struct GIN_EXPORT Converter<v8::Local<v8::External> > {
146 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
147 v8::Local<v8::External> val);
[email protected]7618ebbb2013-11-27 03:38:26148 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48149 v8::Local<v8::Value> val,
150 v8::Local<v8::External>* out);
[email protected]97f21ca2013-11-17 17:46:07151};
152
153template<>
deepak.sfaaa1b62015-04-30 07:30:48154struct GIN_EXPORT Converter<v8::Local<v8::Value> > {
155 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
156 v8::Local<v8::Value> val);
[email protected]7618ebbb2013-11-27 03:38:26157 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48158 v8::Local<v8::Value> val,
159 v8::Local<v8::Value>* out);
[email protected]97f21ca2013-11-17 17:46:07160};
161
[email protected]a22998a2013-11-10 05:00:50162template<typename T>
163struct Converter<std::vector<T> > {
bashidbd2ef9bb2015-06-02 01:39:32164 static v8::MaybeLocal<v8::Value> ToV8(v8::Local<v8::Context> context,
165 const std::vector<T>& val) {
166 v8::Isolate* isolate = context->GetIsolate();
deepak.sfaaa1b62015-04-30 07:30:48167 v8::Local<v8::Array> result(
[email protected]91cd4fe2013-11-28 09:31:58168 v8::Array::New(isolate, static_cast<int>(val.size())));
bashidbd2ef9bb2015-06-02 01:39:32169 for (uint32_t i = 0; i < val.size(); ++i) {
170 auto maybe = result->Set(context, i, Converter<T>::ToV8(isolate, val[i]));
171 if (maybe.IsNothing() || !maybe.FromJust())
172 return v8::MaybeLocal<v8::Value>();
[email protected]a22998a2013-11-10 05:00:50173 }
174 return result;
175 }
176
[email protected]7618ebbb2013-11-27 03:38:26177 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48178 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:50179 std::vector<T>* out) {
180 if (!val->IsArray())
181 return false;
182
183 std::vector<T> result;
deepak.sfaaa1b62015-04-30 07:30:48184 v8::Local<v8::Array> array(v8::Local<v8::Array>::Cast(val));
[email protected]a22998a2013-11-10 05:00:50185 uint32_t length = array->Length();
186 for (uint32_t i = 0; i < length; ++i) {
bashidbd2ef9bb2015-06-02 01:39:32187 v8::Local<v8::Value> v8_item;
188 if (!array->Get(isolate->GetCurrentContext(), i).ToLocal(&v8_item))
189 return false;
[email protected]a22998a2013-11-10 05:00:50190 T item;
bashidbd2ef9bb2015-06-02 01:39:32191 if (!Converter<T>::FromV8(isolate, v8_item, &item))
[email protected]a22998a2013-11-10 05:00:50192 return false;
193 result.push_back(item);
194 }
195
196 out->swap(result);
197 return true;
198 }
199};
200
bashidbd2ef9bb2015-06-02 01:39:32201template<typename T>
202struct ToV8ReturnsMaybe<std::vector<T>> {
203 static const bool value = true;
204};
205
[email protected]a22998a2013-11-10 05:00:50206// Convenience functions that deduce T.
207template<typename T>
deepak.sfaaa1b62015-04-30 07:30:48208v8::Local<v8::Value> ConvertToV8(v8::Isolate* isolate, T input) {
[email protected]a22998a2013-11-10 05:00:50209 return Converter<T>::ToV8(isolate, input);
210}
211
bashidbd2ef9bb2015-06-02 01:39:32212template<typename T>
213v8::MaybeLocal<v8::Value> ConvertToV8(v8::Local<v8::Context> context, T input) {
214 return Converter<T>::ToV8(context, input);
215}
216
217template<typename T, bool = ToV8ReturnsMaybe<T>::value> struct ToV8Traits;
218
219template <typename T>
220struct ToV8Traits<T, true> {
221 static bool TryConvertToV8(v8::Isolate* isolate,
222 T input,
223 v8::Local<v8::Value>* output) {
224 auto maybe = ConvertToV8(isolate->GetCurrentContext(), input);
225 if (maybe.IsEmpty())
226 return false;
227 *output = maybe.ToLocalChecked();
228 return true;
229 }
230};
231
232template <typename T>
233struct ToV8Traits<T, false> {
234 static bool TryConvertToV8(v8::Isolate* isolate,
235 T input,
236 v8::Local<v8::Value>* output) {
237 *output = ConvertToV8(isolate, input);
238 return true;
239 }
240};
241
242template <typename T>
243bool TryConvertToV8(v8::Isolate* isolate,
244 T input,
245 v8::Local<v8::Value>* output) {
246 return ToV8Traits<T>::TryConvertToV8(isolate, input, output);
247}
248
249// This crashes when input.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48250GIN_EXPORT inline v8::Local<v8::String> StringToV8(
[email protected]48c21632013-12-12 21:32:34251 v8::Isolate* isolate,
252 const base::StringPiece& input) {
[email protected]a22998a2013-11-10 05:00:50253 return ConvertToV8(isolate, input).As<v8::String>();
254}
255
bashidbd2ef9bb2015-06-02 01:39:32256// This crashes when input.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48257GIN_EXPORT v8::Local<v8::String> StringToSymbol(v8::Isolate* isolate,
[email protected]48c21632013-12-12 21:32:34258 const base::StringPiece& val);
[email protected]e87f3122013-11-12 00:41:27259
[email protected]a22998a2013-11-10 05:00:50260template<typename T>
deepak.sfaaa1b62015-04-30 07:30:48261bool ConvertFromV8(v8::Isolate* isolate, v8::Local<v8::Value> input,
[email protected]7618ebbb2013-11-27 03:38:26262 T* result) {
263 return Converter<T>::FromV8(isolate, input, result);
[email protected]a22998a2013-11-10 05:00:50264}
265
deepak.sfaaa1b62015-04-30 07:30:48266GIN_EXPORT std::string V8ToString(v8::Local<v8::Value> value);
[email protected]2f703422013-11-25 21:26:15267
[email protected]a22998a2013-11-10 05:00:50268} // namespace gin
269
270#endif // GIN_CONVERTER_H_