converter.cc 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  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. #include "gin/converter.h"
  5. #include <stdint.h>
  6. #include "base/strings/string_util.h"
  7. #include "base/time/time.h"
  8. #include "v8/include/v8-array-buffer.h"
  9. #include "v8/include/v8-external.h"
  10. #include "v8/include/v8-function.h"
  11. #include "v8/include/v8-maybe.h"
  12. #include "v8/include/v8-object.h"
  13. #include "v8/include/v8-primitive.h"
  14. #include "v8/include/v8-promise.h"
  15. #include "v8/include/v8-value.h"
  16. using v8::ArrayBuffer;
  17. using v8::External;
  18. using v8::Function;
  19. using v8::Int32;
  20. using v8::Integer;
  21. using v8::Isolate;
  22. using v8::Local;
  23. using v8::Maybe;
  24. using v8::MaybeLocal;
  25. using v8::Number;
  26. using v8::Object;
  27. using v8::Promise;
  28. using v8::String;
  29. using v8::Uint32;
  30. using v8::Value;
  31. namespace {
  32. template <typename T, typename U>
  33. bool FromMaybe(Maybe<T> maybe, U* out) {
  34. if (maybe.IsNothing())
  35. return false;
  36. *out = static_cast<U>(maybe.FromJust());
  37. return true;
  38. }
  39. } // namespace
  40. namespace gin {
  41. Local<Value> Converter<bool>::ToV8(Isolate* isolate, bool val) {
  42. return v8::Boolean::New(isolate, val).As<Value>();
  43. }
  44. bool Converter<bool>::FromV8(Isolate* isolate, Local<Value> val, bool* out) {
  45. *out = val->BooleanValue(isolate);
  46. // BooleanValue cannot throw.
  47. return true;
  48. }
  49. Local<Value> Converter<int32_t>::ToV8(Isolate* isolate, int32_t val) {
  50. return Integer::New(isolate, val).As<Value>();
  51. }
  52. bool Converter<int32_t>::FromV8(Isolate* isolate,
  53. Local<Value> val,
  54. int32_t* out) {
  55. if (!val->IsInt32())
  56. return false;
  57. *out = val.As<Int32>()->Value();
  58. return true;
  59. }
  60. Local<Value> Converter<uint32_t>::ToV8(Isolate* isolate, uint32_t val) {
  61. return Integer::NewFromUnsigned(isolate, val).As<Value>();
  62. }
  63. bool Converter<uint32_t>::FromV8(Isolate* isolate,
  64. Local<Value> val,
  65. uint32_t* out) {
  66. if (!val->IsUint32())
  67. return false;
  68. *out = val.As<Uint32>()->Value();
  69. return true;
  70. }
  71. Local<Value> Converter<int64_t>::ToV8(Isolate* isolate, int64_t val) {
  72. return Number::New(isolate, static_cast<double>(val)).As<Value>();
  73. }
  74. bool Converter<int64_t>::FromV8(Isolate* isolate,
  75. Local<Value> val,
  76. int64_t* out) {
  77. if (!val->IsNumber())
  78. return false;
  79. // Even though IntegerValue returns int64_t, JavaScript cannot represent
  80. // the full precision of int64_t, which means some rounding might occur.
  81. return FromMaybe(val->IntegerValue(isolate->GetCurrentContext()), out);
  82. }
  83. Local<Value> Converter<uint64_t>::ToV8(Isolate* isolate, uint64_t val) {
  84. return Number::New(isolate, static_cast<double>(val)).As<Value>();
  85. }
  86. bool Converter<uint64_t>::FromV8(Isolate* isolate,
  87. Local<Value> val,
  88. uint64_t* out) {
  89. if (!val->IsNumber())
  90. return false;
  91. return FromMaybe(val->IntegerValue(isolate->GetCurrentContext()), out);
  92. }
  93. Local<Value> Converter<float>::ToV8(Isolate* isolate, float val) {
  94. return Number::New(isolate, val).As<Value>();
  95. }
  96. bool Converter<float>::FromV8(Isolate* isolate, Local<Value> val, float* out) {
  97. if (!val->IsNumber())
  98. return false;
  99. *out = static_cast<float>(val.As<Number>()->Value());
  100. return true;
  101. }
  102. Local<Value> Converter<double>::ToV8(Isolate* isolate, double val) {
  103. return Number::New(isolate, val).As<Value>();
  104. }
  105. bool Converter<double>::FromV8(Isolate* isolate,
  106. Local<Value> val,
  107. double* out) {
  108. if (!val->IsNumber())
  109. return false;
  110. *out = val.As<Number>()->Value();
  111. return true;
  112. }
  113. Local<Value> Converter<base::StringPiece>::ToV8(Isolate* isolate,
  114. const base::StringPiece& val) {
  115. return String::NewFromUtf8(isolate, val.data(),
  116. v8::NewStringType::kNormal,
  117. static_cast<uint32_t>(val.length()))
  118. .ToLocalChecked();
  119. }
  120. Local<Value> Converter<std::string>::ToV8(Isolate* isolate,
  121. const std::string& val) {
  122. return Converter<base::StringPiece>::ToV8(isolate, val);
  123. }
  124. bool Converter<std::string>::FromV8(Isolate* isolate,
  125. Local<Value> val,
  126. std::string* out) {
  127. if (!val->IsString())
  128. return false;
  129. Local<String> str = Local<String>::Cast(val);
  130. int length = str->Utf8Length(isolate);
  131. out->resize(length);
  132. str->WriteUtf8(isolate, &(*out)[0], length, NULL,
  133. String::NO_NULL_TERMINATION);
  134. return true;
  135. }
  136. Local<Value> Converter<std::u16string>::ToV8(Isolate* isolate,
  137. const std::u16string& val) {
  138. return String::NewFromTwoByte(isolate,
  139. reinterpret_cast<const uint16_t*>(val.data()),
  140. v8::NewStringType::kNormal, val.size())
  141. .ToLocalChecked();
  142. }
  143. bool Converter<std::u16string>::FromV8(Isolate* isolate,
  144. Local<Value> val,
  145. std::u16string* out) {
  146. if (!val->IsString())
  147. return false;
  148. Local<String> str = Local<String>::Cast(val);
  149. int length = str->Length();
  150. // Note that the reinterpret cast is because on Windows string16 is an alias
  151. // to wstring, and hence has character type wchar_t not uint16_t.
  152. str->Write(isolate,
  153. reinterpret_cast<uint16_t*>(base::WriteInto(out, length + 1)), 0,
  154. length);
  155. return true;
  156. }
  157. v8::Local<v8::Value> Converter<base::TimeTicks>::ToV8(v8::Isolate* isolate,
  158. base::TimeTicks val) {
  159. return v8::BigInt::New(isolate, val.since_origin().InMicroseconds())
  160. .As<v8::Value>();
  161. }
  162. Local<Value> Converter<Local<Function>>::ToV8(Isolate* isolate,
  163. Local<Function> val) {
  164. return val.As<Value>();
  165. }
  166. bool Converter<Local<Function>>::FromV8(Isolate* isolate,
  167. Local<Value> val,
  168. Local<Function>* out) {
  169. if (!val->IsFunction())
  170. return false;
  171. *out = Local<Function>::Cast(val);
  172. return true;
  173. }
  174. Local<Value> Converter<Local<Object>>::ToV8(Isolate* isolate,
  175. Local<Object> val) {
  176. return val.As<Value>();
  177. }
  178. bool Converter<Local<Object>>::FromV8(Isolate* isolate,
  179. Local<Value> val,
  180. Local<Object>* out) {
  181. if (!val->IsObject())
  182. return false;
  183. *out = Local<Object>::Cast(val);
  184. return true;
  185. }
  186. Local<Value> Converter<Local<Promise>>::ToV8(Isolate* isolate,
  187. Local<Promise> val) {
  188. return val.As<Value>();
  189. }
  190. bool Converter<Local<Promise>>::FromV8(Isolate* isolate,
  191. Local<Value> val,
  192. Local<Promise>* out) {
  193. if (!val->IsPromise())
  194. return false;
  195. *out = Local<Promise>::Cast(val);
  196. return true;
  197. }
  198. Local<Value> Converter<Local<ArrayBuffer>>::ToV8(Isolate* isolate,
  199. Local<ArrayBuffer> val) {
  200. return val.As<Value>();
  201. }
  202. bool Converter<Local<ArrayBuffer>>::FromV8(Isolate* isolate,
  203. Local<Value> val,
  204. Local<ArrayBuffer>* out) {
  205. if (!val->IsArrayBuffer())
  206. return false;
  207. *out = Local<ArrayBuffer>::Cast(val);
  208. return true;
  209. }
  210. Local<Value> Converter<Local<External>>::ToV8(Isolate* isolate,
  211. Local<External> val) {
  212. return val.As<Value>();
  213. }
  214. bool Converter<Local<External>>::FromV8(Isolate* isolate,
  215. v8::Local<Value> val,
  216. Local<External>* out) {
  217. if (!val->IsExternal())
  218. return false;
  219. *out = Local<External>::Cast(val);
  220. return true;
  221. }
  222. Local<Value> Converter<Local<Value>>::ToV8(Isolate* isolate, Local<Value> val) {
  223. return val;
  224. }
  225. bool Converter<Local<Value>>::FromV8(Isolate* isolate,
  226. Local<Value> val,
  227. Local<Value>* out) {
  228. *out = val;
  229. return true;
  230. }
  231. v8::Local<v8::String> StringToSymbol(v8::Isolate* isolate,
  232. const base::StringPiece& val) {
  233. return String::NewFromUtf8(isolate, val.data(),
  234. v8::NewStringType::kInternalized,
  235. static_cast<uint32_t>(val.length()))
  236. .ToLocalChecked();
  237. }
  238. v8::Local<v8::String> StringToSymbol(v8::Isolate* isolate,
  239. const base::StringPiece16& val) {
  240. return String::NewFromTwoByte(isolate,
  241. reinterpret_cast<const uint16_t*>(val.data()),
  242. v8::NewStringType::kInternalized, val.length())
  243. .ToLocalChecked();
  244. }
  245. std::string V8ToString(v8::Isolate* isolate, v8::Local<v8::Value> value) {
  246. if (value.IsEmpty())
  247. return std::string();
  248. std::string result;
  249. if (!ConvertFromV8(isolate, value, &result))
  250. return std::string();
  251. return result;
  252. }
  253. } // namespace gin