blob: 53e8068ad7e5b1b39c45ba94730da43a5260b2b8 [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
Hans Wennborg5cd6d192020-06-18 11:14:5610#include <ostream>
[email protected]a22998a2013-11-10 05:00:5011#include <string>
Jeremy Romaneb8a2f172018-01-29 17:33:4012#include <type_traits>
[email protected]a22998a2013-11-10 05:00:5013#include <vector>
14
bashidbd2ef9bb2015-06-02 01:39:3215#include "base/logging.h"
Shimi Zhang15708bfc2019-08-13 19:24:4816#include "base/strings/string16.h"
[email protected]b520e132013-11-29 03:21:4817#include "base/strings/string_piece.h"
[email protected]48c21632013-12-12 21:32:3418#include "gin/gin_export.h"
[email protected]a22998a2013-11-10 05:00:5019#include "v8/include/v8.h"
20
21namespace gin {
22
bashidbd2ef9bb2015-06-02 01:39:3223template<typename KeyType>
24bool SetProperty(v8::Isolate* isolate,
25 v8::Local<v8::Object> object,
26 KeyType key,
27 v8::Local<v8::Value> value) {
rdevlin.cronin415b73b2015-11-13 01:14:4728 auto maybe =
29 object->DefineOwnProperty(isolate->GetCurrentContext(), key, value);
bashidbd2ef9bb2015-06-02 01:39:3230 return !maybe.IsNothing() && maybe.FromJust();
31}
32
Ken Rockot2b0f07652017-04-12 19:10:4933template <typename T, typename Enable = void>
bashidbd2ef9bb2015-06-02 01:39:3234struct ToV8ReturnsMaybe {
35 static const bool value = false;
36};
37
[email protected]cf76c84a2013-12-06 14:07:0738template<typename T, typename Enable = void>
[email protected]a22998a2013-11-10 05:00:5039struct Converter {};
40
41template<>
[email protected]48c21632013-12-12 21:32:3442struct GIN_EXPORT Converter<bool> {
deepak.sfaaa1b62015-04-30 07:30:4843 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:5044 bool val);
[email protected]7618ebbb2013-11-27 03:38:2645 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4846 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:5047 bool* out);
48};
49
50template<>
[email protected]48c21632013-12-12 21:32:3451struct GIN_EXPORT Converter<int32_t> {
deepak.sfaaa1b62015-04-30 07:30:4852 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:5053 int32_t val);
[email protected]7618ebbb2013-11-27 03:38:2654 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4855 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:5056 int32_t* out);
57};
58
59template<>
[email protected]48c21632013-12-12 21:32:3460struct GIN_EXPORT Converter<uint32_t> {
deepak.sfaaa1b62015-04-30 07:30:4861 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:5062 uint32_t val);
[email protected]7618ebbb2013-11-27 03:38:2663 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4864 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:5065 uint32_t* out);
66};
67
68template<>
[email protected]48c21632013-12-12 21:32:3469struct GIN_EXPORT Converter<int64_t> {
[email protected]e87f3122013-11-12 00:41:2770 // Warning: JavaScript cannot represent 64 integers precisely.
deepak.sfaaa1b62015-04-30 07:30:4871 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]e87f3122013-11-12 00:41:2772 int64_t val);
[email protected]7618ebbb2013-11-27 03:38:2673 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4874 v8::Local<v8::Value> val,
[email protected]e87f3122013-11-12 00:41:2775 int64_t* out);
76};
77
78template<>
[email protected]48c21632013-12-12 21:32:3479struct GIN_EXPORT Converter<uint64_t> {
[email protected]e87f3122013-11-12 00:41:2780 // Warning: JavaScript cannot represent 64 integers precisely.
deepak.sfaaa1b62015-04-30 07:30:4881 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]e87f3122013-11-12 00:41:2782 uint64_t val);
[email protected]7618ebbb2013-11-27 03:38:2683 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4884 v8::Local<v8::Value> val,
[email protected]e87f3122013-11-12 00:41:2785 uint64_t* out);
86};
87
88template<>
[email protected]d73341d12013-12-21 00:48:4689struct GIN_EXPORT Converter<float> {
deepak.sfaaa1b62015-04-30 07:30:4890 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]d73341d12013-12-21 00:48:4691 float val);
92 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4893 v8::Local<v8::Value> val,
[email protected]d73341d12013-12-21 00:48:4694 float* out);
95};
96
97template<>
[email protected]48c21632013-12-12 21:32:3498struct GIN_EXPORT Converter<double> {
deepak.sfaaa1b62015-04-30 07:30:4899 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:50100 double val);
[email protected]7618ebbb2013-11-27 03:38:26101 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48102 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:50103 double* out);
104};
105
106template<>
[email protected]48c21632013-12-12 21:32:34107struct GIN_EXPORT Converter<base::StringPiece> {
bashidbd2ef9bb2015-06-02 01:39:32108 // This crashes when val.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48109 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]b520e132013-11-29 03:21:48110 const base::StringPiece& val);
111 // No conversion out is possible because StringPiece does not contain storage.
112};
113
114template<>
[email protected]48c21632013-12-12 21:32:34115struct GIN_EXPORT Converter<std::string> {
bashidbd2ef9bb2015-06-02 01:39:32116 // This crashes when val.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48117 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:50118 const std::string& val);
[email protected]7618ebbb2013-11-27 03:38:26119 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48120 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:50121 std::string* out);
122};
123
Shimi Zhang15708bfc2019-08-13 19:24:48124template <>
125struct GIN_EXPORT Converter<base::string16> {
126 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
127 const base::string16& val);
128 static bool FromV8(v8::Isolate* isolate,
129 v8::Local<v8::Value> val,
130 base::string16* out);
131};
132
133template <>
134struct GIN_EXPORT Converter<v8::Local<v8::Function>> {
Nitish Sakhawalkarf7bbaa522019-02-11 16:19:09135 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
136 v8::Local<v8::Function> val);
[email protected]7618ebbb2013-11-27 03:38:26137 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48138 v8::Local<v8::Value> val,
139 v8::Local<v8::Function>* out);
[email protected]a22998a2013-11-10 05:00:50140};
141
142template<>
deepak.sfaaa1b62015-04-30 07:30:48143struct GIN_EXPORT Converter<v8::Local<v8::Object> > {
144 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
145 v8::Local<v8::Object> val);
[email protected]7618ebbb2013-11-27 03:38:26146 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48147 v8::Local<v8::Value> val,
148 v8::Local<v8::Object>* out);
[email protected]a22998a2013-11-10 05:00:50149};
150
Scott Grahamd2f4ed4b2018-10-17 01:57:27151template <>
152struct GIN_EXPORT Converter<v8::Local<v8::Promise>> {
153 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
154 v8::Local<v8::Promise> val);
155 static bool FromV8(v8::Isolate* isolate,
156 v8::Local<v8::Value> val,
157 v8::Local<v8::Promise>* out);
158};
159
[email protected]97f21ca2013-11-17 17:46:07160template<>
deepak.sfaaa1b62015-04-30 07:30:48161struct GIN_EXPORT Converter<v8::Local<v8::ArrayBuffer> > {
162 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
163 v8::Local<v8::ArrayBuffer> val);
[email protected]7618ebbb2013-11-27 03:38:26164 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48165 v8::Local<v8::Value> val,
166 v8::Local<v8::ArrayBuffer>* out);
[email protected]ec95fdf2013-11-24 19:10:11167};
168
169template<>
deepak.sfaaa1b62015-04-30 07:30:48170struct GIN_EXPORT Converter<v8::Local<v8::External> > {
171 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
172 v8::Local<v8::External> val);
[email protected]7618ebbb2013-11-27 03:38:26173 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48174 v8::Local<v8::Value> val,
175 v8::Local<v8::External>* out);
[email protected]97f21ca2013-11-17 17:46:07176};
177
178template<>
deepak.sfaaa1b62015-04-30 07:30:48179struct GIN_EXPORT Converter<v8::Local<v8::Value> > {
180 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
181 v8::Local<v8::Value> val);
[email protected]7618ebbb2013-11-27 03:38:26182 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48183 v8::Local<v8::Value> val,
184 v8::Local<v8::Value>* out);
[email protected]97f21ca2013-11-17 17:46:07185};
186
[email protected]a22998a2013-11-10 05:00:50187template<typename T>
188struct Converter<std::vector<T> > {
Jeremy Romaneb8a2f172018-01-29 17:33:40189 static std::conditional_t<ToV8ReturnsMaybe<T>::value,
190 v8::MaybeLocal<v8::Value>,
191 v8::Local<v8::Value>>
192 ToV8(v8::Isolate* isolate, const std::vector<T>& val) {
193 v8::Local<v8::Context> context = isolate->GetCurrentContext();
deepak.sfaaa1b62015-04-30 07:30:48194 v8::Local<v8::Array> result(
[email protected]91cd4fe2013-11-28 09:31:58195 v8::Array::New(isolate, static_cast<int>(val.size())));
bashidbd2ef9bb2015-06-02 01:39:32196 for (uint32_t i = 0; i < val.size(); ++i) {
Jeremy Romaneb8a2f172018-01-29 17:33:40197 v8::MaybeLocal<v8::Value> maybe = Converter<T>::ToV8(isolate, val[i]);
198 v8::Local<v8::Value> element;
199 if (!maybe.ToLocal(&element))
200 return {};
201 bool property_created;
202 if (!result->CreateDataProperty(context, i, element)
203 .To(&property_created) ||
204 !property_created) {
205 NOTREACHED() << "CreateDataProperty should always succeed here.";
206 }
[email protected]a22998a2013-11-10 05:00:50207 }
208 return result;
209 }
210
[email protected]7618ebbb2013-11-27 03:38:26211 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48212 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:50213 std::vector<T>* out) {
214 if (!val->IsArray())
215 return false;
216
217 std::vector<T> result;
deepak.sfaaa1b62015-04-30 07:30:48218 v8::Local<v8::Array> array(v8::Local<v8::Array>::Cast(val));
[email protected]a22998a2013-11-10 05:00:50219 uint32_t length = array->Length();
220 for (uint32_t i = 0; i < length; ++i) {
bashidbd2ef9bb2015-06-02 01:39:32221 v8::Local<v8::Value> v8_item;
222 if (!array->Get(isolate->GetCurrentContext(), i).ToLocal(&v8_item))
223 return false;
[email protected]a22998a2013-11-10 05:00:50224 T item;
bashidbd2ef9bb2015-06-02 01:39:32225 if (!Converter<T>::FromV8(isolate, v8_item, &item))
[email protected]a22998a2013-11-10 05:00:50226 return false;
227 result.push_back(item);
228 }
229
230 out->swap(result);
231 return true;
232 }
233};
234
bashidbd2ef9bb2015-06-02 01:39:32235template<typename T>
236struct ToV8ReturnsMaybe<std::vector<T>> {
Jeremy Romaneb8a2f172018-01-29 17:33:40237 static const bool value = ToV8ReturnsMaybe<T>::value;
bashidbd2ef9bb2015-06-02 01:39:32238};
239
[email protected]a22998a2013-11-10 05:00:50240// Convenience functions that deduce T.
Jeremy Romaneb8a2f172018-01-29 17:33:40241template <typename T>
242std::conditional_t<ToV8ReturnsMaybe<T>::value,
243 v8::MaybeLocal<v8::Value>,
244 v8::Local<v8::Value>>
Jeremy Apthorp6a3480292018-04-26 18:53:59245ConvertToV8(v8::Isolate* isolate, const T& input) {
[email protected]a22998a2013-11-10 05:00:50246 return Converter<T>::ToV8(isolate, input);
247}
248
Jeremy Roman44bda444b2018-03-16 17:33:45249template <typename T>
Jeremy Apthorp6a3480292018-04-26 18:53:59250std::enable_if_t<ToV8ReturnsMaybe<T>::value, bool> TryConvertToV8(
251 v8::Isolate* isolate,
252 const T& input,
253 v8::Local<v8::Value>* output) {
Jeremy Roman44bda444b2018-03-16 17:33:45254 return ConvertToV8(isolate, input).ToLocal(output);
255}
bashidbd2ef9bb2015-06-02 01:39:32256
257template <typename T>
Jeremy Apthorp6a3480292018-04-26 18:53:59258std::enable_if_t<!ToV8ReturnsMaybe<T>::value, bool> TryConvertToV8(
259 v8::Isolate* isolate,
260 const T& input,
261 v8::Local<v8::Value>* output) {
Jeremy Roman44bda444b2018-03-16 17:33:45262 *output = ConvertToV8(isolate, input);
263 return true;
bashidbd2ef9bb2015-06-02 01:39:32264}
265
266// This crashes when input.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48267GIN_EXPORT inline v8::Local<v8::String> StringToV8(
[email protected]48c21632013-12-12 21:32:34268 v8::Isolate* isolate,
269 const base::StringPiece& input) {
[email protected]a22998a2013-11-10 05:00:50270 return ConvertToV8(isolate, input).As<v8::String>();
271}
272
bashidbd2ef9bb2015-06-02 01:39:32273// This crashes when input.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48274GIN_EXPORT v8::Local<v8::String> StringToSymbol(v8::Isolate* isolate,
[email protected]48c21632013-12-12 21:32:34275 const base::StringPiece& val);
[email protected]e87f3122013-11-12 00:41:27276
Shimi Zhang15708bfc2019-08-13 19:24:48277// This crashes when input.size() > v8::String::kMaxLength.
278GIN_EXPORT v8::Local<v8::String> StringToSymbol(v8::Isolate* isolate,
279 const base::StringPiece16& val);
280
[email protected]a22998a2013-11-10 05:00:50281template<typename T>
deepak.sfaaa1b62015-04-30 07:30:48282bool ConvertFromV8(v8::Isolate* isolate, v8::Local<v8::Value> input,
[email protected]7618ebbb2013-11-27 03:38:26283 T* result) {
Dan Elphick712beaa2018-07-24 17:37:24284 DCHECK(isolate);
[email protected]7618ebbb2013-11-27 03:38:26285 return Converter<T>::FromV8(isolate, input, result);
[email protected]a22998a2013-11-10 05:00:50286}
287
Dan Elphick38a508052018-07-23 22:19:53288GIN_EXPORT std::string V8ToString(v8::Isolate* isolate,
289 v8::Local<v8::Value> value);
[email protected]2f703422013-11-25 21:26:15290
[email protected]a22998a2013-11-10 05:00:50291} // namespace gin
292
293#endif // GIN_CONVERTER_H_