This patch combine three patch which is related to "--gcov" flag.
[platform/framework/web/chromium-efl.git] / gin / converter.h
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.
4
5 #ifndef GIN_CONVERTER_H_
6 #define GIN_CONVERTER_H_
7
8 #include <stdint.h>
9
10 #include <ostream>
11 #include <string>
12 #include <type_traits>
13 #include <vector>
14
15 #include "base/check.h"
16 #include "base/notreached.h"
17 #include "base/strings/string_piece.h"
18 #include "gin/gin_export.h"
19 #include "v8/include/v8-container.h"
20 #include "v8/include/v8-forward.h"
21 #include "v8/include/v8-isolate.h"
22
23 namespace base {
24 class TimeTicks;
25 }
26
27 namespace gin {
28
29 template<typename KeyType>
30 bool SetProperty(v8::Isolate* isolate,
31                  v8::Local<v8::Object> object,
32                  KeyType key,
33                  v8::Local<v8::Value> value) {
34   auto maybe =
35       object->DefineOwnProperty(isolate->GetCurrentContext(), key, value);
36   return !maybe.IsNothing() && maybe.FromJust();
37 }
38
39 template <typename T, typename Enable = void>
40 struct ToV8ReturnsMaybe {
41   static const bool value = false;
42 };
43
44 template<typename T, typename Enable = void>
45 struct Converter {};
46
47 template<>
48 struct GIN_EXPORT Converter<bool> {
49   static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
50                                     bool val);
51   static bool FromV8(v8::Isolate* isolate,
52                      v8::Local<v8::Value> val,
53                      bool* out);
54 };
55
56 template<>
57 struct GIN_EXPORT Converter<int32_t> {
58   static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
59                                     int32_t val);
60   static bool FromV8(v8::Isolate* isolate,
61                      v8::Local<v8::Value> val,
62                      int32_t* out);
63 };
64
65 template<>
66 struct GIN_EXPORT Converter<uint32_t> {
67   static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
68                                     uint32_t val);
69   static bool FromV8(v8::Isolate* isolate,
70                      v8::Local<v8::Value> val,
71                      uint32_t* out);
72 };
73
74 template<>
75 struct GIN_EXPORT Converter<int64_t> {
76   // Warning: JavaScript cannot represent 64 integers precisely.
77   static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
78                                     int64_t val);
79   static bool FromV8(v8::Isolate* isolate,
80                      v8::Local<v8::Value> val,
81                      int64_t* out);
82 };
83
84 template<>
85 struct GIN_EXPORT Converter<uint64_t> {
86   // Warning: JavaScript cannot represent 64 integers precisely.
87   static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
88                                     uint64_t val);
89   static bool FromV8(v8::Isolate* isolate,
90                      v8::Local<v8::Value> val,
91                      uint64_t* out);
92 };
93
94 template<>
95 struct GIN_EXPORT Converter<float> {
96   static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
97                                     float val);
98   static bool FromV8(v8::Isolate* isolate,
99                      v8::Local<v8::Value> val,
100                      float* out);
101 };
102
103 template<>
104 struct GIN_EXPORT Converter<double> {
105   static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
106                                     double val);
107   static bool FromV8(v8::Isolate* isolate,
108                      v8::Local<v8::Value> val,
109                      double* out);
110 };
111
112 template<>
113 struct GIN_EXPORT Converter<base::StringPiece> {
114   // This crashes when val.size() > v8::String::kMaxLength.
115   static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
116                                     const base::StringPiece& val);
117   // No conversion out is possible because StringPiece does not contain storage.
118 };
119
120 template<>
121 struct GIN_EXPORT Converter<std::string> {
122   // This crashes when val.size() > v8::String::kMaxLength.
123   static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
124                                     const std::string& val);
125   static bool FromV8(v8::Isolate* isolate,
126                      v8::Local<v8::Value> val,
127                      std::string* out);
128 };
129
130 template <>
131 struct GIN_EXPORT Converter<std::u16string> {
132   static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
133                                    const std::u16string& val);
134   static bool FromV8(v8::Isolate* isolate,
135                      v8::Local<v8::Value> val,
136                      std::u16string* out);
137 };
138
139 // Converter for C++ TimeTicks to Javascript BigInt (unit: microseconds).
140 // TimeTicks can't be converted using the existing Converter<int64_t> because
141 // the target type will be Number and will lose precision.
142 template <>
143 struct GIN_EXPORT Converter<base::TimeTicks> {
144   static v8::Local<v8::Value> ToV8(v8::Isolate* isolate, base::TimeTicks val);
145 };
146
147 template <>
148 struct GIN_EXPORT Converter<v8::Local<v8::Function>> {
149   static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
150                                    v8::Local<v8::Function> val);
151   static bool FromV8(v8::Isolate* isolate,
152                      v8::Local<v8::Value> val,
153                      v8::Local<v8::Function>* out);
154 };
155
156 template<>
157 struct GIN_EXPORT Converter<v8::Local<v8::Object> > {
158   static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
159                                     v8::Local<v8::Object> val);
160   static bool FromV8(v8::Isolate* isolate,
161                      v8::Local<v8::Value> val,
162                      v8::Local<v8::Object>* out);
163 };
164
165 template <>
166 struct GIN_EXPORT Converter<v8::Local<v8::Promise>> {
167   static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
168                                    v8::Local<v8::Promise> val);
169   static bool FromV8(v8::Isolate* isolate,
170                      v8::Local<v8::Value> val,
171                      v8::Local<v8::Promise>* out);
172 };
173
174 template<>
175 struct GIN_EXPORT Converter<v8::Local<v8::ArrayBuffer> > {
176   static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
177                                     v8::Local<v8::ArrayBuffer> val);
178   static bool FromV8(v8::Isolate* isolate,
179                      v8::Local<v8::Value> val,
180                      v8::Local<v8::ArrayBuffer>* out);
181 };
182
183 template<>
184 struct GIN_EXPORT Converter<v8::Local<v8::External> > {
185   static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
186                                     v8::Local<v8::External> val);
187   static bool FromV8(v8::Isolate* isolate,
188                      v8::Local<v8::Value> val,
189                      v8::Local<v8::External>* out);
190 };
191
192 template<>
193 struct GIN_EXPORT Converter<v8::Local<v8::Value> > {
194   static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
195                                     v8::Local<v8::Value> val);
196   static bool FromV8(v8::Isolate* isolate,
197                      v8::Local<v8::Value> val,
198                      v8::Local<v8::Value>* out);
199 };
200
201 template<typename T>
202 struct Converter<std::vector<T> > {
203   static std::conditional_t<ToV8ReturnsMaybe<T>::value,
204                             v8::MaybeLocal<v8::Value>,
205                             v8::Local<v8::Value>>
206   ToV8(v8::Isolate* isolate, const std::vector<T>& val) {
207     v8::Local<v8::Context> context = isolate->GetCurrentContext();
208     v8::Local<v8::Array> result(
209         v8::Array::New(isolate, static_cast<int>(val.size())));
210     for (uint32_t i = 0; i < val.size(); ++i) {
211       v8::MaybeLocal<v8::Value> maybe = Converter<T>::ToV8(isolate, val[i]);
212       v8::Local<v8::Value> element;
213       if (!maybe.ToLocal(&element))
214         return {};
215       bool property_created;
216       if (!result->CreateDataProperty(context, i, element)
217                .To(&property_created) ||
218           !property_created) {
219         NOTREACHED() << "CreateDataProperty should always succeed here.";
220       }
221     }
222     return result;
223   }
224
225   static bool FromV8(v8::Isolate* isolate,
226                      v8::Local<v8::Value> val,
227                      std::vector<T>* out) {
228     if (!val->IsArray())
229       return false;
230
231     std::vector<T> result;
232     v8::Local<v8::Array> array(v8::Local<v8::Array>::Cast(val));
233     uint32_t length = array->Length();
234     for (uint32_t i = 0; i < length; ++i) {
235       v8::Local<v8::Value> v8_item;
236       if (!array->Get(isolate->GetCurrentContext(), i).ToLocal(&v8_item))
237         return false;
238       T item;
239       if (!Converter<T>::FromV8(isolate, v8_item, &item))
240         return false;
241       result.push_back(item);
242     }
243
244     out->swap(result);
245     return true;
246   }
247 };
248
249 template <typename T>
250 struct Converter<v8::LocalVector<T>> {
251   static std::conditional_t<ToV8ReturnsMaybe<v8::Local<T>>::value,
252                             v8::MaybeLocal<v8::Value>,
253                             v8::Local<v8::Value>>
254   ToV8(v8::Isolate* isolate, const v8::LocalVector<T>& val) {
255     v8::Local<v8::Context> context = isolate->GetCurrentContext();
256     v8::Local<v8::Array> result(
257         v8::Array::New(isolate, static_cast<int>(val.size())));
258     for (uint32_t i = 0; i < val.size(); ++i) {
259       v8::MaybeLocal<v8::Value> maybe =
260           Converter<v8::Local<T>>::ToV8(isolate, val[i]);
261       v8::Local<v8::Value> element;
262       if (!maybe.ToLocal(&element)) {
263         return {};
264       }
265       bool property_created;
266       if (!result->CreateDataProperty(context, i, element)
267                .To(&property_created) ||
268           !property_created) {
269         NOTREACHED() << "CreateDataProperty should always succeed here.";
270       }
271     }
272     return result;
273   }
274
275   static bool FromV8(v8::Isolate* isolate,
276                      v8::Local<v8::Value> val,
277                      v8::LocalVector<T>* out) {
278     if (!val->IsArray()) {
279       return false;
280     }
281
282     v8::LocalVector<T> result(isolate);
283     v8::Local<v8::Array> array(v8::Local<v8::Array>::Cast(val));
284     uint32_t length = array->Length();
285     for (uint32_t i = 0; i < length; ++i) {
286       v8::Local<v8::Value> v8_item;
287       if (!array->Get(isolate->GetCurrentContext(), i).ToLocal(&v8_item)) {
288         return false;
289       }
290       v8::Local<T> item;
291       if (!Converter<v8::Local<T>>::FromV8(isolate, v8_item, &item)) {
292         return false;
293       }
294       result.push_back(item);
295     }
296
297     out->swap(result);
298     return true;
299   }
300 };
301
302 template<typename T>
303 struct ToV8ReturnsMaybe<std::vector<T>> {
304   static const bool value = ToV8ReturnsMaybe<T>::value;
305 };
306
307 template <typename T>
308 struct ToV8ReturnsMaybe<v8::LocalVector<T>> {
309   static const bool value = ToV8ReturnsMaybe<T>::value;
310 };
311
312 // Convenience functions that deduce T.
313 template <typename T>
314 std::conditional_t<ToV8ReturnsMaybe<T>::value,
315                    v8::MaybeLocal<v8::Value>,
316                    v8::Local<v8::Value>>
317 ConvertToV8(v8::Isolate* isolate, const T& input) {
318   return Converter<T>::ToV8(isolate, input);
319 }
320
321 template <typename T>
322 std::enable_if_t<ToV8ReturnsMaybe<T>::value, bool> TryConvertToV8(
323     v8::Isolate* isolate,
324     const T& input,
325     v8::Local<v8::Value>* output) {
326   return ConvertToV8(isolate, input).ToLocal(output);
327 }
328
329 template <typename T>
330 std::enable_if_t<!ToV8ReturnsMaybe<T>::value, bool> TryConvertToV8(
331     v8::Isolate* isolate,
332     const T& input,
333     v8::Local<v8::Value>* output) {
334   *output = ConvertToV8(isolate, input);
335   return true;
336 }
337
338 // This crashes when input.size() > v8::String::kMaxLength.
339 GIN_EXPORT inline v8::Local<v8::String> StringToV8(
340     v8::Isolate* isolate,
341     const base::StringPiece& input) {
342   return ConvertToV8(isolate, input).As<v8::String>();
343 }
344
345 // This crashes when input.size() > v8::String::kMaxLength.
346 GIN_EXPORT v8::Local<v8::String> StringToSymbol(v8::Isolate* isolate,
347                                                  const base::StringPiece& val);
348
349 // This crashes when input.size() > v8::String::kMaxLength.
350 GIN_EXPORT v8::Local<v8::String> StringToSymbol(v8::Isolate* isolate,
351                                                 const base::StringPiece16& val);
352
353 template<typename T>
354 bool ConvertFromV8(v8::Isolate* isolate, v8::Local<v8::Value> input,
355                    T* result) {
356   DCHECK(isolate);
357   return Converter<T>::FromV8(isolate, input, result);
358 }
359
360 GIN_EXPORT std::string V8ToString(v8::Isolate* isolate,
361                                   v8::Local<v8::Value> value);
362
363 }  // namespace gin
364
365 #endif  // GIN_CONVERTER_H_