Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(451)

Side by Side Diff: mojo/public/cpp/bindings/lib/array_serialization.h

Issue 1358353002: * Change C++ serialization/deserialization to not be move-only operations (with the except of |Ha… (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_ 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_ 6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_
7 7
8 #include <string.h> // For |memcpy()|. 8 #include <string.h> // For |memcpy()|.
9
10 #include <vector> 9 #include <vector>
11 10
12 #include "mojo/public/c/system/macros.h" 11 #include "mojo/public/c/system/macros.h"
13 #include "mojo/public/cpp/bindings/lib/array_internal.h" 12 #include "mojo/public/cpp/bindings/lib/array_internal.h"
14 #include "mojo/public/cpp/bindings/lib/map_serialization.h" 13 #include "mojo/public/cpp/bindings/lib/bindings_internal.h"
14 #include "mojo/public/cpp/bindings/lib/iterator_util.h"
15 #include "mojo/public/cpp/bindings/lib/map_data_internal.h"
15 #include "mojo/public/cpp/bindings/lib/string_serialization.h" 16 #include "mojo/public/cpp/bindings/lib/string_serialization.h"
16 #include "mojo/public/cpp/bindings/lib/template_util.h" 17 #include "mojo/public/cpp/bindings/lib/template_util.h"
17 #include "mojo/public/cpp/bindings/lib/validation_errors.h" 18 #include "mojo/public/cpp/bindings/lib/validation_errors.h"
18 19
19 namespace mojo { 20 namespace mojo {
20 21
21 template <typename E> 22 template <typename E>
22 inline size_t GetSerializedSize_(const Array<E>& input); 23 inline size_t GetSerializedSize_(const Array<E>& input);
23 24
24 template <typename E, typename F> 25 template <typename E, typename F>
25 inline void SerializeArray_( 26 inline void SerializeArray_(
26 Array<E> input, 27 Array<E>* input,
27 internal::Buffer* buf, 28 internal::Buffer* buf,
28 internal::Array_Data<F>** output, 29 internal::Array_Data<F>** output,
29 const internal::ArrayValidateParams* validate_params); 30 const internal::ArrayValidateParams* validate_params);
30 31
31 template <typename E, typename F> 32 template <typename E, typename F>
32 inline void Deserialize_(internal::Array_Data<F>* data, Array<E>* output); 33 inline void Deserialize_(internal::Array_Data<F>* data, Array<E>* output);
33 34
35 // To avoid a circular dependency on map_serialization.h, we forward declare:
viettrungluu 2015/09/23 18:15:55 Maybe we should have a map_serialization_forward.h
vardhan 2015/09/23 22:07:00 I think SerializeMap_ should be internal (not avai
vardhan 2015/09/23 22:12:16 Sorry, I meant its a little ambigious*
viettrungluu 2015/09/23 23:20:24 Probably it should be moved to internal:: (without
vardhan 2015/09/25 19:33:05 Another thought is that I would have to leave Dese
viettrungluu 2015/09/25 20:08:08 OK
36 template <typename Key, typename Value>
37 class Map;
38
39 template <typename MapKey,
40 typename MapValue,
41 typename DataKey,
42 typename DataValue>
43 void SerializeMap_(Map<MapKey, MapValue>* input,
44 internal::Buffer* buf,
45 internal::Map_Data<DataKey, DataValue>** output,
46 const internal::ArrayValidateParams* value_validate_params);
47 template <typename MapKey, typename MapValue>
48 size_t GetSerializedSize_(const Map<MapKey, MapValue>& input);
49
50 template <typename MapKey,
51 typename MapValue,
52 typename DataKey,
53 typename DataValue>
54 void Deserialize_(internal::Map_Data<DataKey, DataValue>* input,
55 Map<MapKey, MapValue>* output);
56
34 namespace internal { 57 namespace internal {
35 58
59 // ArraySerializer template contains static methods for serializing |Array|s of
viettrungluu 2015/09/23 18:15:55 *The* ArraySerializer template ...
vardhan 2015/09/23 22:07:00 Done.
60 // various types. These methods include:
61 // * size_t GetSerializedSize(..)
62 // Computes the size of the serialized version of the |Array|.
63 // * void SerializeElementsWithIterator(..)
64 // Takes an iterator and |num_elements| representing an |Array| (or
65 // possibly a |Map|), and serializes it.
66 // * void SerializeElements(..)
67 // Takes an |Array| directly and serializes it. This usually calls into
68 // SerializeElementsWithIterator(), except for an |Array| of PODs which
69 // will directly memcpy the PODs as an optimization.
36 template <typename E, 70 template <typename E,
37 typename F, 71 typename F,
38 bool is_union = 72 bool is_union =
39 IsUnionDataType<typename RemovePointer<F>::type>::value> 73 IsUnionDataType<typename RemovePointer<F>::type>::value>
40 struct ArraySerializer; 74 struct ArraySerializer;
41 75
42 // Handles serialization and deserialization of arrays of pod types. 76 // Handles serialization and deserialization of arrays of pod types.
43 template <typename E, typename F> 77 template <typename E, typename F>
44 struct ArraySerializer<E, F, false> { 78 struct ArraySerializer<E, F, false> {
45 static_assert(sizeof(E) == sizeof(F), "Incorrect array serializer"); 79 static_assert(sizeof(E) == sizeof(F), "Incorrect array serializer");
46 static size_t GetSerializedSize(const Array<E>& input) { 80 static size_t GetSerializedSize(const Array<E>& input) {
47 return sizeof(Array_Data<F>) + Align(input.size() * sizeof(E)); 81 return sizeof(Array_Data<F>) + Align(input.size() * sizeof(E));
48 } 82 }
49 83
50 static void SerializeElements(Array<E> input, 84 template <typename Iterator>
85 static void SerializeElementsWithIterator(
86 Iterator it,
87 size_t num_elements,
88 Buffer* buf,
89 Array_Data<F>* output,
90 const ArrayValidateParams* validate_params) {
91 MOJO_DCHECK(!validate_params->element_is_nullable)
92 << "Primitive type should be non-nullable";
93 MOJO_DCHECK(!validate_params->element_validate_params)
94 << "Primitive type should not have array validate params";
95 if (num_elements) {
96 for (size_t i = 0; i < num_elements; ++i, ++it) {
97 output->at(i) = *it;
98 }
99 }
100 }
101
102 // We can optimize serializing PODs by |memcpy|ing directly.
103 static void SerializeElements(Array<E>* input,
51 Buffer* buf, 104 Buffer* buf,
52 Array_Data<F>* output, 105 Array_Data<F>* output,
53 const ArrayValidateParams* validate_params) { 106 const ArrayValidateParams* validate_params) {
54 MOJO_DCHECK(!validate_params->element_is_nullable) 107 MOJO_DCHECK(!validate_params->element_is_nullable)
55 << "Primitive type should be non-nullable"; 108 << "Primitive type should be non-nullable";
56 MOJO_DCHECK(!validate_params->element_validate_params) 109 MOJO_DCHECK(!validate_params->element_validate_params)
57 << "Primitive type should not have array validate params"; 110 << "Primitive type should not have array validate params";
111 if (input->size()) {
112 memcpy(output->storage(), &input->storage()[0],
113 input->size() * sizeof(E));
114 }
115 }
58 116
59 if (input.size())
60 memcpy(output->storage(), &input.storage()[0], input.size() * sizeof(E));
61 }
62 static void DeserializeElements(Array_Data<F>* input, Array<E>* output) { 117 static void DeserializeElements(Array_Data<F>* input, Array<E>* output) {
63 std::vector<E> result(input->size()); 118 std::vector<E> result(input->size());
64 if (input->size()) 119 if (input->size())
65 memcpy(&result[0], input->storage(), input->size() * sizeof(E)); 120 memcpy(&result[0], input->storage(), input->size() * sizeof(E));
66 output->Swap(&result); 121 output->Swap(&result);
67 } 122 }
68 }; 123 };
69 124
70 // Serializes and deserializes arrays of bools. 125 // Serializes and deserializes arrays of bools.
71 template <> 126 template <>
72 struct ArraySerializer<bool, bool, false> { 127 struct ArraySerializer<bool, bool, false> {
73 static size_t GetSerializedSize(const Array<bool>& input) { 128 static size_t GetSerializedSize(const Array<bool>& input) {
74 return sizeof(Array_Data<bool>) + Align((input.size() + 7) / 8); 129 return sizeof(Array_Data<bool>) + Align((input.size() + 7) / 8);
75 } 130 }
76 131
77 static void SerializeElements(Array<bool> input, 132 template <typename Iterator>
78 Buffer* buf, 133 static void SerializeElementsWithIterator(
79 Array_Data<bool>* output, 134 Iterator it,
80 const ArrayValidateParams* validate_params) { 135 size_t num_elements,
136 Buffer* buf,
137 Array_Data<bool>* output,
138 const ArrayValidateParams* validate_params) {
81 MOJO_DCHECK(!validate_params->element_is_nullable) 139 MOJO_DCHECK(!validate_params->element_is_nullable)
82 << "Primitive type should be non-nullable"; 140 << "Primitive type should be non-nullable";
83 MOJO_DCHECK(!validate_params->element_validate_params) 141 MOJO_DCHECK(!validate_params->element_validate_params)
84 << "Primitive type should not have array validate params"; 142 << "Primitive type should not have array validate params";
85 143
86 // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy? 144 // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy?
87 for (size_t i = 0; i < input.size(); ++i) 145 for (size_t i = 0; i < num_elements; ++i, ++it) {
88 output->at(i) = input[i]; 146 output->at(i) = *it;
147 }
89 } 148 }
149
150 static void SerializeElements(Array<bool>* input,
151 Buffer* buf,
152 Array_Data<bool>* output,
153 const ArrayValidateParams* validate_params) {
154 SerializeElementsWithIterator(input->begin(), input->size(), buf, output,
155 validate_params);
156 }
157
90 static void DeserializeElements(Array_Data<bool>* input, 158 static void DeserializeElements(Array_Data<bool>* input,
91 Array<bool>* output) { 159 Array<bool>* output) {
92 Array<bool> result(input->size()); 160 Array<bool> result(input->size());
93 // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy? 161 // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy?
94 for (size_t i = 0; i < input->size(); ++i) 162 for (size_t i = 0; i < input->size(); ++i)
95 result.at(i) = input->at(i); 163 result.at(i) = input->at(i);
96 output->Swap(&result); 164 output->Swap(&result);
97 } 165 }
98 }; 166 };
99 167
100 // Serializes and deserializes arrays of handles. 168 // Serializes and deserializes arrays of handles.
101 template <typename H> 169 template <typename H>
102 struct ArraySerializer<ScopedHandleBase<H>, H, false> { 170 struct ArraySerializer<ScopedHandleBase<H>, H, false> {
103 static size_t GetSerializedSize(const Array<ScopedHandleBase<H>>& input) { 171 static size_t GetSerializedSize(const Array<ScopedHandleBase<H>>& input) {
104 return sizeof(Array_Data<H>) + Align(input.size() * sizeof(H)); 172 return sizeof(Array_Data<H>) + Align(input.size() * sizeof(H));
105 } 173 }
106 174
107 static void SerializeElements(Array<ScopedHandleBase<H>> input, 175 template <typename Iterator>
108 Buffer* buf, 176 static void SerializeElementsWithIterator(
109 Array_Data<H>* output, 177 Iterator it,
110 const ArrayValidateParams* validate_params) { 178 size_t num_elements,
179 Buffer* buf,
180 Array_Data<H>* output,
181 const ArrayValidateParams* validate_params) {
111 MOJO_DCHECK(!validate_params->element_validate_params) 182 MOJO_DCHECK(!validate_params->element_validate_params)
112 << "Handle type should not have array validate params"; 183 << "Handle type should not have array validate params";
113 184
114 for (size_t i = 0; i < input.size(); ++i) { 185 for (size_t i = 0; i < num_elements; ++i, ++it) {
115 output->at(i) = input[i].release(); // Transfer ownership of the handle. 186 // Transfer ownership of the handle.
187 output->at(i) = (*it).release();
116 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( 188 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
117 !validate_params->element_is_nullable && !output->at(i).is_valid(), 189 !validate_params->element_is_nullable && !output->at(i).is_valid(),
118 VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE, 190 VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
119 MakeMessageWithArrayIndex( 191 MakeMessageWithArrayIndex(
120 "invalid handle in array expecting valid handles", input.size(), 192 "invalid handle in array expecting valid handles", num_elements,
121 i)); 193 i));
122 } 194 }
123 } 195 }
196
197 static void SerializeElements(Array<ScopedHandleBase<H>>* input,
viettrungluu 2015/09/23 18:15:55 Do you really need this? (Not having it would also
vardhan 2015/09/23 22:06:59 The only reason we have both SerializeElements and
viettrungluu 2015/09/23 23:20:24 Is it possible to do this via some appropriate spe
vardhan 2015/09/25 19:33:05 Done :(
198 Buffer* buf,
199 Array_Data<H>* output,
200 const ArrayValidateParams* validate_params) {
201 SerializeElementsWithIterator(input->begin(), input->size(), buf, output,
202 validate_params);
203 }
204
124 static void DeserializeElements(Array_Data<H>* input, 205 static void DeserializeElements(Array_Data<H>* input,
125 Array<ScopedHandleBase<H>>* output) { 206 Array<ScopedHandleBase<H>>* output) {
126 Array<ScopedHandleBase<H>> result(input->size()); 207 Array<ScopedHandleBase<H>> result(input->size());
127 for (size_t i = 0; i < input->size(); ++i) 208 for (size_t i = 0; i < input->size(); ++i)
128 result.at(i) = MakeScopedHandle(FetchAndReset(&input->at(i))); 209 result.at(i) = MakeScopedHandle(FetchAndReset(&input->at(i)));
129 output->Swap(&result); 210 output->Swap(&result);
130 } 211 }
131 }; 212 };
132 213
133 // This template must only apply to pointer mojo entity (structs and arrays). 214 // SerializeCaller template is used by |ArraySerializer| to dispatch a serialize
134 // This is done by ensuring that WrapperTraits<S>::DataType is a pointer. 215 // call on a non-POD type. This template is defined outside |ArraySerializer|
216 // since you cannot specialize a struct within a class definition.
viettrungluu 2015/09/23 18:15:55 Are you allowed to specialize static member functi
vardhan 2015/09/23 22:06:59 Yeah, but explicitly specialized definitions of a
viettrungluu 2015/09/23 23:20:24 Well, the definition would be declared outside, bu
vardhan 2015/09/25 19:33:05 Done.
217 template <typename T>
218 struct SerializeCaller {
219 static void Run(T* input,
220 Buffer* buf,
221 typename WrapperTraits<T>::DataType* output,
222 const ArrayValidateParams* validate_params) {
223 MOJO_DCHECK(!validate_params)
224 << "Struct type should not have array validate params";
225 Serialize_(UnwrapStructPtr<T>::value(*input), buf, output);
226 }
227 };
228
229 template <>
230 struct SerializeCaller<String> {
231 static void Run(const String* input,
232 Buffer* buf,
233 String_Data** output,
234 const ArrayValidateParams* validate_params) {
235 MOJO_DCHECK(validate_params && !validate_params->element_validate_params &&
236 !validate_params->element_is_nullable &&
237 validate_params->expected_num_elements == 0)
238 << "String type has unexpected array validate params";
239 SerializeString_(*input, buf, output);
240 }
241 };
242
243 template <typename T>
244 struct SerializeCaller<Array<T>> {
245 static void Run(Array<T>* input,
246 Buffer* buf,
247 typename Array<T>::Data_** output,
248 const ArrayValidateParams* validate_params) {
249 SerializeArray_(input, buf, output, validate_params);
250 }
251 };
252
253 template <typename Key, typename Value>
254 struct SerializeCaller<Map<Key, Value>> {
255 static void Run(Map<Key, Value>* input,
256 Buffer* buf,
257 typename Map<Key, Value>::Data_** output,
258 const ArrayValidateParams* validate_params) {
259 SerializeMap_(input, buf, output, validate_params);
260 }
261 };
262
263 template <typename T,
264 bool IsStructPtr = IsSpecializationOf<StructPtr, T>::value ||
265 IsSpecializationOf<InlinedStructPtr, T>::value>
266 struct DeserializeCaller;
267
268 template <typename T>
269 struct DeserializeCaller<T, false> {
270 static void Run(typename WrapperTraits<T>::DataType input, T* output) {
271 Deserialize_(input, output);
272 }
273 };
274
275 template <typename T>
276 struct DeserializeCaller<T, true> {
277 static void Run(typename WrapperTraits<T>::DataType input, T* output) {
278 // Since Deserialize_ takes in a |Struct*| (not |StructPtr|), we need to
279 // initialize the |StructPtr| here before deserializing into its underlying
280 // data.
281 // TODO(vardhan): Either all containers, or just Deserialize_(), should
282 // support taking in an allocator.
283 using UnwrapedStructType = typename RemoveStructPtr<T>::type;
284 *output = UnwrapedStructType::New();
285 Deserialize_(input, output->get());
286 }
287 };
288
289 // This template must only apply to pointer mojo entity (structs, arrays,
290 // strings). This is done by ensuring that WrapperTraits<S>::DataType is a
291 // pointer.
135 template <typename S> 292 template <typename S>
136 struct ArraySerializer< 293 struct ArraySerializer<
137 S, 294 S,
138 typename EnableIf<IsPointer<typename WrapperTraits<S>::DataType>::value, 295 typename EnableIf<IsPointer<typename WrapperTraits<S>::DataType>::value,
139 typename WrapperTraits<S>::DataType>::type, 296 typename WrapperTraits<S>::DataType>::type,
140 false> { 297 false> {
141 typedef 298 typedef
142 typename RemovePointer<typename WrapperTraits<S>::DataType>::type S_Data; 299 typename RemovePointer<typename WrapperTraits<S>::DataType>::type S_Data;
143 static size_t GetSerializedSize(const Array<S>& input) { 300 static size_t GetSerializedSize(const Array<S>& input) {
144 size_t size = sizeof(Array_Data<S_Data*>) + 301 size_t size = sizeof(Array_Data<S_Data*>) +
145 input.size() * sizeof(StructPointer<S_Data>); 302 input.size() * sizeof(StructPointer<S_Data>);
146 for (size_t i = 0; i < input.size(); ++i) 303 for (size_t i = 0; i < input.size(); ++i)
147 size += GetSerializedSize_(input[i]); 304 size += GetSerializedSize_(*(UnwrapConstStructPtr<S>::value(input[i])));
148 return size; 305 return size;
149 } 306 }
150 307
151 static void SerializeElements(Array<S> input, 308 template <typename Iterator>
152 Buffer* buf, 309 static void SerializeElementsWithIterator(
153 Array_Data<S_Data*>* output, 310 Iterator it,
154 const ArrayValidateParams* validate_params) { 311 size_t num_elements,
155 for (size_t i = 0; i < input.size(); ++i) { 312 Buffer* buf,
313 Array_Data<S_Data*>* output,
314 const ArrayValidateParams* validate_params) {
315 for (size_t i = 0; i < num_elements; ++i, ++it) {
156 S_Data* element; 316 S_Data* element;
157 SerializeCaller<S>::Run(input[i].Pass(), buf, &element, 317 SerializeCaller<S>::Run(&(*it), buf, &element,
158 validate_params->element_validate_params); 318 validate_params->element_validate_params);
159 output->at(i) = element; 319 output->at(i) = element;
160 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( 320 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
161 !validate_params->element_is_nullable && !element, 321 !validate_params->element_is_nullable && !element,
162 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, 322 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
163 MakeMessageWithArrayIndex("null in array expecting valid pointers", 323 MakeMessageWithArrayIndex("null in array expecting valid pointers",
164 input.size(), i)); 324 num_elements, i));
165 } 325 }
166 } 326 }
327
328 static void SerializeElements(Array<S>* input,
329 Buffer* buf,
330 Array_Data<S_Data*>* output,
331 const ArrayValidateParams* validate_params) {
332 SerializeElementsWithIterator(input->begin(), input->size(), buf, output,
333 validate_params);
334 }
335
167 static void DeserializeElements(Array_Data<S_Data*>* input, 336 static void DeserializeElements(Array_Data<S_Data*>* input,
168 Array<S>* output) { 337 Array<S>* output) {
169 Array<S> result(input->size()); 338 Array<S> result(input->size());
170 for (size_t i = 0; i < input->size(); ++i) { 339 for (size_t i = 0; i < input->size(); ++i) {
171 Deserialize_(input->at(i), &result[i]); 340 DeserializeCaller<S>::Run(input->at(i), &result[i]);
172 } 341 }
173 output->Swap(&result); 342 output->Swap(&result);
174 } 343 }
175
176 private:
177 template <typename T>
178 struct SerializeCaller {
179 static void Run(T input,
180 Buffer* buf,
181 typename WrapperTraits<T>::DataType* output,
182 const ArrayValidateParams* validate_params) {
183 MOJO_DCHECK(!validate_params)
184 << "Struct type should not have array validate params";
185
186 Serialize_(input.Pass(), buf, output);
187 }
188 };
189
190 template <typename T>
191 struct SerializeCaller<Array<T>> {
192 static void Run(Array<T> input,
193 Buffer* buf,
194 typename Array<T>::Data_** output,
195 const ArrayValidateParams* validate_params) {
196 SerializeArray_(input.Pass(), buf, output, validate_params);
197 }
198 };
199
200 template <typename T, typename U>
201 struct SerializeCaller<Map<T, U>> {
202 static void Run(Map<T, U> input,
203 Buffer* buf,
204 typename Map<T, U>::Data_** output,
205 const ArrayValidateParams* validate_params) {
206 SerializeMap_(input.Pass(), buf, output, validate_params);
207 }
208 };
209 }; 344 };
210 345
211 // Handles serialization and deserialization of arrays of unions. 346 // Handles serialization and deserialization of arrays of unions.
212 template <typename U, typename U_Data> 347 template <typename U, typename U_Data>
213 struct ArraySerializer<U, U_Data, true> { 348 struct ArraySerializer<U, U_Data, true> {
214 static size_t GetSerializedSize(const Array<U>& input) { 349 static size_t GetSerializedSize(const Array<U>& input) {
215 size_t size = sizeof(Array_Data<U_Data>); 350 size_t size = sizeof(Array_Data<U_Data>);
216 for (size_t i = 0; i < input.size(); ++i) { 351 for (size_t i = 0; i < input.size(); ++i) {
217 // GetSerializedSize_ will account for both the data in the union and the 352 // GetSerializedSize_ will account for both the data in the union and the
218 // space in the array used to hold the union. 353 // space in the array used to hold the union.
219 size += GetSerializedSize_(input[i], false); 354 size += GetSerializedSize_(input[i], false);
220 } 355 }
221 return size; 356 return size;
222 } 357 }
223 358
224 static void SerializeElements(Array<U> input, 359 template <typename Iterator>
225 Buffer* buf, 360 static void SerializeElementsWithIterator(
226 Array_Data<U_Data>* output, 361 Iterator it,
227 const ArrayValidateParams* validate_params) { 362 size_t num_elements,
228 for (size_t i = 0; i < input.size(); ++i) { 363 Buffer* buf,
364 Array_Data<U_Data>* output,
365 const ArrayValidateParams* validate_params) {
366 for (size_t i = 0; i < num_elements; ++i, ++it) {
229 U_Data* result = output->storage() + i; 367 U_Data* result = output->storage() + i;
230 SerializeUnion_(input[i].Pass(), buf, &result, true); 368 SerializeUnion_((*it).get(), buf, &result, true);
231 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( 369 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
232 !validate_params->element_is_nullable && output->at(i).is_null(), 370 !validate_params->element_is_nullable && output->at(i).is_null(),
233 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, 371 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
234 MakeMessageWithArrayIndex("null in array expecting valid unions", 372 MakeMessageWithArrayIndex("null in array expecting valid unions",
235 input.size(), i)); 373 num_elements, i));
236 } 374 }
237 } 375 }
238 376
377 static void SerializeElements(Array<U>* input,
378 Buffer* buf,
379 Array_Data<U_Data>* output,
380 const ArrayValidateParams* validate_params) {
381 SerializeElementsWithIterator(input->begin(), input->size(), buf, output,
382 validate_params);
383 }
384
239 static void DeserializeElements(Array_Data<U_Data>* input, Array<U>* output) { 385 static void DeserializeElements(Array_Data<U_Data>* input, Array<U>* output) {
240 Array<U> result(input->size()); 386 Array<U> result(input->size());
241 for (size_t i = 0; i < input->size(); ++i) { 387 for (size_t i = 0; i < input->size(); ++i) {
242 Deserialize_(&input->at(i), &result[i]); 388 auto& elem = input->at(i);
389 if (!elem.is_null()) {
390 using UnwrapedUnionType = typename RemoveStructPtr<U>::type;
391 result[i] = UnwrapedUnionType::New();
392 Deserialize_(&elem, result[i].get());
393 }
243 } 394 }
244 output->Swap(&result); 395 output->Swap(&result);
245 } 396 }
246 }; 397 };
247
248 // Handles serialization and deserialization of arrays of strings.
249 template <>
250 struct ArraySerializer<String, String_Data*> {
251 static size_t GetSerializedSize(const Array<String>& input) {
252 size_t size =
253 sizeof(Array_Data<String_Data*>) + input.size() * sizeof(StringPointer);
254 for (size_t i = 0; i < input.size(); ++i)
255 size += GetSerializedSize_(input[i]);
256 return size;
257 }
258
259 static void SerializeElements(Array<String> input,
260 Buffer* buf,
261 Array_Data<String_Data*>* output,
262 const ArrayValidateParams* validate_params) {
263 MOJO_DCHECK(
264 validate_params->element_validate_params &&
265 !validate_params->element_validate_params->element_validate_params &&
266 !validate_params->element_validate_params->element_is_nullable &&
267 validate_params->element_validate_params->expected_num_elements == 0)
268 << "String type has unexpected array validate params";
269
270 for (size_t i = 0; i < input.size(); ++i) {
271 String_Data* element;
272 Serialize_(input[i], buf, &element);
273 output->at(i) = element;
274 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
275 !validate_params->element_is_nullable && !element,
276 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
277 MakeMessageWithArrayIndex("null in array expecting valid strings",
278 input.size(), i));
279 }
280 }
281 static void DeserializeElements(Array_Data<String_Data*>* input,
282 Array<String>* output) {
283 Array<String> result(input->size());
284 for (size_t i = 0; i < input->size(); ++i)
285 Deserialize_(input->at(i), &result[i]);
286 output->Swap(&result);
287 }
288 };
289 398
290 } // namespace internal 399 } // namespace internal
291 400
292 template <typename E> 401 template <typename E>
293 inline size_t GetSerializedSize_(const Array<E>& input) { 402 inline size_t GetSerializedSize_(const Array<E>& input) {
294 if (!input) 403 if (!input)
295 return 0; 404 return 0;
296 typedef typename internal::WrapperTraits<E>::DataType F; 405 typedef typename internal::WrapperTraits<E>::DataType F;
297 return internal::ArraySerializer<E, F>::GetSerializedSize(input); 406 return internal::ArraySerializer<E, F>::GetSerializedSize(input);
298 } 407 }
299 408
300 template <typename E, typename F> 409 template <typename E, typename F>
301 inline void SerializeArray_( 410 inline void SerializeArray_(
302 Array<E> input, 411 Array<E>* input,
303 internal::Buffer* buf, 412 internal::Buffer* buf,
304 internal::Array_Data<F>** output, 413 internal::Array_Data<F>** output,
305 const internal::ArrayValidateParams* validate_params) { 414 const internal::ArrayValidateParams* validate_params) {
306 if (input) { 415 if (input && *input) {
307 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( 416 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
308 validate_params->expected_num_elements != 0 && 417 validate_params->expected_num_elements != 0 &&
309 input.size() != validate_params->expected_num_elements, 418 input->size() != validate_params->expected_num_elements,
310 internal::VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER, 419 internal::VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER,
311 internal::MakeMessageWithExpectedArraySize( 420 internal::MakeMessageWithExpectedArraySize(
312 "fixed-size array has wrong number of elements", input.size(), 421 "fixed-size array has wrong number of elements", input->size(),
313 validate_params->expected_num_elements)); 422 validate_params->expected_num_elements));
314 423
315 internal::Array_Data<F>* result = 424 internal::Array_Data<F>* result =
316 internal::Array_Data<F>::New(input.size(), buf); 425 internal::Array_Data<F>::New(input->size(), buf);
317 if (result) { 426 if (result) {
318 internal::ArraySerializer<E, F>::SerializeElements( 427 internal::ArraySerializer<E, F>::SerializeElements(input, buf, result,
319 internal::Forward(input), buf, result, validate_params); 428 validate_params);
320 } 429 }
321 *output = result; 430 *output = result;
322 } else { 431 } else {
323 *output = nullptr; 432 *output = nullptr;
324 } 433 }
325 } 434 }
326 435
327 template <typename E, typename F> 436 template <typename E, typename F>
328 inline void Deserialize_(internal::Array_Data<F>* input, Array<E>* output) { 437 inline void Deserialize_(internal::Array_Data<F>* input, Array<E>* output) {
329 if (input) { 438 if (input) {
330 internal::ArraySerializer<E, F>::DeserializeElements(input, output); 439 internal::ArraySerializer<E, F>::DeserializeElements(input, output);
331 } else { 440 } else {
332 output->reset(); 441 output->reset();
333 } 442 }
334 } 443 }
335 444
336 } // namespace mojo 445 } // namespace mojo
337 446
338 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_ 447 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698