blob: dcb97433a93c6eaccaa01275b22933118aeed006 [file] [log] [blame]
John McCutchan040a7ed2015-07-21 06:55:34 -07001// Copyright 2015 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
John McCutchanc27a98c2015-07-21 11:25:24 -07005#ifndef TONIC_DART_CONVERTER_WTF_H_
6#define TONIC_DART_CONVERTER_WTF_H_
John McCutchan040a7ed2015-07-21 06:55:34 -07007
8#include <string>
9#include "sky/engine/wtf/text/StringUTF8Adaptor.h"
10#include "sky/engine/wtf/text/WTFString.h"
11#include "tonic/dart_converter.h"
12#include "tonic/dart_string.h"
13#include "tonic/dart_string_cache.h"
14#include "tonic/dart_value.h"
15
John McCutchandeace8f2015-07-21 08:01:40 -070016namespace tonic {
John McCutchan040a7ed2015-07-21 06:55:34 -070017
18////////////////////////////////////////////////////////////////////////////////
19// Strings
20
21template <>
22struct DartConverter<String> {
23 static Dart_Handle ToDart(DartState* state, const String& val) {
24 if (val.isEmpty())
25 return Dart_EmptyString();
26 return Dart_HandleFromWeakPersistent(state->string_cache().Get(val.impl()));
27 }
28
29 static void SetReturnValue(Dart_NativeArguments args,
30 const String& val,
31 bool auto_scope = true) {
32 // TODO(abarth): What should we do with auto_scope?
33 if (val.isEmpty()) {
34 Dart_SetReturnValue(args, Dart_EmptyString());
35 return;
36 }
37 DartState* state = DartState::Current();
38 Dart_SetWeakHandleReturnValue(args, state->string_cache().Get(val.impl()));
39 }
40
41 static void SetReturnValueWithNullCheck(Dart_NativeArguments args,
42 const String& val,
43 bool auto_scope = true) {
44 if (val.isNull())
45 Dart_SetReturnValue(args, Dart_Null());
46 else
47 SetReturnValue(args, val, auto_scope);
48 }
49
50 static String FromDart(Dart_Handle handle) {
51 intptr_t char_size = 0;
52 intptr_t length = 0;
53 void* peer = nullptr;
54 Dart_Handle result =
55 Dart_StringGetProperties(handle, &char_size, &length, &peer);
56 if (peer)
57 return String(static_cast<StringImpl*>(peer));
58 if (Dart_IsError(result))
59 return String();
60 return ExternalizeDartString(handle);
61 }
62
63 static String FromArguments(Dart_NativeArguments args,
64 int index,
65 Dart_Handle& exception,
66 bool auto_scope = true) {
67 // TODO(abarth): What should we do with auto_scope?
68 void* peer = nullptr;
69 Dart_Handle handle = Dart_GetNativeStringArgument(args, index, &peer);
70 if (peer)
71 return reinterpret_cast<StringImpl*>(peer);
72 if (Dart_IsError(handle))
73 return String();
74 return ExternalizeDartString(handle);
75 }
76
77 static String FromArgumentsWithNullCheck(Dart_NativeArguments args,
78 int index,
79 Dart_Handle& exception,
80 bool auto_scope = true) {
81 // TODO(abarth): What should we do with auto_scope?
82 void* peer = nullptr;
83 Dart_Handle handle = Dart_GetNativeStringArgument(args, index, &peer);
84 if (peer)
85 return reinterpret_cast<StringImpl*>(peer);
86 if (Dart_IsError(handle) || Dart_IsNull(handle))
87 return String();
88 return ExternalizeDartString(handle);
89 }
90};
91
92template <>
93struct DartConverter<AtomicString> {
94 static Dart_Handle ToDart(DartState* state, const AtomicString& val) {
95 return DartConverter<String>::ToDart(state, val.string());
96 }
97};
98
99////////////////////////////////////////////////////////////////////////////////
100// Collections
101
102template <typename T>
103struct DartConverter<Vector<T>> {
104 using ValueType = typename DartConverterTypes<T>::ValueType;
105 using ConverterType = typename DartConverterTypes<T>::ConverterType;
106
107 static Dart_Handle ToDart(const Vector<ValueType>& val) {
108 Dart_Handle list = Dart_NewList(val.size());
109 if (Dart_IsError(list))
110 return list;
111 for (size_t i = 0; i < val.size(); i++) {
112 Dart_Handle result =
113 Dart_ListSetAt(list, i,
114 DartConverter<ConverterType>::ToDart(val[i]));
115 if (Dart_IsError(result))
116 return result;
117 }
118 return list;
119 }
120
121 static Vector<ValueType> FromDart(Dart_Handle handle) {
122 Vector<ValueType> result;
123 if (!Dart_IsList(handle))
124 return result;
125 intptr_t length = 0;
126 Dart_ListLength(handle, &length);
127 result.reserveCapacity(length);
128 for (intptr_t i = 0; i < length; ++i) {
129 Dart_Handle item = Dart_ListGetAt(handle, i);
130 DCHECK(!Dart_IsError(item));
131 DCHECK(item);
132 result.append(DartConverter<ConverterType>::FromDart(item));
133 }
134 return result;
135 }
136
137 static Vector<ValueType> FromArguments(Dart_NativeArguments args,
138 int index,
139 Dart_Handle& exception,
140 bool auto_scope = true) {
141 // TODO(abarth): What should we do with auto_scope?
142 return FromDart(Dart_GetNativeArgument(args, index));
143 }
144};
145
146////////////////////////////////////////////////////////////////////////////////
147// DartValue
148
149template <>
150struct DartConverter<DartValue*> {
151 static Dart_Handle ToDart(DartState* state, DartValue* val) {
152 return val->dart_value();
153 }
154
155 static void SetReturnValue(Dart_NativeArguments args, DartValue* val) {
156 Dart_SetReturnValue(args, val->dart_value());
157 }
158
159 static PassRefPtr<DartValue> FromDart(Dart_Handle handle) {
160 return DartValue::Create(DartState::Current(), handle);
161 }
162
163 static PassRefPtr<DartValue> FromArguments(Dart_NativeArguments args,
164 int index,
165 Dart_Handle& exception,
166 bool auto_scope = true) {
167 // TODO(abarth): What should we do with auto_scope?
168 return FromDart(Dart_GetNativeArgument(args, index));
169 }
170};
171
172////////////////////////////////////////////////////////////////////////////////
173// Convience wrappers for commonly used conversions
174
175inline Dart_Handle StringToDart(DartState* state, const String& val) {
176 return DartConverter<String>::ToDart(state, val);
177}
178
179inline Dart_Handle StringToDart(DartState* state, const AtomicString& val) {
180 return DartConverter<AtomicString>::ToDart(state, val);
181}
182
183inline String StringFromDart(Dart_Handle handle) {
184 return DartConverter<String>::FromDart(handle);
185}
186
187////////////////////////////////////////////////////////////////////////////////
188// Convience wrappers using type inference for ease of code generation
189
190template <typename T>
191inline Dart_Handle VectorToDart(const Vector<T>& val) {
192 return DartConverter<Vector<T>>::ToDart(val);
193}
194
195template<typename T>
196Dart_Handle ToDart(const T& object) {
197 return DartConverter<T>::ToDart(object);
198}
199
200template<typename T>
201struct DartConverter<RefPtr<T>> {
202 static Dart_Handle ToDart(RefPtr<T> val) {
203 return DartConverter<T*>::ToDart(val.get());
204 }
205
206 static RefPtr<T> FromDart(Dart_Handle handle) {
207 return DartConverter<T*>::FromDart(handle);
208 }
209};
210
John McCutchanc27a98c2015-07-21 11:25:24 -0700211#endif // TONIC_DART_CONVERTER_WTF_H_