blob: 6f8a421f5d8bdf9e013f6004741b4271070c3c05 [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
Hans Wennborgc8b134b2020-06-19 21:15:3915#include "base/check.h"
16#include "base/notreached.h"
Shimi Zhang15708bfc2019-08-13 19:24:4817#include "base/strings/string16.h"
[email protected]b520e132013-11-29 03:21:4818#include "base/strings/string_piece.h"
[email protected]48c21632013-12-12 21:32:3419#include "gin/gin_export.h"
[email protected]a22998a2013-11-10 05:00:5020#include "v8/include/v8.h"
21
22namespace gin {
23
bashidbd2ef9bb2015-06-02 01:39:3224template<typename KeyType>
25bool SetProperty(v8::Isolate* isolate,
26 v8::Local<v8::Object> object,
27 KeyType key,
28 v8::Local<v8::Value> value) {
rdevlin.cronin415b73b2015-11-13 01:14:4729 auto maybe =
30 object->DefineOwnProperty(isolate->GetCurrentContext(), key, value);
bashidbd2ef9bb2015-06-02 01:39:3231 return !maybe.IsNothing() && maybe.FromJust();
32}
33
Ken Rockot2b0f07652017-04-12 19:10:4934template <typename T, typename Enable = void>
bashidbd2ef9bb2015-06-02 01:39:3235struct ToV8ReturnsMaybe {
36 static const bool value = false;
37};
38
[email protected]cf76c84a2013-12-06 14:07:0739template<typename T, typename Enable = void>
[email protected]a22998a2013-11-10 05:00:5040struct Converter {};
41
42template<>
[email protected]48c21632013-12-12 21:32:3443struct GIN_EXPORT Converter<bool> {
deepak.sfaaa1b62015-04-30 07:30:4844 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:5045 bool val);
[email protected]7618ebbb2013-11-27 03:38:2646 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4847 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:5048 bool* out);
49};
50
51template<>
[email protected]48c21632013-12-12 21:32:3452struct GIN_EXPORT Converter<int32_t> {
deepak.sfaaa1b62015-04-30 07:30:4853 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:5054 int32_t val);
[email protected]7618ebbb2013-11-27 03:38:2655 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4856 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:5057 int32_t* out);
58};
59
60template<>
[email protected]48c21632013-12-12 21:32:3461struct GIN_EXPORT Converter<uint32_t> {
deepak.sfaaa1b62015-04-30 07:30:4862 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:5063 uint32_t val);
[email protected]7618ebbb2013-11-27 03:38:2664 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4865 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:5066 uint32_t* out);
67};
68
69template<>
[email protected]48c21632013-12-12 21:32:3470struct GIN_EXPORT Converter<int64_t> {
[email protected]e87f3122013-11-12 00:41:2771 // Warning: JavaScript cannot represent 64 integers precisely.
deepak.sfaaa1b62015-04-30 07:30:4872 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]e87f3122013-11-12 00:41:2773 int64_t val);
[email protected]7618ebbb2013-11-27 03:38:2674 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4875 v8::Local<v8::Value> val,
[email protected]e87f3122013-11-12 00:41:2776 int64_t* out);
77};
78
79template<>
[email protected]48c21632013-12-12 21:32:3480struct GIN_EXPORT Converter<uint64_t> {
[email protected]e87f3122013-11-12 00:41:2781 // Warning: JavaScript cannot represent 64 integers precisely.
deepak.sfaaa1b62015-04-30 07:30:4882 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]e87f3122013-11-12 00:41:2783 uint64_t val);
[email protected]7618ebbb2013-11-27 03:38:2684 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4885 v8::Local<v8::Value> val,
[email protected]e87f3122013-11-12 00:41:2786 uint64_t* out);
87};
88
89template<>
[email protected]d73341d12013-12-21 00:48:4690struct GIN_EXPORT Converter<float> {
deepak.sfaaa1b62015-04-30 07:30:4891 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]d73341d12013-12-21 00:48:4692 float val);
93 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4894 v8::Local<v8::Value> val,
[email protected]d73341d12013-12-21 00:48:4695 float* out);
96};
97
98template<>
[email protected]48c21632013-12-12 21:32:3499struct GIN_EXPORT Converter<double> {
deepak.sfaaa1b62015-04-30 07:30:48100 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:50101 double val);
[email protected]7618ebbb2013-11-27 03:38:26102 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48103 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:50104 double* out);
105};
106
107template<>
[email protected]48c21632013-12-12 21:32:34108struct GIN_EXPORT Converter<base::StringPiece> {
bashidbd2ef9bb2015-06-02 01:39:32109 // This crashes when val.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48110 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]b520e132013-11-29 03:21:48111 const base::StringPiece& val);
112 // No conversion out is possible because StringPiece does not contain storage.
113};
114
115template<>
[email protected]48c21632013-12-12 21:32:34116struct GIN_EXPORT Converter<std::string> {
bashidbd2ef9bb2015-06-02 01:39:32117 // This crashes when val.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48118 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:50119 const std::string& val);
[email protected]7618ebbb2013-11-27 03:38:26120 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48121 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:50122 std::string* out);
123};
124
Shimi Zhang15708bfc2019-08-13 19:24:48125template <>
Jan Wilken Dörrie739ccc212021-03-11 18:13:05126struct GIN_EXPORT Converter<std::u16string> {
Shimi Zhang15708bfc2019-08-13 19:24:48127 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
Jan Wilken Dörrie739ccc212021-03-11 18:13:05128 const std::u16string& val);
Shimi Zhang15708bfc2019-08-13 19:24:48129 static bool FromV8(v8::Isolate* isolate,
130 v8::Local<v8::Value> val,
Jan Wilken Dörrie739ccc212021-03-11 18:13:05131 std::u16string* out);
Shimi Zhang15708bfc2019-08-13 19:24:48132};
133
134template <>
135struct GIN_EXPORT Converter<v8::Local<v8::Function>> {
Nitish Sakhawalkarf7bbaa522019-02-11 16:19:09136 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
137 v8::Local<v8::Function> val);
[email protected]7618ebbb2013-11-27 03:38:26138 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48139 v8::Local<v8::Value> val,
140 v8::Local<v8::Function>* out);
[email protected]a22998a2013-11-10 05:00:50141};
142
143template<>
deepak.sfaaa1b62015-04-30 07:30:48144struct GIN_EXPORT Converter<v8::Local<v8::Object> > {
145 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
146 v8::Local<v8::Object> val);
[email protected]7618ebbb2013-11-27 03:38:26147 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48148 v8::Local<v8::Value> val,
149 v8::Local<v8::Object>* out);
[email protected]a22998a2013-11-10 05:00:50150};
151
Scott Grahamd2f4ed4b2018-10-17 01:57:27152template <>
153struct GIN_EXPORT Converter<v8::Local<v8::Promise>> {
154 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
155 v8::Local<v8::Promise> val);
156 static bool FromV8(v8::Isolate* isolate,
157 v8::Local<v8::Value> val,
158 v8::Local<v8::Promise>* out);
159};
160
[email protected]97f21ca2013-11-17 17:46:07161template<>
deepak.sfaaa1b62015-04-30 07:30:48162struct GIN_EXPORT Converter<v8::Local<v8::ArrayBuffer> > {
163 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
164 v8::Local<v8::ArrayBuffer> val);
[email protected]7618ebbb2013-11-27 03:38:26165 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48166 v8::Local<v8::Value> val,
167 v8::Local<v8::ArrayBuffer>* out);
[email protected]ec95fdf2013-11-24 19:10:11168};
169
170template<>
deepak.sfaaa1b62015-04-30 07:30:48171struct GIN_EXPORT Converter<v8::Local<v8::External> > {
172 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
173 v8::Local<v8::External> val);
[email protected]7618ebbb2013-11-27 03:38:26174 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48175 v8::Local<v8::Value> val,
176 v8::Local<v8::External>* out);
[email protected]97f21ca2013-11-17 17:46:07177};
178
179template<>
deepak.sfaaa1b62015-04-30 07:30:48180struct GIN_EXPORT Converter<v8::Local<v8::Value> > {
181 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
182 v8::Local<v8::Value> val);
[email protected]7618ebbb2013-11-27 03:38:26183 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48184 v8::Local<v8::Value> val,
185 v8::Local<v8::Value>* out);
[email protected]97f21ca2013-11-17 17:46:07186};
187
[email protected]a22998a2013-11-10 05:00:50188template<typename T>
189struct Converter<std::vector<T> > {
Jeremy Romaneb8a2f172018-01-29 17:33:40190 static std::conditional_t<ToV8ReturnsMaybe<T>::value,
191 v8::MaybeLocal<v8::Value>,
192 v8::Local<v8::Value>>
193 ToV8(v8::Isolate* isolate, const std::vector<T>& val) {
194 v8::Local<v8::Context> context = isolate->GetCurrentContext();
deepak.sfaaa1b62015-04-30 07:30:48195 v8::Local<v8::Array> result(
[email protected]91cd4fe2013-11-28 09:31:58196 v8::Array::New(isolate, static_cast<int>(val.size())));
bashidbd2ef9bb2015-06-02 01:39:32197 for (uint32_t i = 0; i < val.size(); ++i) {
Jeremy Romaneb8a2f172018-01-29 17:33:40198 v8::MaybeLocal<v8::Value> maybe = Converter<T>::ToV8(isolate, val[i]);
199 v8::Local<v8::Value> element;
200 if (!maybe.ToLocal(&element))
201 return {};
202 bool property_created;
203 if (!result->CreateDataProperty(context, i, element)
204 .To(&property_created) ||
205 !property_created) {
206 NOTREACHED() << "CreateDataProperty should always succeed here.";
207 }
[email protected]a22998a2013-11-10 05:00:50208 }
209 return result;
210 }
211
[email protected]7618ebbb2013-11-27 03:38:26212 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48213 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:50214 std::vector<T>* out) {
215 if (!val->IsArray())
216 return false;
217
218 std::vector<T> result;
deepak.sfaaa1b62015-04-30 07:30:48219 v8::Local<v8::Array> array(v8::Local<v8::Array>::Cast(val));
[email protected]a22998a2013-11-10 05:00:50220 uint32_t length = array->Length();
221 for (uint32_t i = 0; i < length; ++i) {
bashidbd2ef9bb2015-06-02 01:39:32222 v8::Local<v8::Value> v8_item;
223 if (!array->Get(isolate->GetCurrentContext(), i).ToLocal(&v8_item))
224 return false;
[email protected]a22998a2013-11-10 05:00:50225 T item;
bashidbd2ef9bb2015-06-02 01:39:32226 if (!Converter<T>::FromV8(isolate, v8_item, &item))
[email protected]a22998a2013-11-10 05:00:50227 return false;
228 result.push_back(item);
229 }
230
231 out->swap(result);
232 return true;
233 }
234};
235
bashidbd2ef9bb2015-06-02 01:39:32236template<typename T>
237struct ToV8ReturnsMaybe<std::vector<T>> {
Jeremy Romaneb8a2f172018-01-29 17:33:40238 static const bool value = ToV8ReturnsMaybe<T>::value;
bashidbd2ef9bb2015-06-02 01:39:32239};
240
[email protected]a22998a2013-11-10 05:00:50241// Convenience functions that deduce T.
Jeremy Romaneb8a2f172018-01-29 17:33:40242template <typename T>
243std::conditional_t<ToV8ReturnsMaybe<T>::value,
244 v8::MaybeLocal<v8::Value>,
245 v8::Local<v8::Value>>
Jeremy Apthorp6a3480292018-04-26 18:53:59246ConvertToV8(v8::Isolate* isolate, const T& input) {
[email protected]a22998a2013-11-10 05:00:50247 return Converter<T>::ToV8(isolate, input);
248}
249
Jeremy Roman44bda444b2018-03-16 17:33:45250template <typename T>
Jeremy Apthorp6a3480292018-04-26 18:53:59251std::enable_if_t<ToV8ReturnsMaybe<T>::value, bool> TryConvertToV8(
252 v8::Isolate* isolate,
253 const T& input,
254 v8::Local<v8::Value>* output) {
Jeremy Roman44bda444b2018-03-16 17:33:45255 return ConvertToV8(isolate, input).ToLocal(output);
256}
bashidbd2ef9bb2015-06-02 01:39:32257
258template <typename T>
Jeremy Apthorp6a3480292018-04-26 18:53:59259std::enable_if_t<!ToV8ReturnsMaybe<T>::value, bool> TryConvertToV8(
260 v8::Isolate* isolate,
261 const T& input,
262 v8::Local<v8::Value>* output) {
Jeremy Roman44bda444b2018-03-16 17:33:45263 *output = ConvertToV8(isolate, input);
264 return true;
bashidbd2ef9bb2015-06-02 01:39:32265}
266
267// This crashes when input.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48268GIN_EXPORT inline v8::Local<v8::String> StringToV8(
[email protected]48c21632013-12-12 21:32:34269 v8::Isolate* isolate,
270 const base::StringPiece& input) {
[email protected]a22998a2013-11-10 05:00:50271 return ConvertToV8(isolate, input).As<v8::String>();
272}
273
bashidbd2ef9bb2015-06-02 01:39:32274// This crashes when input.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48275GIN_EXPORT v8::Local<v8::String> StringToSymbol(v8::Isolate* isolate,
[email protected]48c21632013-12-12 21:32:34276 const base::StringPiece& val);
[email protected]e87f3122013-11-12 00:41:27277
Shimi Zhang15708bfc2019-08-13 19:24:48278// This crashes when input.size() > v8::String::kMaxLength.
279GIN_EXPORT v8::Local<v8::String> StringToSymbol(v8::Isolate* isolate,
280 const base::StringPiece16& val);
281
[email protected]a22998a2013-11-10 05:00:50282template<typename T>
deepak.sfaaa1b62015-04-30 07:30:48283bool ConvertFromV8(v8::Isolate* isolate, v8::Local<v8::Value> input,
[email protected]7618ebbb2013-11-27 03:38:26284 T* result) {
Dan Elphick712beaa2018-07-24 17:37:24285 DCHECK(isolate);
[email protected]7618ebbb2013-11-27 03:38:26286 return Converter<T>::FromV8(isolate, input, result);
[email protected]a22998a2013-11-10 05:00:50287}
288
Dan Elphick38a508052018-07-23 22:19:53289GIN_EXPORT std::string V8ToString(v8::Isolate* isolate,
290 v8::Local<v8::Value> value);
[email protected]2f703422013-11-25 21:26:15291
[email protected]a22998a2013-11-10 05:00:50292} // namespace gin
293
294#endif // GIN_CONVERTER_H_