blob: 27b4d0acd016df378e4cb44ccda1a433244fe2c6 [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>
Jeremy Romaneb8a2f172018-01-29 17:33:4011#include <type_traits>
[email protected]a22998a2013-11-10 05:00:5012#include <vector>
13
bashidbd2ef9bb2015-06-02 01:39:3214#include "base/logging.h"
Shimi Zhang15708bfc2019-08-13 19:24:4815#include "base/strings/string16.h"
[email protected]b520e132013-11-29 03:21:4816#include "base/strings/string_piece.h"
[email protected]48c21632013-12-12 21:32:3417#include "gin/gin_export.h"
[email protected]a22998a2013-11-10 05:00:5018#include "v8/include/v8.h"
19
20namespace gin {
21
bashidbd2ef9bb2015-06-02 01:39:3222template<typename KeyType>
23bool SetProperty(v8::Isolate* isolate,
24 v8::Local<v8::Object> object,
25 KeyType key,
26 v8::Local<v8::Value> value) {
rdevlin.cronin415b73b2015-11-13 01:14:4727 auto maybe =
28 object->DefineOwnProperty(isolate->GetCurrentContext(), key, value);
bashidbd2ef9bb2015-06-02 01:39:3229 return !maybe.IsNothing() && maybe.FromJust();
30}
31
Ken Rockot2b0f07652017-04-12 19:10:4932template <typename T, typename Enable = void>
bashidbd2ef9bb2015-06-02 01:39:3233struct ToV8ReturnsMaybe {
34 static const bool value = false;
35};
36
[email protected]cf76c84a2013-12-06 14:07:0737template<typename T, typename Enable = void>
[email protected]a22998a2013-11-10 05:00:5038struct Converter {};
39
40template<>
[email protected]48c21632013-12-12 21:32:3441struct GIN_EXPORT Converter<bool> {
deepak.sfaaa1b62015-04-30 07:30:4842 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:5043 bool val);
[email protected]7618ebbb2013-11-27 03:38:2644 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4845 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:5046 bool* out);
47};
48
49template<>
[email protected]48c21632013-12-12 21:32:3450struct GIN_EXPORT Converter<int32_t> {
deepak.sfaaa1b62015-04-30 07:30:4851 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:5052 int32_t val);
[email protected]7618ebbb2013-11-27 03:38:2653 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4854 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:5055 int32_t* out);
56};
57
58template<>
[email protected]48c21632013-12-12 21:32:3459struct GIN_EXPORT Converter<uint32_t> {
deepak.sfaaa1b62015-04-30 07:30:4860 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:5061 uint32_t val);
[email protected]7618ebbb2013-11-27 03:38:2662 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4863 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:5064 uint32_t* out);
65};
66
67template<>
[email protected]48c21632013-12-12 21:32:3468struct GIN_EXPORT Converter<int64_t> {
[email protected]e87f3122013-11-12 00:41:2769 // Warning: JavaScript cannot represent 64 integers precisely.
deepak.sfaaa1b62015-04-30 07:30:4870 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]e87f3122013-11-12 00:41:2771 int64_t val);
[email protected]7618ebbb2013-11-27 03:38:2672 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4873 v8::Local<v8::Value> val,
[email protected]e87f3122013-11-12 00:41:2774 int64_t* out);
75};
76
77template<>
[email protected]48c21632013-12-12 21:32:3478struct GIN_EXPORT Converter<uint64_t> {
[email protected]e87f3122013-11-12 00:41:2779 // Warning: JavaScript cannot represent 64 integers precisely.
deepak.sfaaa1b62015-04-30 07:30:4880 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]e87f3122013-11-12 00:41:2781 uint64_t val);
[email protected]7618ebbb2013-11-27 03:38:2682 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4883 v8::Local<v8::Value> val,
[email protected]e87f3122013-11-12 00:41:2784 uint64_t* out);
85};
86
87template<>
[email protected]d73341d12013-12-21 00:48:4688struct GIN_EXPORT Converter<float> {
deepak.sfaaa1b62015-04-30 07:30:4889 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]d73341d12013-12-21 00:48:4690 float val);
91 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4892 v8::Local<v8::Value> val,
[email protected]d73341d12013-12-21 00:48:4693 float* out);
94};
95
96template<>
[email protected]48c21632013-12-12 21:32:3497struct GIN_EXPORT Converter<double> {
deepak.sfaaa1b62015-04-30 07:30:4898 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:5099 double val);
[email protected]7618ebbb2013-11-27 03:38:26100 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48101 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:50102 double* out);
103};
104
105template<>
[email protected]48c21632013-12-12 21:32:34106struct GIN_EXPORT Converter<base::StringPiece> {
bashidbd2ef9bb2015-06-02 01:39:32107 // This crashes when val.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48108 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]b520e132013-11-29 03:21:48109 const base::StringPiece& val);
110 // No conversion out is possible because StringPiece does not contain storage.
111};
112
113template<>
[email protected]48c21632013-12-12 21:32:34114struct GIN_EXPORT Converter<std::string> {
bashidbd2ef9bb2015-06-02 01:39:32115 // This crashes when val.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48116 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:50117 const std::string& val);
[email protected]7618ebbb2013-11-27 03:38:26118 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48119 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:50120 std::string* out);
121};
122
Shimi Zhang15708bfc2019-08-13 19:24:48123template <>
124struct GIN_EXPORT Converter<base::string16> {
125 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
126 const base::string16& val);
127 static bool FromV8(v8::Isolate* isolate,
128 v8::Local<v8::Value> val,
129 base::string16* out);
130};
131
132template <>
133struct GIN_EXPORT Converter<v8::Local<v8::Function>> {
Nitish Sakhawalkarf7bbaa522019-02-11 16:19:09134 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
135 v8::Local<v8::Function> val);
[email protected]7618ebbb2013-11-27 03:38:26136 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48137 v8::Local<v8::Value> val,
138 v8::Local<v8::Function>* out);
[email protected]a22998a2013-11-10 05:00:50139};
140
141template<>
deepak.sfaaa1b62015-04-30 07:30:48142struct GIN_EXPORT Converter<v8::Local<v8::Object> > {
143 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
144 v8::Local<v8::Object> val);
[email protected]7618ebbb2013-11-27 03:38:26145 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48146 v8::Local<v8::Value> val,
147 v8::Local<v8::Object>* out);
[email protected]a22998a2013-11-10 05:00:50148};
149
Scott Grahamd2f4ed4b2018-10-17 01:57:27150template <>
151struct GIN_EXPORT Converter<v8::Local<v8::Promise>> {
152 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
153 v8::Local<v8::Promise> val);
154 static bool FromV8(v8::Isolate* isolate,
155 v8::Local<v8::Value> val,
156 v8::Local<v8::Promise>* out);
157};
158
[email protected]97f21ca2013-11-17 17:46:07159template<>
deepak.sfaaa1b62015-04-30 07:30:48160struct GIN_EXPORT Converter<v8::Local<v8::ArrayBuffer> > {
161 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
162 v8::Local<v8::ArrayBuffer> val);
[email protected]7618ebbb2013-11-27 03:38:26163 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48164 v8::Local<v8::Value> val,
165 v8::Local<v8::ArrayBuffer>* out);
[email protected]ec95fdf2013-11-24 19:10:11166};
167
168template<>
deepak.sfaaa1b62015-04-30 07:30:48169struct GIN_EXPORT Converter<v8::Local<v8::External> > {
170 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
171 v8::Local<v8::External> val);
[email protected]7618ebbb2013-11-27 03:38:26172 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48173 v8::Local<v8::Value> val,
174 v8::Local<v8::External>* out);
[email protected]97f21ca2013-11-17 17:46:07175};
176
177template<>
deepak.sfaaa1b62015-04-30 07:30:48178struct GIN_EXPORT Converter<v8::Local<v8::Value> > {
179 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
180 v8::Local<v8::Value> val);
[email protected]7618ebbb2013-11-27 03:38:26181 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48182 v8::Local<v8::Value> val,
183 v8::Local<v8::Value>* out);
[email protected]97f21ca2013-11-17 17:46:07184};
185
[email protected]a22998a2013-11-10 05:00:50186template<typename T>
187struct Converter<std::vector<T> > {
Jeremy Romaneb8a2f172018-01-29 17:33:40188 static std::conditional_t<ToV8ReturnsMaybe<T>::value,
189 v8::MaybeLocal<v8::Value>,
190 v8::Local<v8::Value>>
191 ToV8(v8::Isolate* isolate, const std::vector<T>& val) {
192 v8::Local<v8::Context> context = isolate->GetCurrentContext();
deepak.sfaaa1b62015-04-30 07:30:48193 v8::Local<v8::Array> result(
[email protected]91cd4fe2013-11-28 09:31:58194 v8::Array::New(isolate, static_cast<int>(val.size())));
bashidbd2ef9bb2015-06-02 01:39:32195 for (uint32_t i = 0; i < val.size(); ++i) {
Jeremy Romaneb8a2f172018-01-29 17:33:40196 v8::MaybeLocal<v8::Value> maybe = Converter<T>::ToV8(isolate, val[i]);
197 v8::Local<v8::Value> element;
198 if (!maybe.ToLocal(&element))
199 return {};
200 bool property_created;
201 if (!result->CreateDataProperty(context, i, element)
202 .To(&property_created) ||
203 !property_created) {
204 NOTREACHED() << "CreateDataProperty should always succeed here.";
205 }
[email protected]a22998a2013-11-10 05:00:50206 }
207 return result;
208 }
209
[email protected]7618ebbb2013-11-27 03:38:26210 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48211 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:50212 std::vector<T>* out) {
213 if (!val->IsArray())
214 return false;
215
216 std::vector<T> result;
deepak.sfaaa1b62015-04-30 07:30:48217 v8::Local<v8::Array> array(v8::Local<v8::Array>::Cast(val));
[email protected]a22998a2013-11-10 05:00:50218 uint32_t length = array->Length();
219 for (uint32_t i = 0; i < length; ++i) {
bashidbd2ef9bb2015-06-02 01:39:32220 v8::Local<v8::Value> v8_item;
221 if (!array->Get(isolate->GetCurrentContext(), i).ToLocal(&v8_item))
222 return false;
[email protected]a22998a2013-11-10 05:00:50223 T item;
bashidbd2ef9bb2015-06-02 01:39:32224 if (!Converter<T>::FromV8(isolate, v8_item, &item))
[email protected]a22998a2013-11-10 05:00:50225 return false;
226 result.push_back(item);
227 }
228
229 out->swap(result);
230 return true;
231 }
232};
233
bashidbd2ef9bb2015-06-02 01:39:32234template<typename T>
235struct ToV8ReturnsMaybe<std::vector<T>> {
Jeremy Romaneb8a2f172018-01-29 17:33:40236 static const bool value = ToV8ReturnsMaybe<T>::value;
bashidbd2ef9bb2015-06-02 01:39:32237};
238
[email protected]a22998a2013-11-10 05:00:50239// Convenience functions that deduce T.
Jeremy Romaneb8a2f172018-01-29 17:33:40240template <typename T>
241std::conditional_t<ToV8ReturnsMaybe<T>::value,
242 v8::MaybeLocal<v8::Value>,
243 v8::Local<v8::Value>>
Jeremy Apthorp6a3480292018-04-26 18:53:59244ConvertToV8(v8::Isolate* isolate, const T& input) {
[email protected]a22998a2013-11-10 05:00:50245 return Converter<T>::ToV8(isolate, input);
246}
247
Jeremy Roman44bda444b2018-03-16 17:33:45248template <typename T>
Jeremy Apthorp6a3480292018-04-26 18:53:59249std::enable_if_t<ToV8ReturnsMaybe<T>::value, bool> TryConvertToV8(
250 v8::Isolate* isolate,
251 const T& input,
252 v8::Local<v8::Value>* output) {
Jeremy Roman44bda444b2018-03-16 17:33:45253 return ConvertToV8(isolate, input).ToLocal(output);
254}
bashidbd2ef9bb2015-06-02 01:39:32255
256template <typename T>
Jeremy Apthorp6a3480292018-04-26 18:53:59257std::enable_if_t<!ToV8ReturnsMaybe<T>::value, bool> TryConvertToV8(
258 v8::Isolate* isolate,
259 const T& input,
260 v8::Local<v8::Value>* output) {
Jeremy Roman44bda444b2018-03-16 17:33:45261 *output = ConvertToV8(isolate, input);
262 return true;
bashidbd2ef9bb2015-06-02 01:39:32263}
264
265// This crashes when input.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48266GIN_EXPORT inline v8::Local<v8::String> StringToV8(
[email protected]48c21632013-12-12 21:32:34267 v8::Isolate* isolate,
268 const base::StringPiece& input) {
[email protected]a22998a2013-11-10 05:00:50269 return ConvertToV8(isolate, input).As<v8::String>();
270}
271
bashidbd2ef9bb2015-06-02 01:39:32272// This crashes when input.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48273GIN_EXPORT v8::Local<v8::String> StringToSymbol(v8::Isolate* isolate,
[email protected]48c21632013-12-12 21:32:34274 const base::StringPiece& val);
[email protected]e87f3122013-11-12 00:41:27275
Shimi Zhang15708bfc2019-08-13 19:24:48276// This crashes when input.size() > v8::String::kMaxLength.
277GIN_EXPORT v8::Local<v8::String> StringToSymbol(v8::Isolate* isolate,
278 const base::StringPiece16& val);
279
[email protected]a22998a2013-11-10 05:00:50280template<typename T>
deepak.sfaaa1b62015-04-30 07:30:48281bool ConvertFromV8(v8::Isolate* isolate, v8::Local<v8::Value> input,
[email protected]7618ebbb2013-11-27 03:38:26282 T* result) {
Dan Elphick712beaa2018-07-24 17:37:24283 DCHECK(isolate);
[email protected]7618ebbb2013-11-27 03:38:26284 return Converter<T>::FromV8(isolate, input, result);
[email protected]a22998a2013-11-10 05:00:50285}
286
Dan Elphick38a508052018-07-23 22:19:53287GIN_EXPORT std::string V8ToString(v8::Isolate* isolate,
288 v8::Local<v8::Value> value);
[email protected]2f703422013-11-25 21:26:15289
[email protected]a22998a2013-11-10 05:00:50290} // namespace gin
291
292#endif // GIN_CONVERTER_H_