1 // Copyright 2013 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "gin/converter.h"
9 #include "base/strings/string_util.h"
10 #include "base/time/time.h"
11 #include "v8/include/v8-array-buffer.h"
12 #include "v8/include/v8-external.h"
13 #include "v8/include/v8-function.h"
14 #include "v8/include/v8-maybe.h"
15 #include "v8/include/v8-object.h"
16 #include "v8/include/v8-primitive.h"
17 #include "v8/include/v8-promise.h"
18 #include "v8/include/v8-value.h"
20 using v8::ArrayBuffer;
38 template <typename T, typename U>
39 bool FromMaybe(Maybe<T> maybe, U* out) {
40 if (maybe.IsNothing())
42 *out = static_cast<U>(maybe.FromJust());
50 Local<Value> Converter<bool>::ToV8(Isolate* isolate, bool val) {
51 return v8::Boolean::New(isolate, val).As<Value>();
54 bool Converter<bool>::FromV8(Isolate* isolate, Local<Value> val, bool* out) {
55 *out = val->BooleanValue(isolate);
56 // BooleanValue cannot throw.
60 Local<Value> Converter<int32_t>::ToV8(Isolate* isolate, int32_t val) {
61 return Integer::New(isolate, val).As<Value>();
64 bool Converter<int32_t>::FromV8(Isolate* isolate,
69 *out = val.As<Int32>()->Value();
73 Local<Value> Converter<uint32_t>::ToV8(Isolate* isolate, uint32_t val) {
74 return Integer::NewFromUnsigned(isolate, val).As<Value>();
77 bool Converter<uint32_t>::FromV8(Isolate* isolate,
82 *out = val.As<Uint32>()->Value();
86 Local<Value> Converter<int64_t>::ToV8(Isolate* isolate, int64_t val) {
87 return Number::New(isolate, static_cast<double>(val)).As<Value>();
90 bool Converter<int64_t>::FromV8(Isolate* isolate,
95 // Even though IntegerValue returns int64_t, JavaScript cannot represent
96 // the full precision of int64_t, which means some rounding might occur.
97 return FromMaybe(val->IntegerValue(isolate->GetCurrentContext()), out);
100 Local<Value> Converter<uint64_t>::ToV8(Isolate* isolate, uint64_t val) {
101 return Number::New(isolate, static_cast<double>(val)).As<Value>();
104 bool Converter<uint64_t>::FromV8(Isolate* isolate,
107 if (!val->IsNumber())
109 return FromMaybe(val->IntegerValue(isolate->GetCurrentContext()), out);
112 Local<Value> Converter<float>::ToV8(Isolate* isolate, float val) {
113 return Number::New(isolate, val).As<Value>();
116 bool Converter<float>::FromV8(Isolate* isolate, Local<Value> val, float* out) {
117 if (!val->IsNumber())
119 *out = static_cast<float>(val.As<Number>()->Value());
123 Local<Value> Converter<double>::ToV8(Isolate* isolate, double val) {
124 return Number::New(isolate, val).As<Value>();
127 bool Converter<double>::FromV8(Isolate* isolate,
130 if (!val->IsNumber())
132 *out = val.As<Number>()->Value();
136 Local<Value> Converter<base::StringPiece>::ToV8(Isolate* isolate,
137 const base::StringPiece& val) {
138 return String::NewFromUtf8(isolate, val.data(),
139 v8::NewStringType::kNormal,
140 static_cast<uint32_t>(val.length()))
144 Local<Value> Converter<std::string>::ToV8(Isolate* isolate,
145 const std::string& val) {
146 return Converter<base::StringPiece>::ToV8(isolate, val);
149 bool Converter<std::string>::FromV8(Isolate* isolate,
152 if (!val->IsString())
154 Local<String> str = Local<String>::Cast(val);
155 int length = str->Utf8Length(isolate);
157 str->WriteUtf8(isolate, &(*out)[0], length, NULL,
158 String::NO_NULL_TERMINATION);
162 Local<Value> Converter<std::u16string>::ToV8(Isolate* isolate,
163 const std::u16string& val) {
164 return String::NewFromTwoByte(isolate,
165 reinterpret_cast<const uint16_t*>(val.data()),
166 v8::NewStringType::kNormal, val.size())
170 bool Converter<std::u16string>::FromV8(Isolate* isolate,
172 std::u16string* out) {
173 if (!val->IsString())
175 Local<String> str = Local<String>::Cast(val);
176 int length = str->Length();
177 // Note that the reinterpret cast is because on Windows string16 is an alias
178 // to wstring, and hence has character type wchar_t not uint16_t.
180 reinterpret_cast<uint16_t*>(base::WriteInto(out, length + 1)), 0,
185 v8::Local<v8::Value> Converter<base::TimeTicks>::ToV8(v8::Isolate* isolate,
186 base::TimeTicks val) {
187 return v8::BigInt::New(isolate, val.since_origin().InMicroseconds())
191 Local<Value> Converter<Local<Function>>::ToV8(Isolate* isolate,
192 Local<Function> val) {
193 return val.As<Value>();
196 bool Converter<Local<Function>>::FromV8(Isolate* isolate,
198 Local<Function>* out) {
199 if (!val->IsFunction())
201 *out = Local<Function>::Cast(val);
205 Local<Value> Converter<Local<Object>>::ToV8(Isolate* isolate,
207 return val.As<Value>();
210 bool Converter<Local<Object>>::FromV8(Isolate* isolate,
212 Local<Object>* out) {
213 if (!val->IsObject())
215 *out = Local<Object>::Cast(val);
219 Local<Value> Converter<Local<Promise>>::ToV8(Isolate* isolate,
220 Local<Promise> val) {
221 return val.As<Value>();
224 bool Converter<Local<Promise>>::FromV8(Isolate* isolate,
226 Local<Promise>* out) {
227 if (!val->IsPromise())
229 *out = Local<Promise>::Cast(val);
233 Local<Value> Converter<Local<ArrayBuffer>>::ToV8(Isolate* isolate,
234 Local<ArrayBuffer> val) {
235 return val.As<Value>();
238 bool Converter<Local<ArrayBuffer>>::FromV8(Isolate* isolate,
240 Local<ArrayBuffer>* out) {
241 if (!val->IsArrayBuffer())
243 *out = Local<ArrayBuffer>::Cast(val);
247 Local<Value> Converter<Local<External>>::ToV8(Isolate* isolate,
248 Local<External> val) {
249 return val.As<Value>();
252 bool Converter<Local<External>>::FromV8(Isolate* isolate,
253 v8::Local<Value> val,
254 Local<External>* out) {
255 if (!val->IsExternal())
257 *out = Local<External>::Cast(val);
261 Local<Value> Converter<Local<Value>>::ToV8(Isolate* isolate, Local<Value> val) {
265 bool Converter<Local<Value>>::FromV8(Isolate* isolate,
272 v8::Local<v8::String> StringToSymbol(v8::Isolate* isolate,
273 const base::StringPiece& val) {
274 return String::NewFromUtf8(isolate, val.data(),
275 v8::NewStringType::kInternalized,
276 static_cast<uint32_t>(val.length()))
280 v8::Local<v8::String> StringToSymbol(v8::Isolate* isolate,
281 const base::StringPiece16& val) {
282 return String::NewFromTwoByte(isolate,
283 reinterpret_cast<const uint16_t*>(val.data()),
284 v8::NewStringType::kInternalized, val.length())
288 std::string V8ToString(v8::Isolate* isolate, v8::Local<v8::Value> value) {
290 return std::string();
292 if (!ConvertFromV8(isolate, value, &result))
293 return std::string();