1// 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#include "gin/converter.h"
6
7#include "v8/include/v8.h"
8
9using v8::ArrayBuffer;
10using v8::Boolean;
11using v8::External;
12using v8::Function;
13using v8::Handle;
14using v8::Integer;
15using v8::Isolate;
16using v8::Number;
17using v8::Object;
18using v8::String;
19using v8::Value;
20
21namespace gin {
22
23Handle<Value> Converter<bool>::ToV8(Isolate* isolate, bool val) {
24  return Boolean::New(isolate, val).As<Value>();
25}
26
27bool Converter<bool>::FromV8(Isolate* isolate, Handle<Value> val, bool* out) {
28  *out = val->BooleanValue();
29  return true;
30}
31
32Handle<Value> Converter<int32_t>::ToV8(Isolate* isolate, int32_t val) {
33  return Integer::New(isolate, val).As<Value>();
34}
35
36bool Converter<int32_t>::FromV8(Isolate* isolate, Handle<Value> val,
37                                int32_t* out) {
38  if (!val->IsInt32())
39    return false;
40  *out = val->Int32Value();
41  return true;
42}
43
44Handle<Value> Converter<uint32_t>::ToV8(Isolate* isolate, uint32_t val) {
45  return Integer::NewFromUnsigned(isolate, val).As<Value>();
46}
47
48bool Converter<uint32_t>::FromV8(Isolate* isolate, Handle<Value> val,
49                                 uint32_t* out) {
50  if (!val->IsUint32())
51    return false;
52  *out = val->Uint32Value();
53  return true;
54}
55
56Handle<Value> Converter<int64_t>::ToV8(Isolate* isolate, int64_t val) {
57  return Number::New(isolate, static_cast<double>(val)).As<Value>();
58}
59
60bool Converter<int64_t>::FromV8(Isolate* isolate, Handle<Value> val,
61                                int64_t* out) {
62  if (!val->IsNumber())
63    return false;
64  // Even though IntegerValue returns int64_t, JavaScript cannot represent
65  // the full precision of int64_t, which means some rounding might occur.
66  *out = val->IntegerValue();
67  return true;
68}
69
70Handle<Value> Converter<uint64_t>::ToV8(Isolate* isolate, uint64_t val) {
71  return Number::New(isolate, static_cast<double>(val)).As<Value>();
72}
73
74bool Converter<uint64_t>::FromV8(Isolate* isolate, Handle<Value> val,
75                                 uint64_t* out) {
76  if (!val->IsNumber())
77    return false;
78  *out = static_cast<uint64_t>(val->IntegerValue());
79  return true;
80}
81
82Handle<Value> Converter<float>::ToV8(Isolate* isolate, float val) {
83  return Number::New(isolate, val).As<Value>();
84}
85
86bool Converter<float>::FromV8(Isolate* isolate, Handle<Value> val,
87                              float* out) {
88  if (!val->IsNumber())
89    return false;
90  *out = static_cast<float>(val->NumberValue());
91  return true;
92}
93
94Handle<Value> Converter<double>::ToV8(Isolate* isolate, double val) {
95  return Number::New(isolate, val).As<Value>();
96}
97
98bool Converter<double>::FromV8(Isolate* isolate, Handle<Value> val,
99                               double* out) {
100  if (!val->IsNumber())
101    return false;
102  *out = val->NumberValue();
103  return true;
104}
105
106Handle<Value> Converter<base::StringPiece>::ToV8(
107    Isolate* isolate, const base::StringPiece& val) {
108  return String::NewFromUtf8(isolate, val.data(), String::kNormalString,
109                             static_cast<uint32_t>(val.length()));
110}
111
112Handle<Value> Converter<std::string>::ToV8(Isolate* isolate,
113                                           const std::string& val) {
114  return Converter<base::StringPiece>::ToV8(isolate, val);
115}
116
117bool Converter<std::string>::FromV8(Isolate* isolate, Handle<Value> val,
118                                    std::string* out) {
119  if (!val->IsString())
120    return false;
121  Handle<String> str = Handle<String>::Cast(val);
122  int length = str->Utf8Length();
123  out->resize(length);
124  str->WriteUtf8(&(*out)[0], length, NULL, String::NO_NULL_TERMINATION);
125  return true;
126}
127
128bool Converter<Handle<Function> >::FromV8(Isolate* isolate, Handle<Value> val,
129                                          Handle<Function>* out) {
130  if (!val->IsFunction())
131    return false;
132  *out = Handle<Function>::Cast(val);
133  return true;
134}
135
136Handle<Value> Converter<Handle<Object> >::ToV8(Isolate* isolate,
137                                               Handle<Object> val) {
138  return val.As<Value>();
139}
140
141bool Converter<Handle<Object> >::FromV8(Isolate* isolate, Handle<Value> val,
142                                        Handle<Object>* out) {
143  if (!val->IsObject())
144    return false;
145  *out = Handle<Object>::Cast(val);
146  return true;
147}
148
149Handle<Value> Converter<Handle<ArrayBuffer> >::ToV8(Isolate* isolate,
150                                                    Handle<ArrayBuffer> val) {
151  return val.As<Value>();
152}
153
154bool Converter<Handle<ArrayBuffer> >::FromV8(Isolate* isolate,
155                                             Handle<Value> val,
156                                             Handle<ArrayBuffer>* out) {
157  if (!val->IsArrayBuffer())
158    return false;
159  *out = Handle<ArrayBuffer>::Cast(val);
160  return true;
161}
162
163Handle<Value> Converter<Handle<External> >::ToV8(Isolate* isolate,
164                                                 Handle<External> val) {
165  return val.As<Value>();
166}
167
168bool Converter<Handle<External> >::FromV8(Isolate* isolate,
169                                          v8::Handle<Value> val,
170                                          Handle<External>* out) {
171  if (!val->IsExternal())
172    return false;
173  *out = Handle<External>::Cast(val);
174  return true;
175}
176
177Handle<Value> Converter<Handle<Value> >::ToV8(Isolate* isolate,
178                                              Handle<Value> val) {
179  return val;
180}
181
182bool Converter<Handle<Value> >::FromV8(Isolate* isolate, Handle<Value> val,
183                                       Handle<Value>* out) {
184  *out = val;
185  return true;
186}
187
188v8::Handle<v8::String> StringToSymbol(v8::Isolate* isolate,
189                                      const base::StringPiece& val) {
190  return String::NewFromUtf8(isolate,
191                             val.data(),
192                             String::kInternalizedString,
193                             static_cast<uint32_t>(val.length()));
194}
195
196std::string V8ToString(v8::Handle<v8::Value> value) {
197  if (value.IsEmpty())
198    return std::string();
199  std::string result;
200  if (!ConvertFromV8(NULL, value, &result))
201    return std::string();
202  return result;
203}
204
205}  // namespace gin
206