OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef SKY_ENGINE_TONIC_DART_CONVERTER_H_ | 5 #ifndef SKY_ENGINE_TONIC_DART_CONVERTER_H_ |
6 #define SKY_ENGINE_TONIC_DART_CONVERTER_H_ | 6 #define SKY_ENGINE_TONIC_DART_CONVERTER_H_ |
7 | 7 |
8 #include <string> | 8 #include <string> |
| 9 |
9 #include "tonic/dart_state.h" | 10 #include "tonic/dart_state.h" |
10 #include "tonic/dart_string.h" | |
11 #include "tonic/dart_string_cache.h" | |
12 #include "tonic/dart_value.h" | |
13 #include "sky/engine/wtf/text/StringUTF8Adaptor.h" | |
14 #include "sky/engine/wtf/text/WTFString.h" | |
15 | 11 |
16 namespace blink { | 12 namespace blink { |
17 | 13 |
18 // DartConvert converts types back and forth from Sky to Dart. The template | 14 // DartConvert converts types back and forth from Sky to Dart. The template |
19 // parameter |T| determines what kind of type conversion to perform. | 15 // parameter |T| determines what kind of type conversion to perform. |
20 template <typename T, typename Enable = void> | 16 template <typename T, typename Enable = void> |
21 struct DartConverter { | 17 struct DartConverter { |
22 }; | 18 }; |
23 | 19 |
24 // This is to work around the fact that typedefs do not create new types. If you | 20 // This is to work around the fact that typedefs do not create new types. If you |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 Dart_Handle enum_handle = Dart_GetNativeArgument(args, index); | 165 Dart_Handle enum_handle = Dart_GetNativeArgument(args, index); |
170 Dart_Handle index_handle = | 166 Dart_Handle index_handle = |
171 Dart_GetField(enum_handle, DartState::Current()->index_handle()); | 167 Dart_GetField(enum_handle, DartState::Current()->index_handle()); |
172 | 168 |
173 uint64_t enum_index = 0; | 169 uint64_t enum_index = 0; |
174 Dart_IntegerToUint64(index_handle, &enum_index); | 170 Dart_IntegerToUint64(index_handle, &enum_index); |
175 return static_cast<T>(enum_index); | 171 return static_cast<T>(enum_index); |
176 } | 172 } |
177 }; | 173 }; |
178 | 174 |
179 //////////////////////////////////////////////////////////////////////////////// | |
180 // Strings | |
181 | |
182 template <> | |
183 struct DartConverter<String> { | |
184 static Dart_Handle ToDart(DartState* state, const String& val) { | |
185 if (val.isEmpty()) | |
186 return Dart_EmptyString(); | |
187 return Dart_HandleFromWeakPersistent(state->string_cache().Get(val.impl())); | |
188 } | |
189 | |
190 static void SetReturnValue(Dart_NativeArguments args, | |
191 const String& val, | |
192 bool auto_scope = true) { | |
193 // TODO(abarth): What should we do with auto_scope? | |
194 if (val.isEmpty()) { | |
195 Dart_SetReturnValue(args, Dart_EmptyString()); | |
196 return; | |
197 } | |
198 DartState* state = DartState::Current(); | |
199 Dart_SetWeakHandleReturnValue(args, state->string_cache().Get(val.impl())); | |
200 } | |
201 | |
202 static void SetReturnValueWithNullCheck(Dart_NativeArguments args, | |
203 const String& val, | |
204 bool auto_scope = true) { | |
205 if (val.isNull()) | |
206 Dart_SetReturnValue(args, Dart_Null()); | |
207 else | |
208 SetReturnValue(args, val, auto_scope); | |
209 } | |
210 | |
211 static String FromDart(Dart_Handle handle) { | |
212 intptr_t char_size = 0; | |
213 intptr_t length = 0; | |
214 void* peer = nullptr; | |
215 Dart_Handle result = | |
216 Dart_StringGetProperties(handle, &char_size, &length, &peer); | |
217 if (peer) | |
218 return String(static_cast<StringImpl*>(peer)); | |
219 if (Dart_IsError(result)) | |
220 return String(); | |
221 return ExternalizeDartString(handle); | |
222 } | |
223 | |
224 static String FromArguments(Dart_NativeArguments args, | |
225 int index, | |
226 Dart_Handle& exception, | |
227 bool auto_scope = true) { | |
228 // TODO(abarth): What should we do with auto_scope? | |
229 void* peer = nullptr; | |
230 Dart_Handle handle = Dart_GetNativeStringArgument(args, index, &peer); | |
231 if (peer) | |
232 return reinterpret_cast<StringImpl*>(peer); | |
233 if (Dart_IsError(handle)) | |
234 return String(); | |
235 return ExternalizeDartString(handle); | |
236 } | |
237 | |
238 static String FromArgumentsWithNullCheck(Dart_NativeArguments args, | |
239 int index, | |
240 Dart_Handle& exception, | |
241 bool auto_scope = true) { | |
242 // TODO(abarth): What should we do with auto_scope? | |
243 void* peer = nullptr; | |
244 Dart_Handle handle = Dart_GetNativeStringArgument(args, index, &peer); | |
245 if (peer) | |
246 return reinterpret_cast<StringImpl*>(peer); | |
247 if (Dart_IsError(handle) || Dart_IsNull(handle)) | |
248 return String(); | |
249 return ExternalizeDartString(handle); | |
250 } | |
251 }; | |
252 | |
253 template <> | |
254 struct DartConverter<AtomicString> { | |
255 static Dart_Handle ToDart(DartState* state, const AtomicString& val) { | |
256 return DartConverter<String>::ToDart(state, val.string()); | |
257 } | |
258 }; | |
259 | |
260 //////////////////////////////////////////////////////////////////////////////// | |
261 // Collections | |
262 | |
263 template <typename T> | |
264 struct DartConverter<Vector<T>> { | |
265 using ValueType = typename DartConverterTypes<T>::ValueType; | |
266 using ConverterType = typename DartConverterTypes<T>::ConverterType; | |
267 | |
268 static Dart_Handle ToDart(const Vector<ValueType>& val) { | |
269 Dart_Handle list = Dart_NewList(val.size()); | |
270 if (Dart_IsError(list)) | |
271 return list; | |
272 for (size_t i = 0; i < val.size(); i++) { | |
273 Dart_Handle result = | |
274 Dart_ListSetAt(list, i, | |
275 DartConverter<ConverterType>::ToDart(val[i])); | |
276 if (Dart_IsError(result)) | |
277 return result; | |
278 } | |
279 return list; | |
280 } | |
281 | |
282 static Vector<ValueType> FromDart(Dart_Handle handle) { | |
283 Vector<ValueType> result; | |
284 if (!Dart_IsList(handle)) | |
285 return result; | |
286 intptr_t length = 0; | |
287 Dart_ListLength(handle, &length); | |
288 result.reserveCapacity(length); | |
289 for (intptr_t i = 0; i < length; ++i) { | |
290 Dart_Handle item = Dart_ListGetAt(handle, i); | |
291 DCHECK(!Dart_IsError(item)); | |
292 DCHECK(item); | |
293 result.append(DartConverter<ConverterType>::FromDart(item)); | |
294 } | |
295 return result; | |
296 } | |
297 | |
298 static Vector<ValueType> FromArguments(Dart_NativeArguments args, | |
299 int index, | |
300 Dart_Handle& exception, | |
301 bool auto_scope = true) { | |
302 // TODO(abarth): What should we do with auto_scope? | |
303 return FromDart(Dart_GetNativeArgument(args, index)); | |
304 } | |
305 }; | |
306 | |
307 //////////////////////////////////////////////////////////////////////////////// | |
308 // DartValue | |
309 | |
310 template <> | |
311 struct DartConverter<DartValue*> { | |
312 static Dart_Handle ToDart(DartState* state, DartValue* val) { | |
313 return val->dart_value(); | |
314 } | |
315 | |
316 static void SetReturnValue(Dart_NativeArguments args, DartValue* val) { | |
317 Dart_SetReturnValue(args, val->dart_value()); | |
318 } | |
319 | |
320 static PassRefPtr<DartValue> FromDart(Dart_Handle handle) { | |
321 return DartValue::Create(DartState::Current(), handle); | |
322 } | |
323 | |
324 static PassRefPtr<DartValue> FromArguments(Dart_NativeArguments args, | |
325 int index, | |
326 Dart_Handle& exception, | |
327 bool auto_scope = true) { | |
328 // TODO(abarth): What should we do with auto_scope? | |
329 return FromDart(Dart_GetNativeArgument(args, index)); | |
330 } | |
331 }; | |
332 | |
333 //////////////////////////////////////////////////////////////////////////////// | |
334 // Convience wrappers for commonly used conversions | |
335 | |
336 inline Dart_Handle StringToDart(DartState* state, const String& val) { | |
337 return DartConverter<String>::ToDart(state, val); | |
338 } | |
339 | |
340 inline Dart_Handle StringToDart(DartState* state, const AtomicString& val) { | |
341 return DartConverter<AtomicString>::ToDart(state, val); | |
342 } | |
343 | |
344 inline String StringFromDart(Dart_Handle handle) { | |
345 return DartConverter<String>::FromDart(handle); | |
346 } | |
347 | |
348 //////////////////////////////////////////////////////////////////////////////// | |
349 // Convience wrappers using type inference for ease of code generation | |
350 | |
351 template <typename T> | |
352 inline Dart_Handle VectorToDart(const Vector<T>& val) { | |
353 return DartConverter<Vector<T>>::ToDart(val); | |
354 } | |
355 | |
356 template<typename T> | |
357 Dart_Handle ToDart(const T& object) { | |
358 return DartConverter<T>::ToDart(object); | |
359 } | |
360 | 175 |
361 //////////////////////////////////////////////////////////////////////////////// | 176 //////////////////////////////////////////////////////////////////////////////// |
362 // std::string support (slower, but more convienent for some clients) | 177 // std::string support (slower, but more convienent for some clients) |
363 | 178 |
364 inline Dart_Handle StdStringToDart(const std::string& val) { | 179 inline Dart_Handle StdStringToDart(const std::string& val) { |
365 return Dart_NewStringFromUTF8(reinterpret_cast<const uint8_t*>(val.data()), | 180 return Dart_NewStringFromUTF8(reinterpret_cast<const uint8_t*>(val.data()), |
366 val.length()); | 181 val.length()); |
367 } | 182 } |
368 | 183 |
369 inline std::string StdStringFromDart(Dart_Handle handle) { | 184 inline std::string StdStringFromDart(Dart_Handle handle) { |
370 String string = StringFromDart(handle); | 185 uint8_t* data = nullptr; |
371 StringUTF8Adaptor utf8(string); | 186 intptr_t length = 0; |
372 return std::string(utf8.data(), utf8.length()); | 187 Dart_Handle r = Dart_StringToUTF8(handle, &data, &length); |
| 188 if (Dart_IsError(r)) { |
| 189 return std::string(); |
| 190 } |
| 191 return std::string(reinterpret_cast<const char*>(data), |
| 192 static_cast<size_t>(length)); |
373 } | 193 } |
374 | 194 |
375 | 195 |
376 // Alias Dart_NewStringFromCString for less typing. | 196 // Alias Dart_NewStringFromCString for less typing. |
377 inline Dart_Handle ToDart(const char* val) { | 197 inline Dart_Handle ToDart(const char* val) { |
378 return Dart_NewStringFromCString(val); | 198 return Dart_NewStringFromCString(val); |
379 } | 199 } |
380 | 200 |
381 } // namespace blink | 201 } // namespace blink |
382 | 202 |
383 #endif // SKY_ENGINE_TONIC_DART_CONVERTER_H_ | 203 #endif // SKY_ENGINE_TONIC_DART_CONVERTER_H_ |
OLD | NEW |