[go: nahoru, domu]

blob: 8d17d41c29fba56bd5bae0a66d895f7cd035d79b [file] [log] [blame]
abarth@chromium.orga22998a2013-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
8#include <string>
9#include <vector>
10
bashidbd2ef9bb2015-06-02 01:39:3211#include "base/logging.h"
aa@chromium.orgb520e132013-11-29 03:21:4812#include "base/strings/string_piece.h"
jochen@chromium.org48c21632013-12-12 21:32:3413#include "gin/gin_export.h"
abarth@chromium.orga22998a2013-11-10 05:00:5014#include "v8/include/v8.h"
15
16namespace gin {
bashidbd2ef9bb2015-06-02 01:39:3217
18template<typename KeyType>
19bool SetProperty(v8::Isolate* isolate,
20 v8::Local<v8::Object> object,
21 KeyType key,
22 v8::Local<v8::Value> value) {
23 auto maybe = object->Set(isolate->GetCurrentContext(), key, value);
24 return !maybe.IsNothing() && maybe.FromJust();
25}
26
27template<typename T>
28struct ToV8ReturnsMaybe {
29 static const bool value = false;
30};
abarth@chromium.orga22998a2013-11-10 05:00:5031
aa@chromium.orgcf76c84a2013-12-06 14:07:0732template<typename T, typename Enable = void>
abarth@chromium.orga22998a2013-11-10 05:00:5033struct Converter {};
34
35template<>
jochen@chromium.org48c21632013-12-12 21:32:3436struct GIN_EXPORT Converter<bool> {
deepak.sfaaa1b62015-04-30 07:30:4837 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
abarth@chromium.orga22998a2013-11-10 05:00:5038 bool val);
aa@chromium.org7618ebbb2013-11-27 03:38:2639 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4840 v8::Local<v8::Value> val,
abarth@chromium.orga22998a2013-11-10 05:00:5041 bool* out);
42};
43
44template<>
jochen@chromium.org48c21632013-12-12 21:32:3445struct GIN_EXPORT Converter<int32_t> {
deepak.sfaaa1b62015-04-30 07:30:4846 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
abarth@chromium.orga22998a2013-11-10 05:00:5047 int32_t val);
aa@chromium.org7618ebbb2013-11-27 03:38:2648 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4849 v8::Local<v8::Value> val,
abarth@chromium.orga22998a2013-11-10 05:00:5050 int32_t* out);
51};
52
53template<>
jochen@chromium.org48c21632013-12-12 21:32:3454struct GIN_EXPORT Converter<uint32_t> {
deepak.sfaaa1b62015-04-30 07:30:4855 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
abarth@chromium.orga22998a2013-11-10 05:00:5056 uint32_t val);
aa@chromium.org7618ebbb2013-11-27 03:38:2657 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4858 v8::Local<v8::Value> val,
abarth@chromium.orga22998a2013-11-10 05:00:5059 uint32_t* out);
60};
61
62template<>
jochen@chromium.org48c21632013-12-12 21:32:3463struct GIN_EXPORT Converter<int64_t> {
abarth@chromium.orge87f3122013-11-12 00:41:2764 // Warning: JavaScript cannot represent 64 integers precisely.
deepak.sfaaa1b62015-04-30 07:30:4865 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
abarth@chromium.orge87f3122013-11-12 00:41:2766 int64_t val);
aa@chromium.org7618ebbb2013-11-27 03:38:2667 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4868 v8::Local<v8::Value> val,
abarth@chromium.orge87f3122013-11-12 00:41:2769 int64_t* out);
70};
71
72template<>
jochen@chromium.org48c21632013-12-12 21:32:3473struct GIN_EXPORT Converter<uint64_t> {
abarth@chromium.orge87f3122013-11-12 00:41:2774 // Warning: JavaScript cannot represent 64 integers precisely.
deepak.sfaaa1b62015-04-30 07:30:4875 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
abarth@chromium.orge87f3122013-11-12 00:41:2776 uint64_t val);
aa@chromium.org7618ebbb2013-11-27 03:38:2677 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4878 v8::Local<v8::Value> val,
abarth@chromium.orge87f3122013-11-12 00:41:2779 uint64_t* out);
80};
81
82template<>
aa@chromium.orgd73341d12013-12-21 00:48:4683struct GIN_EXPORT Converter<float> {
deepak.sfaaa1b62015-04-30 07:30:4884 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
aa@chromium.orgd73341d12013-12-21 00:48:4685 float val);
86 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4887 v8::Local<v8::Value> val,
aa@chromium.orgd73341d12013-12-21 00:48:4688 float* out);
89};
90
91template<>
jochen@chromium.org48c21632013-12-12 21:32:3492struct GIN_EXPORT Converter<double> {
deepak.sfaaa1b62015-04-30 07:30:4893 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
abarth@chromium.orga22998a2013-11-10 05:00:5094 double val);
aa@chromium.org7618ebbb2013-11-27 03:38:2695 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4896 v8::Local<v8::Value> val,
abarth@chromium.orga22998a2013-11-10 05:00:5097 double* out);
aa@chromium.orgb520e132013-11-29 03:21:4898};
99
100template<>
jochen@chromium.org48c21632013-12-12 21:32:34101struct GIN_EXPORT Converter<base::StringPiece> {
bashidbd2ef9bb2015-06-02 01:39:32102 // This crashes when val.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48103 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
aa@chromium.orgb520e132013-11-29 03:21:48104 const base::StringPiece& val);
105 // No conversion out is possible because StringPiece does not contain storage.
abarth@chromium.orga22998a2013-11-10 05:00:50106};
107
108template<>
jochen@chromium.org48c21632013-12-12 21:32:34109struct GIN_EXPORT Converter<std::string> {
bashidbd2ef9bb2015-06-02 01:39:32110 // This crashes when val.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48111 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
abarth@chromium.orga22998a2013-11-10 05:00:50112 const std::string& val);
aa@chromium.org7618ebbb2013-11-27 03:38:26113 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48114 v8::Local<v8::Value> val,
abarth@chromium.orga22998a2013-11-10 05:00:50115 std::string* out);
116};
117
118template<>
deepak.sfaaa1b62015-04-30 07:30:48119struct GIN_EXPORT Converter<v8::Local<v8::Function> > {
aa@chromium.org7618ebbb2013-11-27 03:38:26120 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48121 v8::Local<v8::Value> val,
122 v8::Local<v8::Function>* out);
abarth@chromium.orga22998a2013-11-10 05:00:50123};
124
125template<>
deepak.sfaaa1b62015-04-30 07:30:48126struct GIN_EXPORT Converter<v8::Local<v8::Object> > {
127 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
128 v8::Local<v8::Object> val);
aa@chromium.org7618ebbb2013-11-27 03:38:26129 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48130 v8::Local<v8::Value> val,
131 v8::Local<v8::Object>* out);
abarth@chromium.orga22998a2013-11-10 05:00:50132};
133
abarth@chromium.org97f21ca2013-11-17 17:46:07134template<>
deepak.sfaaa1b62015-04-30 07:30:48135struct GIN_EXPORT Converter<v8::Local<v8::ArrayBuffer> > {
136 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
137 v8::Local<v8::ArrayBuffer> val);
aa@chromium.org7618ebbb2013-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::ArrayBuffer>* out);
abarth@chromium.orgec95fdf2013-11-24 19:10:11141};
142
143template<>
deepak.sfaaa1b62015-04-30 07:30:48144struct GIN_EXPORT Converter<v8::Local<v8::External> > {
145 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
146 v8::Local<v8::External> val);
aa@chromium.org7618ebbb2013-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::External>* out);
abarth@chromium.org97f21ca2013-11-17 17:46:07150};
151
152template<>
deepak.sfaaa1b62015-04-30 07:30:48153struct GIN_EXPORT Converter<v8::Local<v8::Value> > {
154 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
155 v8::Local<v8::Value> val);
aa@chromium.org7618ebbb2013-11-27 03:38:26156 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48157 v8::Local<v8::Value> val,
158 v8::Local<v8::Value>* out);
abarth@chromium.org97f21ca2013-11-17 17:46:07159};
160
abarth@chromium.orga22998a2013-11-10 05:00:50161template<typename T>
162struct Converter<std::vector<T> > {
bashidbd2ef9bb2015-06-02 01:39:32163 static v8::MaybeLocal<v8::Value> ToV8(v8::Local<v8::Context> context,
164 const std::vector<T>& val) {
165 v8::Isolate* isolate = context->GetIsolate();
deepak.sfaaa1b62015-04-30 07:30:48166 v8::Local<v8::Array> result(
jochen@chromium.org91cd4fe2013-11-28 09:31:58167 v8::Array::New(isolate, static_cast<int>(val.size())));
bashidbd2ef9bb2015-06-02 01:39:32168 for (uint32_t i = 0; i < val.size(); ++i) {
169 auto maybe = result->Set(context, i, Converter<T>::ToV8(isolate, val[i]));
170 if (maybe.IsNothing() || !maybe.FromJust())
171 return v8::MaybeLocal<v8::Value>();
abarth@chromium.orga22998a2013-11-10 05:00:50172 }
173 return result;
174 }
175
aa@chromium.org7618ebbb2013-11-27 03:38:26176 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48177 v8::Local<v8::Value> val,
abarth@chromium.orga22998a2013-11-10 05:00:50178 std::vector<T>* out) {
179 if (!val->IsArray())
180 return false;
181
182 std::vector<T> result;
deepak.sfaaa1b62015-04-30 07:30:48183 v8::Local<v8::Array> array(v8::Local<v8::Array>::Cast(val));
abarth@chromium.orga22998a2013-11-10 05:00:50184 uint32_t length = array->Length();
185 for (uint32_t i = 0; i < length; ++i) {
bashidbd2ef9bb2015-06-02 01:39:32186 v8::Local<v8::Value> v8_item;
187 if (!array->Get(isolate->GetCurrentContext(), i).ToLocal(&v8_item))
188 return false;
abarth@chromium.orga22998a2013-11-10 05:00:50189 T item;
bashidbd2ef9bb2015-06-02 01:39:32190 if (!Converter<T>::FromV8(isolate, v8_item, &item))
abarth@chromium.orga22998a2013-11-10 05:00:50191 return false;
192 result.push_back(item);
193 }
194
195 out->swap(result);
196 return true;
197 }
198};
199
bashidbd2ef9bb2015-06-02 01:39:32200template<typename T>
201struct ToV8ReturnsMaybe<std::vector<T>> {
202 static const bool value = true;
203};
204
abarth@chromium.orga22998a2013-11-10 05:00:50205// Convenience functions that deduce T.
206template<typename T>
deepak.sfaaa1b62015-04-30 07:30:48207v8::Local<v8::Value> ConvertToV8(v8::Isolate* isolate, T input) {
abarth@chromium.orga22998a2013-11-10 05:00:50208 return Converter<T>::ToV8(isolate, input);
209}
210
bashidbd2ef9bb2015-06-02 01:39:32211template<typename T>
212v8::MaybeLocal<v8::Value> ConvertToV8(v8::Local<v8::Context> context, T input) {
213 return Converter<T>::ToV8(context, input);
214}
215
216template<typename T, bool = ToV8ReturnsMaybe<T>::value> struct ToV8Traits;
217
218template <typename T>
219struct ToV8Traits<T, true> {
220 static bool TryConvertToV8(v8::Isolate* isolate,
221 T input,
222 v8::Local<v8::Value>* output) {
223 auto maybe = ConvertToV8(isolate->GetCurrentContext(), input);
224 if (maybe.IsEmpty())
225 return false;
226 *output = maybe.ToLocalChecked();
227 return true;
228 }
229};
230
231template <typename T>
232struct ToV8Traits<T, false> {
233 static bool TryConvertToV8(v8::Isolate* isolate,
234 T input,
235 v8::Local<v8::Value>* output) {
236 *output = ConvertToV8(isolate, input);
237 return true;
238 }
239};
240
241template <typename T>
242bool TryConvertToV8(v8::Isolate* isolate,
243 T input,
244 v8::Local<v8::Value>* output) {
245 return ToV8Traits<T>::TryConvertToV8(isolate, input, output);
246}
247
248// This crashes when input.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48249GIN_EXPORT inline v8::Local<v8::String> StringToV8(
jochen@chromium.org48c21632013-12-12 21:32:34250 v8::Isolate* isolate,
251 const base::StringPiece& input) {
abarth@chromium.orga22998a2013-11-10 05:00:50252 return ConvertToV8(isolate, input).As<v8::String>();
253}
254
bashidbd2ef9bb2015-06-02 01:39:32255// This crashes when input.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48256GIN_EXPORT v8::Local<v8::String> StringToSymbol(v8::Isolate* isolate,
jochen@chromium.org48c21632013-12-12 21:32:34257 const base::StringPiece& val);
abarth@chromium.orge87f3122013-11-12 00:41:27258
abarth@chromium.orga22998a2013-11-10 05:00:50259template<typename T>
deepak.sfaaa1b62015-04-30 07:30:48260bool ConvertFromV8(v8::Isolate* isolate, v8::Local<v8::Value> input,
aa@chromium.org7618ebbb2013-11-27 03:38:26261 T* result) {
262 return Converter<T>::FromV8(isolate, input, result);
abarth@chromium.orga22998a2013-11-10 05:00:50263}
264
deepak.sfaaa1b62015-04-30 07:30:48265GIN_EXPORT std::string V8ToString(v8::Local<v8::Value> value);
abarth@chromium.org2f703422013-11-25 21:26:15266
abarth@chromium.orga22998a2013-11-10 05:00:50267} // namespace gin
268
269#endif // GIN_CONVERTER_H_