blob: 72c1d709d8f7683a0288aeaa941c62a3c88feeea [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"
[email protected]b520e132013-11-29 03:21:4815#include "base/strings/string_piece.h"
[email protected]48c21632013-12-12 21:32:3416#include "gin/gin_export.h"
[email protected]a22998a2013-11-10 05:00:5017#include "v8/include/v8.h"
18
19namespace gin {
20
bashidbd2ef9bb2015-06-02 01:39:3221template<typename KeyType>
22bool SetProperty(v8::Isolate* isolate,
23 v8::Local<v8::Object> object,
24 KeyType key,
25 v8::Local<v8::Value> value) {
rdevlin.cronin415b73b2015-11-13 01:14:4726 auto maybe =
27 object->DefineOwnProperty(isolate->GetCurrentContext(), key, value);
bashidbd2ef9bb2015-06-02 01:39:3228 return !maybe.IsNothing() && maybe.FromJust();
29}
30
Ken Rockot2b0f07652017-04-12 19:10:4931template <typename T, typename Enable = void>
bashidbd2ef9bb2015-06-02 01:39:3232struct ToV8ReturnsMaybe {
33 static const bool value = false;
34};
35
[email protected]cf76c84a2013-12-06 14:07:0736template<typename T, typename Enable = void>
[email protected]a22998a2013-11-10 05:00:5037struct Converter {};
38
39template<>
[email protected]48c21632013-12-12 21:32:3440struct GIN_EXPORT Converter<bool> {
deepak.sfaaa1b62015-04-30 07:30:4841 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:5042 bool val);
[email protected]7618ebbb2013-11-27 03:38:2643 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4844 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:5045 bool* out);
46};
47
48template<>
[email protected]48c21632013-12-12 21:32:3449struct GIN_EXPORT Converter<int32_t> {
deepak.sfaaa1b62015-04-30 07:30:4850 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:5051 int32_t val);
[email protected]7618ebbb2013-11-27 03:38:2652 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4853 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:5054 int32_t* out);
55};
56
57template<>
[email protected]48c21632013-12-12 21:32:3458struct GIN_EXPORT Converter<uint32_t> {
deepak.sfaaa1b62015-04-30 07:30:4859 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:5060 uint32_t val);
[email protected]7618ebbb2013-11-27 03:38:2661 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4862 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:5063 uint32_t* out);
64};
65
66template<>
[email protected]48c21632013-12-12 21:32:3467struct GIN_EXPORT Converter<int64_t> {
[email protected]e87f3122013-11-12 00:41:2768 // Warning: JavaScript cannot represent 64 integers precisely.
deepak.sfaaa1b62015-04-30 07:30:4869 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]e87f3122013-11-12 00:41:2770 int64_t val);
[email protected]7618ebbb2013-11-27 03:38:2671 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4872 v8::Local<v8::Value> val,
[email protected]e87f3122013-11-12 00:41:2773 int64_t* out);
74};
75
76template<>
[email protected]48c21632013-12-12 21:32:3477struct GIN_EXPORT Converter<uint64_t> {
[email protected]e87f3122013-11-12 00:41:2778 // Warning: JavaScript cannot represent 64 integers precisely.
deepak.sfaaa1b62015-04-30 07:30:4879 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]e87f3122013-11-12 00:41:2780 uint64_t val);
[email protected]7618ebbb2013-11-27 03:38:2681 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4882 v8::Local<v8::Value> val,
[email protected]e87f3122013-11-12 00:41:2783 uint64_t* out);
84};
85
86template<>
[email protected]d73341d12013-12-21 00:48:4687struct GIN_EXPORT Converter<float> {
deepak.sfaaa1b62015-04-30 07:30:4888 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]d73341d12013-12-21 00:48:4689 float val);
90 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4891 v8::Local<v8::Value> val,
[email protected]d73341d12013-12-21 00:48:4692 float* out);
93};
94
95template<>
[email protected]48c21632013-12-12 21:32:3496struct GIN_EXPORT Converter<double> {
deepak.sfaaa1b62015-04-30 07:30:4897 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:5098 double val);
[email protected]7618ebbb2013-11-27 03:38:2699 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48100 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:50101 double* out);
102};
103
104template<>
[email protected]48c21632013-12-12 21:32:34105struct GIN_EXPORT Converter<base::StringPiece> {
bashidbd2ef9bb2015-06-02 01:39:32106 // This crashes when val.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48107 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]b520e132013-11-29 03:21:48108 const base::StringPiece& val);
109 // No conversion out is possible because StringPiece does not contain storage.
110};
111
112template<>
[email protected]48c21632013-12-12 21:32:34113struct GIN_EXPORT Converter<std::string> {
bashidbd2ef9bb2015-06-02 01:39:32114 // This crashes when val.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48115 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:50116 const std::string& val);
[email protected]7618ebbb2013-11-27 03:38:26117 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48118 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:50119 std::string* out);
120};
121
122template<>
deepak.sfaaa1b62015-04-30 07:30:48123struct GIN_EXPORT Converter<v8::Local<v8::Function> > {
[email protected]7618ebbb2013-11-27 03:38:26124 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48125 v8::Local<v8::Value> val,
126 v8::Local<v8::Function>* out);
[email protected]a22998a2013-11-10 05:00:50127};
128
129template<>
deepak.sfaaa1b62015-04-30 07:30:48130struct GIN_EXPORT Converter<v8::Local<v8::Object> > {
131 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
132 v8::Local<v8::Object> val);
[email protected]7618ebbb2013-11-27 03:38:26133 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48134 v8::Local<v8::Value> val,
135 v8::Local<v8::Object>* out);
[email protected]a22998a2013-11-10 05:00:50136};
137
[email protected]97f21ca2013-11-17 17:46:07138template<>
deepak.sfaaa1b62015-04-30 07:30:48139struct GIN_EXPORT Converter<v8::Local<v8::ArrayBuffer> > {
140 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
141 v8::Local<v8::ArrayBuffer> val);
[email protected]7618ebbb2013-11-27 03:38:26142 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48143 v8::Local<v8::Value> val,
144 v8::Local<v8::ArrayBuffer>* out);
[email protected]ec95fdf2013-11-24 19:10:11145};
146
147template<>
deepak.sfaaa1b62015-04-30 07:30:48148struct GIN_EXPORT Converter<v8::Local<v8::External> > {
149 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
150 v8::Local<v8::External> val);
[email protected]7618ebbb2013-11-27 03:38:26151 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48152 v8::Local<v8::Value> val,
153 v8::Local<v8::External>* out);
[email protected]97f21ca2013-11-17 17:46:07154};
155
156template<>
deepak.sfaaa1b62015-04-30 07:30:48157struct GIN_EXPORT Converter<v8::Local<v8::Value> > {
158 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
159 v8::Local<v8::Value> val);
[email protected]7618ebbb2013-11-27 03:38:26160 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48161 v8::Local<v8::Value> val,
162 v8::Local<v8::Value>* out);
[email protected]97f21ca2013-11-17 17:46:07163};
164
[email protected]a22998a2013-11-10 05:00:50165template<typename T>
166struct Converter<std::vector<T> > {
Jeremy Romaneb8a2f172018-01-29 17:33:40167 static std::conditional_t<ToV8ReturnsMaybe<T>::value,
168 v8::MaybeLocal<v8::Value>,
169 v8::Local<v8::Value>>
170 ToV8(v8::Isolate* isolate, const std::vector<T>& val) {
171 v8::Local<v8::Context> context = isolate->GetCurrentContext();
deepak.sfaaa1b62015-04-30 07:30:48172 v8::Local<v8::Array> result(
[email protected]91cd4fe2013-11-28 09:31:58173 v8::Array::New(isolate, static_cast<int>(val.size())));
bashidbd2ef9bb2015-06-02 01:39:32174 for (uint32_t i = 0; i < val.size(); ++i) {
Jeremy Romaneb8a2f172018-01-29 17:33:40175 v8::MaybeLocal<v8::Value> maybe = Converter<T>::ToV8(isolate, val[i]);
176 v8::Local<v8::Value> element;
177 if (!maybe.ToLocal(&element))
178 return {};
179 bool property_created;
180 if (!result->CreateDataProperty(context, i, element)
181 .To(&property_created) ||
182 !property_created) {
183 NOTREACHED() << "CreateDataProperty should always succeed here.";
184 }
[email protected]a22998a2013-11-10 05:00:50185 }
186 return result;
187 }
188
[email protected]7618ebbb2013-11-27 03:38:26189 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48190 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:50191 std::vector<T>* out) {
192 if (!val->IsArray())
193 return false;
194
195 std::vector<T> result;
deepak.sfaaa1b62015-04-30 07:30:48196 v8::Local<v8::Array> array(v8::Local<v8::Array>::Cast(val));
[email protected]a22998a2013-11-10 05:00:50197 uint32_t length = array->Length();
198 for (uint32_t i = 0; i < length; ++i) {
bashidbd2ef9bb2015-06-02 01:39:32199 v8::Local<v8::Value> v8_item;
200 if (!array->Get(isolate->GetCurrentContext(), i).ToLocal(&v8_item))
201 return false;
[email protected]a22998a2013-11-10 05:00:50202 T item;
bashidbd2ef9bb2015-06-02 01:39:32203 if (!Converter<T>::FromV8(isolate, v8_item, &item))
[email protected]a22998a2013-11-10 05:00:50204 return false;
205 result.push_back(item);
206 }
207
208 out->swap(result);
209 return true;
210 }
211};
212
bashidbd2ef9bb2015-06-02 01:39:32213template<typename T>
214struct ToV8ReturnsMaybe<std::vector<T>> {
Jeremy Romaneb8a2f172018-01-29 17:33:40215 static const bool value = ToV8ReturnsMaybe<T>::value;
bashidbd2ef9bb2015-06-02 01:39:32216};
217
[email protected]a22998a2013-11-10 05:00:50218// Convenience functions that deduce T.
Jeremy Romaneb8a2f172018-01-29 17:33:40219template <typename T>
220std::conditional_t<ToV8ReturnsMaybe<T>::value,
221 v8::MaybeLocal<v8::Value>,
222 v8::Local<v8::Value>>
Jeremy Apthorp6a3480292018-04-26 18:53:59223ConvertToV8(v8::Isolate* isolate, const T& input) {
[email protected]a22998a2013-11-10 05:00:50224 return Converter<T>::ToV8(isolate, input);
225}
226
Jeremy Roman44bda444b2018-03-16 17:33:45227template <typename T>
Jeremy Apthorp6a3480292018-04-26 18:53:59228std::enable_if_t<ToV8ReturnsMaybe<T>::value, bool> TryConvertToV8(
229 v8::Isolate* isolate,
230 const T& input,
231 v8::Local<v8::Value>* output) {
Jeremy Roman44bda444b2018-03-16 17:33:45232 return ConvertToV8(isolate, input).ToLocal(output);
233}
bashidbd2ef9bb2015-06-02 01:39:32234
235template <typename T>
Jeremy Apthorp6a3480292018-04-26 18:53:59236std::enable_if_t<!ToV8ReturnsMaybe<T>::value, bool> TryConvertToV8(
237 v8::Isolate* isolate,
238 const T& input,
239 v8::Local<v8::Value>* output) {
Jeremy Roman44bda444b2018-03-16 17:33:45240 *output = ConvertToV8(isolate, input);
241 return true;
bashidbd2ef9bb2015-06-02 01:39:32242}
243
244// This crashes when input.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48245GIN_EXPORT inline v8::Local<v8::String> StringToV8(
[email protected]48c21632013-12-12 21:32:34246 v8::Isolate* isolate,
247 const base::StringPiece& input) {
[email protected]a22998a2013-11-10 05:00:50248 return ConvertToV8(isolate, input).As<v8::String>();
249}
250
bashidbd2ef9bb2015-06-02 01:39:32251// This crashes when input.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48252GIN_EXPORT v8::Local<v8::String> StringToSymbol(v8::Isolate* isolate,
[email protected]48c21632013-12-12 21:32:34253 const base::StringPiece& val);
[email protected]e87f3122013-11-12 00:41:27254
[email protected]a22998a2013-11-10 05:00:50255template<typename T>
deepak.sfaaa1b62015-04-30 07:30:48256bool ConvertFromV8(v8::Isolate* isolate, v8::Local<v8::Value> input,
[email protected]7618ebbb2013-11-27 03:38:26257 T* result) {
258 return Converter<T>::FromV8(isolate, input, result);
[email protected]a22998a2013-11-10 05:00:50259}
260
Dan Elphick38a508052018-07-23 22:19:53261GIN_EXPORT std::string V8ToString(v8::Isolate* isolate,
262 v8::Local<v8::Value> value);
[email protected]2f703422013-11-25 21:26:15263
[email protected]a22998a2013-11-10 05:00:50264} // namespace gin
265
266#endif // GIN_CONVERTER_H_