blob: c15f87dc0b3bf0a7d52825cf6f5b9021ae483d03 [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
avi90e658dd2015-12-21 07:16:198#include <stdint.h>
9
[email protected]a22998a2013-11-10 05:00:5010#include <string>
11#include <vector>
12
bashidbd2ef9bb2015-06-02 01:39:3213#include "base/logging.h"
[email protected]b520e132013-11-29 03:21:4814#include "base/strings/string_piece.h"
[email protected]48c21632013-12-12 21:32:3415#include "gin/gin_export.h"
[email protected]a22998a2013-11-10 05:00:5016#include "v8/include/v8.h"
17
18namespace gin {
19
bashidbd2ef9bb2015-06-02 01:39:3220template<typename KeyType>
21bool SetProperty(v8::Isolate* isolate,
22 v8::Local<v8::Object> object,
23 KeyType key,
24 v8::Local<v8::Value> value) {
rdevlin.cronin415b73b2015-11-13 01:14:4725 auto maybe =
26 object->DefineOwnProperty(isolate->GetCurrentContext(), key, value);
bashidbd2ef9bb2015-06-02 01:39:3227 return !maybe.IsNothing() && maybe.FromJust();
28}
29
30template<typename T>
31struct ToV8ReturnsMaybe {
32 static const bool value = false;
33};
34
[email protected]cf76c84a2013-12-06 14:07:0735template<typename T, typename Enable = void>
[email protected]a22998a2013-11-10 05:00:5036struct Converter {};
37
38template<>
[email protected]48c21632013-12-12 21:32:3439struct GIN_EXPORT Converter<bool> {
deepak.sfaaa1b62015-04-30 07:30:4840 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:5041 bool val);
[email protected]7618ebbb2013-11-27 03:38:2642 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4843 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:5044 bool* out);
45};
46
47template<>
[email protected]48c21632013-12-12 21:32:3448struct GIN_EXPORT Converter<int32_t> {
deepak.sfaaa1b62015-04-30 07:30:4849 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:5050 int32_t val);
[email protected]7618ebbb2013-11-27 03:38:2651 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4852 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:5053 int32_t* out);
54};
55
56template<>
[email protected]48c21632013-12-12 21:32:3457struct GIN_EXPORT Converter<uint32_t> {
deepak.sfaaa1b62015-04-30 07:30:4858 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:5059 uint32_t val);
[email protected]7618ebbb2013-11-27 03:38:2660 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4861 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:5062 uint32_t* out);
63};
64
65template<>
[email protected]48c21632013-12-12 21:32:3466struct GIN_EXPORT Converter<int64_t> {
[email protected]e87f3122013-11-12 00:41:2767 // Warning: JavaScript cannot represent 64 integers precisely.
deepak.sfaaa1b62015-04-30 07:30:4868 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]e87f3122013-11-12 00:41:2769 int64_t val);
[email protected]7618ebbb2013-11-27 03:38:2670 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4871 v8::Local<v8::Value> val,
[email protected]e87f3122013-11-12 00:41:2772 int64_t* out);
73};
74
75template<>
[email protected]48c21632013-12-12 21:32:3476struct GIN_EXPORT Converter<uint64_t> {
[email protected]e87f3122013-11-12 00:41:2777 // Warning: JavaScript cannot represent 64 integers precisely.
deepak.sfaaa1b62015-04-30 07:30:4878 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]e87f3122013-11-12 00:41:2779 uint64_t val);
[email protected]7618ebbb2013-11-27 03:38:2680 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4881 v8::Local<v8::Value> val,
[email protected]e87f3122013-11-12 00:41:2782 uint64_t* out);
83};
84
85template<>
[email protected]d73341d12013-12-21 00:48:4686struct GIN_EXPORT Converter<float> {
deepak.sfaaa1b62015-04-30 07:30:4887 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]d73341d12013-12-21 00:48:4688 float val);
89 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4890 v8::Local<v8::Value> val,
[email protected]d73341d12013-12-21 00:48:4691 float* out);
92};
93
94template<>
[email protected]48c21632013-12-12 21:32:3495struct GIN_EXPORT Converter<double> {
deepak.sfaaa1b62015-04-30 07:30:4896 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:5097 double val);
[email protected]7618ebbb2013-11-27 03:38:2698 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4899 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:50100 double* out);
101};
102
103template<>
[email protected]48c21632013-12-12 21:32:34104struct GIN_EXPORT Converter<base::StringPiece> {
bashidbd2ef9bb2015-06-02 01:39:32105 // This crashes when val.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48106 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]b520e132013-11-29 03:21:48107 const base::StringPiece& val);
108 // No conversion out is possible because StringPiece does not contain storage.
109};
110
111template<>
[email protected]48c21632013-12-12 21:32:34112struct GIN_EXPORT Converter<std::string> {
bashidbd2ef9bb2015-06-02 01:39:32113 // This crashes when val.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48114 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:50115 const std::string& val);
[email protected]7618ebbb2013-11-27 03:38:26116 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48117 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:50118 std::string* out);
119};
120
121template<>
deepak.sfaaa1b62015-04-30 07:30:48122struct GIN_EXPORT Converter<v8::Local<v8::Function> > {
[email protected]7618ebbb2013-11-27 03:38:26123 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48124 v8::Local<v8::Value> val,
125 v8::Local<v8::Function>* out);
[email protected]a22998a2013-11-10 05:00:50126};
127
128template<>
deepak.sfaaa1b62015-04-30 07:30:48129struct GIN_EXPORT Converter<v8::Local<v8::Object> > {
130 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
131 v8::Local<v8::Object> val);
[email protected]7618ebbb2013-11-27 03:38:26132 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48133 v8::Local<v8::Value> val,
134 v8::Local<v8::Object>* out);
[email protected]a22998a2013-11-10 05:00:50135};
136
[email protected]97f21ca2013-11-17 17:46:07137template<>
deepak.sfaaa1b62015-04-30 07:30:48138struct GIN_EXPORT Converter<v8::Local<v8::ArrayBuffer> > {
139 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
140 v8::Local<v8::ArrayBuffer> val);
[email protected]7618ebbb2013-11-27 03:38:26141 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48142 v8::Local<v8::Value> val,
143 v8::Local<v8::ArrayBuffer>* out);
[email protected]ec95fdf2013-11-24 19:10:11144};
145
146template<>
deepak.sfaaa1b62015-04-30 07:30:48147struct GIN_EXPORT Converter<v8::Local<v8::External> > {
148 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
149 v8::Local<v8::External> val);
[email protected]7618ebbb2013-11-27 03:38:26150 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48151 v8::Local<v8::Value> val,
152 v8::Local<v8::External>* out);
[email protected]97f21ca2013-11-17 17:46:07153};
154
155template<>
deepak.sfaaa1b62015-04-30 07:30:48156struct GIN_EXPORT Converter<v8::Local<v8::Value> > {
157 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
158 v8::Local<v8::Value> val);
[email protected]7618ebbb2013-11-27 03:38:26159 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48160 v8::Local<v8::Value> val,
161 v8::Local<v8::Value>* out);
[email protected]97f21ca2013-11-17 17:46:07162};
163
[email protected]a22998a2013-11-10 05:00:50164template<typename T>
165struct Converter<std::vector<T> > {
bashidbd2ef9bb2015-06-02 01:39:32166 static v8::MaybeLocal<v8::Value> ToV8(v8::Local<v8::Context> context,
167 const std::vector<T>& val) {
168 v8::Isolate* isolate = context->GetIsolate();
deepak.sfaaa1b62015-04-30 07:30:48169 v8::Local<v8::Array> result(
[email protected]91cd4fe2013-11-28 09:31:58170 v8::Array::New(isolate, static_cast<int>(val.size())));
bashidbd2ef9bb2015-06-02 01:39:32171 for (uint32_t i = 0; i < val.size(); ++i) {
172 auto maybe = result->Set(context, i, Converter<T>::ToV8(isolate, val[i]));
173 if (maybe.IsNothing() || !maybe.FromJust())
174 return v8::MaybeLocal<v8::Value>();
[email protected]a22998a2013-11-10 05:00:50175 }
176 return result;
177 }
178
[email protected]7618ebbb2013-11-27 03:38:26179 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48180 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:50181 std::vector<T>* out) {
182 if (!val->IsArray())
183 return false;
184
185 std::vector<T> result;
deepak.sfaaa1b62015-04-30 07:30:48186 v8::Local<v8::Array> array(v8::Local<v8::Array>::Cast(val));
[email protected]a22998a2013-11-10 05:00:50187 uint32_t length = array->Length();
188 for (uint32_t i = 0; i < length; ++i) {
bashidbd2ef9bb2015-06-02 01:39:32189 v8::Local<v8::Value> v8_item;
190 if (!array->Get(isolate->GetCurrentContext(), i).ToLocal(&v8_item))
191 return false;
[email protected]a22998a2013-11-10 05:00:50192 T item;
bashidbd2ef9bb2015-06-02 01:39:32193 if (!Converter<T>::FromV8(isolate, v8_item, &item))
[email protected]a22998a2013-11-10 05:00:50194 return false;
195 result.push_back(item);
196 }
197
198 out->swap(result);
199 return true;
200 }
201};
202
bashidbd2ef9bb2015-06-02 01:39:32203template<typename T>
204struct ToV8ReturnsMaybe<std::vector<T>> {
205 static const bool value = true;
206};
207
[email protected]a22998a2013-11-10 05:00:50208// Convenience functions that deduce T.
209template<typename T>
deepak.sfaaa1b62015-04-30 07:30:48210v8::Local<v8::Value> ConvertToV8(v8::Isolate* isolate, T input) {
[email protected]a22998a2013-11-10 05:00:50211 return Converter<T>::ToV8(isolate, input);
212}
213
bashidbd2ef9bb2015-06-02 01:39:32214template<typename T>
215v8::MaybeLocal<v8::Value> ConvertToV8(v8::Local<v8::Context> context, T input) {
216 return Converter<T>::ToV8(context, input);
217}
218
219template<typename T, bool = ToV8ReturnsMaybe<T>::value> struct ToV8Traits;
220
221template <typename T>
222struct ToV8Traits<T, true> {
223 static bool TryConvertToV8(v8::Isolate* isolate,
224 T input,
225 v8::Local<v8::Value>* output) {
226 auto maybe = ConvertToV8(isolate->GetCurrentContext(), input);
227 if (maybe.IsEmpty())
228 return false;
229 *output = maybe.ToLocalChecked();
230 return true;
231 }
232};
233
234template <typename T>
235struct ToV8Traits<T, false> {
236 static bool TryConvertToV8(v8::Isolate* isolate,
237 T input,
238 v8::Local<v8::Value>* output) {
239 *output = ConvertToV8(isolate, input);
240 return true;
241 }
242};
243
244template <typename T>
245bool TryConvertToV8(v8::Isolate* isolate,
246 T input,
247 v8::Local<v8::Value>* output) {
248 return ToV8Traits<T>::TryConvertToV8(isolate, input, output);
249}
250
251// This crashes when input.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48252GIN_EXPORT inline v8::Local<v8::String> StringToV8(
[email protected]48c21632013-12-12 21:32:34253 v8::Isolate* isolate,
254 const base::StringPiece& input) {
[email protected]a22998a2013-11-10 05:00:50255 return ConvertToV8(isolate, input).As<v8::String>();
256}
257
bashidbd2ef9bb2015-06-02 01:39:32258// This crashes when input.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48259GIN_EXPORT v8::Local<v8::String> StringToSymbol(v8::Isolate* isolate,
[email protected]48c21632013-12-12 21:32:34260 const base::StringPiece& val);
[email protected]e87f3122013-11-12 00:41:27261
[email protected]a22998a2013-11-10 05:00:50262template<typename T>
deepak.sfaaa1b62015-04-30 07:30:48263bool ConvertFromV8(v8::Isolate* isolate, v8::Local<v8::Value> input,
[email protected]7618ebbb2013-11-27 03:38:26264 T* result) {
265 return Converter<T>::FromV8(isolate, input, result);
[email protected]a22998a2013-11-10 05:00:50266}
267
deepak.sfaaa1b62015-04-30 07:30:48268GIN_EXPORT std::string V8ToString(v8::Local<v8::Value> value);
[email protected]2f703422013-11-25 21:26:15269
[email protected]a22998a2013-11-10 05:00:50270} // namespace gin
271
272#endif // GIN_CONVERTER_H_