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

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: Cleanup forward declarations of array/map serialization functions Created 5 years, 3 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"
16 #include "mojo/public/cpp/bindings/lib/map_serialization_forward.h"
15 #include "mojo/public/cpp/bindings/lib/string_serialization.h" 17 #include "mojo/public/cpp/bindings/lib/string_serialization.h"
16 #include "mojo/public/cpp/bindings/lib/template_util.h" 18 #include "mojo/public/cpp/bindings/lib/template_util.h"
17 #include "mojo/public/cpp/bindings/lib/validation_errors.h" 19 #include "mojo/public/cpp/bindings/lib/validation_errors.h"
18 20
19 namespace mojo { 21 namespace mojo {
20
21 template <typename E>
22 inline size_t GetSerializedSize_(const Array<E>& input);
23
24 template <typename E, typename F>
25 inline void SerializeArray_(
26 Array<E> input,
27 internal::Buffer* buf,
28 internal::Array_Data<F>** output,
29 const internal::ArrayValidateParams* validate_params);
30
31 template <typename E, typename F>
32 inline void Deserialize_(internal::Array_Data<F>* data, Array<E>* output);
33
34 namespace internal { 22 namespace internal {
35 23
24 // The ArraySerializer template contains static methods for serializing |Array|s
25 // of various types. These methods include:
26 // * size_t GetSerializedSize(..)
27 // Computes the size of the serialized version of the |Array|.
28 // * void SerializeElementsWithIterator(..)
29 // Takes an iterator and |num_elements| representing an |Array| (or
30 // possibly a |Map|), and serializes it.
31 // * void SerializeElements(..)
32 // Takes an |Array| directly and serializes it. This usually calls into
33 // SerializeElementsWithIterator(), except for an |Array| of PODs which
34 // will directly memcpy the PODs as an optimization.
36 template <typename E, 35 template <typename E,
37 typename F, 36 typename F,
38 bool is_union = 37 bool is_union =
39 IsUnionDataType<typename RemovePointer<F>::type>::value> 38 IsUnionDataType<typename RemovePointer<F>::type>::value>
40 struct ArraySerializer; 39 struct ArraySerializer;
41 40
42 // Handles serialization and deserialization of arrays of pod types. 41 // Handles serialization and deserialization of arrays of pod types.
43 template <typename E, typename F> 42 template <typename E, typename F>
44 struct ArraySerializer<E, F, false> { 43 struct ArraySerializer<E, F, false> {
45 static_assert(sizeof(E) == sizeof(F), "Incorrect array serializer"); 44 static_assert(sizeof(E) == sizeof(F), "Incorrect array serializer");
46 static size_t GetSerializedSize(const Array<E>& input) { 45 static size_t GetSerializedSize(const Array<E>& input) {
47 return sizeof(Array_Data<F>) + Align(input.size() * sizeof(E)); 46 return sizeof(Array_Data<F>) + Align(input.size() * sizeof(E));
48 } 47 }
49 48
50 static void SerializeElements(Array<E> input, 49 template <typename Iterator>
50 static void SerializeElementsWithIterator(
51 Iterator it,
52 size_t num_elements,
53 Buffer* buf,
54 Array_Data<F>* output,
55 const ArrayValidateParams* validate_params) {
56 MOJO_DCHECK(!validate_params->element_is_nullable)
57 << "Primitive type should be non-nullable";
58 MOJO_DCHECK(!validate_params->element_validate_params)
59 << "Primitive type should not have array validate params";
60 if (num_elements) {
viettrungluu 2015/09/23 23:20:24 This seems redundant.
vardhan 2015/09/25 19:33:05 oops
61 for (size_t i = 0; i < num_elements; ++i, ++it) {
viettrungluu 2015/09/23 23:20:24 nit: For consistency with other stuff in this file
vardhan 2015/09/25 19:33:05 Done.
62 output->at(i) = *it;
63 }
64 }
65 }
66
67 // We can optimize serializing PODs by |memcpy|ing directly.
68 static void SerializeElements(Array<E>* input,
51 Buffer* buf, 69 Buffer* buf,
52 Array_Data<F>* output, 70 Array_Data<F>* output,
53 const ArrayValidateParams* validate_params) { 71 const ArrayValidateParams* validate_params) {
54 MOJO_DCHECK(!validate_params->element_is_nullable) 72 MOJO_DCHECK(!validate_params->element_is_nullable)
55 << "Primitive type should be non-nullable"; 73 << "Primitive type should be non-nullable";
56 MOJO_DCHECK(!validate_params->element_validate_params) 74 MOJO_DCHECK(!validate_params->element_validate_params)
57 << "Primitive type should not have array validate params"; 75 << "Primitive type should not have array validate params";
76 if (input->size()) {
viettrungluu 2015/09/23 23:20:24 Assuming that output->storage() and &input->storag
vardhan 2015/09/25 19:33:05 output->storage() could point to memory we shouldn
77 memcpy(output->storage(), &input->storage()[0],
78 input->size() * sizeof(E));
79 }
80 }
58 81
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) { 82 static void DeserializeElements(Array_Data<F>* input, Array<E>* output) {
63 std::vector<E> result(input->size()); 83 std::vector<E> result(input->size());
64 if (input->size()) 84 if (input->size())
65 memcpy(&result[0], input->storage(), input->size() * sizeof(E)); 85 memcpy(&result[0], input->storage(), input->size() * sizeof(E));
66 output->Swap(&result); 86 output->Swap(&result);
67 } 87 }
68 }; 88 };
69 89
70 // Serializes and deserializes arrays of bools. 90 // Serializes and deserializes arrays of bools.
71 template <> 91 template <>
72 struct ArraySerializer<bool, bool, false> { 92 struct ArraySerializer<bool, bool, false> {
73 static size_t GetSerializedSize(const Array<bool>& input) { 93 static size_t GetSerializedSize(const Array<bool>& input) {
74 return sizeof(Array_Data<bool>) + Align((input.size() + 7) / 8); 94 return sizeof(Array_Data<bool>) + Align((input.size() + 7) / 8);
75 } 95 }
76 96
77 static void SerializeElements(Array<bool> input, 97 template <typename Iterator>
78 Buffer* buf, 98 static void SerializeElementsWithIterator(
79 Array_Data<bool>* output, 99 Iterator it,
80 const ArrayValidateParams* validate_params) { 100 size_t num_elements,
101 Buffer* buf,
102 Array_Data<bool>* output,
103 const ArrayValidateParams* validate_params) {
81 MOJO_DCHECK(!validate_params->element_is_nullable) 104 MOJO_DCHECK(!validate_params->element_is_nullable)
82 << "Primitive type should be non-nullable"; 105 << "Primitive type should be non-nullable";
83 MOJO_DCHECK(!validate_params->element_validate_params) 106 MOJO_DCHECK(!validate_params->element_validate_params)
84 << "Primitive type should not have array validate params"; 107 << "Primitive type should not have array validate params";
85 108
86 // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy? 109 // 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) 110 for (size_t i = 0; i < num_elements; ++i, ++it) {
viettrungluu 2015/09/23 23:20:24 Omit {}. (Probably do so elsewhere too.)
vardhan 2015/09/25 19:33:05 Done.
88 output->at(i) = input[i]; 111 output->at(i) = *it;
112 }
89 } 113 }
114
115 static void SerializeElements(Array<bool>* input,
116 Buffer* buf,
117 Array_Data<bool>* output,
118 const ArrayValidateParams* validate_params) {
119 SerializeElementsWithIterator(input->begin(), input->size(), buf, output,
120 validate_params);
121 }
122
90 static void DeserializeElements(Array_Data<bool>* input, 123 static void DeserializeElements(Array_Data<bool>* input,
91 Array<bool>* output) { 124 Array<bool>* output) {
92 Array<bool> result(input->size()); 125 Array<bool> result(input->size());
93 // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy? 126 // 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) 127 for (size_t i = 0; i < input->size(); ++i)
95 result.at(i) = input->at(i); 128 result.at(i) = input->at(i);
96 output->Swap(&result); 129 output->Swap(&result);
97 } 130 }
98 }; 131 };
99 132
100 // Serializes and deserializes arrays of handles. 133 // Serializes and deserializes arrays of handles.
101 template <typename H> 134 template <typename H>
102 struct ArraySerializer<ScopedHandleBase<H>, H, false> { 135 struct ArraySerializer<ScopedHandleBase<H>, H, false> {
103 static size_t GetSerializedSize(const Array<ScopedHandleBase<H>>& input) { 136 static size_t GetSerializedSize(const Array<ScopedHandleBase<H>>& input) {
104 return sizeof(Array_Data<H>) + Align(input.size() * sizeof(H)); 137 return sizeof(Array_Data<H>) + Align(input.size() * sizeof(H));
105 } 138 }
106 139
107 static void SerializeElements(Array<ScopedHandleBase<H>> input, 140 template <typename Iterator>
108 Buffer* buf, 141 static void SerializeElementsWithIterator(
109 Array_Data<H>* output, 142 Iterator it,
110 const ArrayValidateParams* validate_params) { 143 size_t num_elements,
144 Buffer* buf,
145 Array_Data<H>* output,
146 const ArrayValidateParams* validate_params) {
111 MOJO_DCHECK(!validate_params->element_validate_params) 147 MOJO_DCHECK(!validate_params->element_validate_params)
112 << "Handle type should not have array validate params"; 148 << "Handle type should not have array validate params";
113 149
114 for (size_t i = 0; i < input.size(); ++i) { 150 for (size_t i = 0; i < num_elements; ++i, ++it) {
115 output->at(i) = input[i].release(); // Transfer ownership of the handle. 151 // Transfer ownership of the handle.
152 output->at(i) = (*it).release();
116 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( 153 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
117 !validate_params->element_is_nullable && !output->at(i).is_valid(), 154 !validate_params->element_is_nullable && !output->at(i).is_valid(),
118 VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE, 155 VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
119 MakeMessageWithArrayIndex( 156 MakeMessageWithArrayIndex(
120 "invalid handle in array expecting valid handles", input.size(), 157 "invalid handle in array expecting valid handles", num_elements,
121 i)); 158 i));
122 } 159 }
123 } 160 }
161
162 static void SerializeElements(Array<ScopedHandleBase<H>>* input,
163 Buffer* buf,
164 Array_Data<H>* output,
165 const ArrayValidateParams* validate_params) {
166 SerializeElementsWithIterator(input->begin(), input->size(), buf, output,
167 validate_params);
168 }
169
124 static void DeserializeElements(Array_Data<H>* input, 170 static void DeserializeElements(Array_Data<H>* input,
125 Array<ScopedHandleBase<H>>* output) { 171 Array<ScopedHandleBase<H>>* output) {
126 Array<ScopedHandleBase<H>> result(input->size()); 172 Array<ScopedHandleBase<H>> result(input->size());
127 for (size_t i = 0; i < input->size(); ++i) 173 for (size_t i = 0; i < input->size(); ++i)
128 result.at(i) = MakeScopedHandle(FetchAndReset(&input->at(i))); 174 result.at(i) = MakeScopedHandle(FetchAndReset(&input->at(i)));
129 output->Swap(&result); 175 output->Swap(&result);
130 } 176 }
131 }; 177 };
132 178
133 // This template must only apply to pointer mojo entity (structs and arrays). 179 // SerializeCaller template is used by |ArraySerializer| to dispatch a serialize
134 // This is done by ensuring that WrapperTraits<S>::DataType is a pointer. 180 // call on a non-POD type. This template is defined outside |ArraySerializer|
181 // since you cannot specialize a struct within a class definition.
182 template <typename T>
183 struct SerializeCaller {
184 static void Run(T* input,
185 Buffer* buf,
186 typename WrapperTraits<T>::DataType* output,
187 const ArrayValidateParams* validate_params) {
188 MOJO_DCHECK(!validate_params)
189 << "Struct type should not have array validate params";
190 Serialize_(UnwrapStructPtr<T>::value(*input), buf, output);
191 }
192 };
193
194 template <>
195 struct SerializeCaller<String> {
196 static void Run(const String* input,
197 Buffer* buf,
198 String_Data** output,
199 const ArrayValidateParams* validate_params) {
200 MOJO_DCHECK(validate_params && !validate_params->element_validate_params &&
201 !validate_params->element_is_nullable &&
202 validate_params->expected_num_elements == 0)
203 << "String type has unexpected array validate params";
204 SerializeString_(*input, buf, output);
205 }
206 };
207
208 template <typename T>
209 struct SerializeCaller<Array<T>> {
210 static void Run(Array<T>* input,
211 Buffer* buf,
212 typename Array<T>::Data_** output,
213 const ArrayValidateParams* validate_params) {
214 SerializeArray_(input, buf, output, validate_params);
215 }
216 };
217
218 template <typename Key, typename Value>
219 struct SerializeCaller<Map<Key, Value>> {
220 static void Run(Map<Key, Value>* input,
221 Buffer* buf,
222 typename Map<Key, Value>::Data_** output,
223 const ArrayValidateParams* validate_params) {
224 SerializeMap_(input, buf, output, validate_params);
225 }
226 };
227
228 template <typename T,
229 bool IsStructPtr = IsSpecializationOf<StructPtr, T>::value ||
230 IsSpecializationOf<InlinedStructPtr, T>::value>
231 struct DeserializeCaller;
232
233 template <typename T>
234 struct DeserializeCaller<T, false> {
235 static void Run(typename WrapperTraits<T>::DataType input, T* output) {
236 Deserialize_(input, output);
237 }
238 };
239
240 template <typename T>
241 struct DeserializeCaller<T, true> {
242 static void Run(typename WrapperTraits<T>::DataType input, T* output) {
243 // Since Deserialize_ takes in a |Struct*| (not |StructPtr|), we need to
244 // initialize the |StructPtr| here before deserializing into its underlying
245 // data.
246 // TODO(vardhan): Either all containers, or just Deserialize_(), should
247 // support taking in an allocator.
248 using UnwrapedStructType = typename RemoveStructPtr<T>::type;
249 *output = UnwrapedStructType::New();
250 Deserialize_(input, output->get());
251 }
252 };
253
254 // This template must only apply to pointer mojo entity (structs, arrays,
255 // strings). This is done by ensuring that WrapperTraits<S>::DataType is a
256 // pointer.
135 template <typename S> 257 template <typename S>
136 struct ArraySerializer< 258 struct ArraySerializer<
137 S, 259 S,
138 typename EnableIf<IsPointer<typename WrapperTraits<S>::DataType>::value, 260 typename EnableIf<IsPointer<typename WrapperTraits<S>::DataType>::value,
139 typename WrapperTraits<S>::DataType>::type, 261 typename WrapperTraits<S>::DataType>::type,
140 false> { 262 false> {
141 typedef 263 typedef
142 typename RemovePointer<typename WrapperTraits<S>::DataType>::type S_Data; 264 typename RemovePointer<typename WrapperTraits<S>::DataType>::type S_Data;
143 static size_t GetSerializedSize(const Array<S>& input) { 265 static size_t GetSerializedSize(const Array<S>& input) {
144 size_t size = sizeof(Array_Data<S_Data*>) + 266 size_t size = sizeof(Array_Data<S_Data*>) +
145 input.size() * sizeof(StructPointer<S_Data>); 267 input.size() * sizeof(StructPointer<S_Data>);
146 for (size_t i = 0; i < input.size(); ++i) 268 for (size_t i = 0; i < input.size(); ++i)
147 size += GetSerializedSize_(input[i]); 269 size += GetSerializedSize_(*(UnwrapConstStructPtr<S>::value(input[i])));
148 return size; 270 return size;
149 } 271 }
150 272
151 static void SerializeElements(Array<S> input, 273 template <typename Iterator>
152 Buffer* buf, 274 static void SerializeElementsWithIterator(
153 Array_Data<S_Data*>* output, 275 Iterator it,
154 const ArrayValidateParams* validate_params) { 276 size_t num_elements,
155 for (size_t i = 0; i < input.size(); ++i) { 277 Buffer* buf,
278 Array_Data<S_Data*>* output,
279 const ArrayValidateParams* validate_params) {
280 for (size_t i = 0; i < num_elements; ++i, ++it) {
156 S_Data* element; 281 S_Data* element;
157 SerializeCaller<S>::Run(input[i].Pass(), buf, &element, 282 SerializeCaller<S>::Run(&(*it), buf, &element,
158 validate_params->element_validate_params); 283 validate_params->element_validate_params);
159 output->at(i) = element; 284 output->at(i) = element;
160 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( 285 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
161 !validate_params->element_is_nullable && !element, 286 !validate_params->element_is_nullable && !element,
162 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, 287 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
163 MakeMessageWithArrayIndex("null in array expecting valid pointers", 288 MakeMessageWithArrayIndex("null in array expecting valid pointers",
164 input.size(), i)); 289 num_elements, i));
165 } 290 }
166 } 291 }
292
293 static void SerializeElements(Array<S>* input,
294 Buffer* buf,
295 Array_Data<S_Data*>* output,
296 const ArrayValidateParams* validate_params) {
297 SerializeElementsWithIterator(input->begin(), input->size(), buf, output,
298 validate_params);
299 }
300
167 static void DeserializeElements(Array_Data<S_Data*>* input, 301 static void DeserializeElements(Array_Data<S_Data*>* input,
168 Array<S>* output) { 302 Array<S>* output) {
169 Array<S> result(input->size()); 303 Array<S> result(input->size());
170 for (size_t i = 0; i < input->size(); ++i) { 304 for (size_t i = 0; i < input->size(); ++i) {
171 Deserialize_(input->at(i), &result[i]); 305 DeserializeCaller<S>::Run(input->at(i), &result[i]);
172 } 306 }
173 output->Swap(&result); 307 output->Swap(&result);
174 } 308 }
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 }; 309 };
210 310
211 // Handles serialization and deserialization of arrays of unions. 311 // Handles serialization and deserialization of arrays of unions.
212 template <typename U, typename U_Data> 312 template <typename U, typename U_Data>
213 struct ArraySerializer<U, U_Data, true> { 313 struct ArraySerializer<U, U_Data, true> {
214 static size_t GetSerializedSize(const Array<U>& input) { 314 static size_t GetSerializedSize(const Array<U>& input) {
215 size_t size = sizeof(Array_Data<U_Data>); 315 size_t size = sizeof(Array_Data<U_Data>);
216 for (size_t i = 0; i < input.size(); ++i) { 316 for (size_t i = 0; i < input.size(); ++i) {
217 // GetSerializedSize_ will account for both the data in the union and the 317 // GetSerializedSize_ will account for both the data in the union and the
218 // space in the array used to hold the union. 318 // space in the array used to hold the union.
219 size += GetSerializedSize_(input[i], false); 319 size += GetSerializedSize_(input[i], false);
220 } 320 }
221 return size; 321 return size;
222 } 322 }
223 323
224 static void SerializeElements(Array<U> input, 324 template <typename Iterator>
225 Buffer* buf, 325 static void SerializeElementsWithIterator(
226 Array_Data<U_Data>* output, 326 Iterator it,
227 const ArrayValidateParams* validate_params) { 327 size_t num_elements,
228 for (size_t i = 0; i < input.size(); ++i) { 328 Buffer* buf,
329 Array_Data<U_Data>* output,
330 const ArrayValidateParams* validate_params) {
331 for (size_t i = 0; i < num_elements; ++i, ++it) {
229 U_Data* result = output->storage() + i; 332 U_Data* result = output->storage() + i;
230 SerializeUnion_(input[i].Pass(), buf, &result, true); 333 SerializeUnion_((*it).get(), buf, &result, true);
231 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( 334 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
232 !validate_params->element_is_nullable && output->at(i).is_null(), 335 !validate_params->element_is_nullable && output->at(i).is_null(),
233 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, 336 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
234 MakeMessageWithArrayIndex("null in array expecting valid unions", 337 MakeMessageWithArrayIndex("null in array expecting valid unions",
235 input.size(), i)); 338 num_elements, i));
236 } 339 }
237 } 340 }
238 341
342 static void SerializeElements(Array<U>* input,
343 Buffer* buf,
344 Array_Data<U_Data>* output,
345 const ArrayValidateParams* validate_params) {
346 SerializeElementsWithIterator(input->begin(), input->size(), buf, output,
347 validate_params);
348 }
349
239 static void DeserializeElements(Array_Data<U_Data>* input, Array<U>* output) { 350 static void DeserializeElements(Array_Data<U_Data>* input, Array<U>* output) {
240 Array<U> result(input->size()); 351 Array<U> result(input->size());
241 for (size_t i = 0; i < input->size(); ++i) { 352 for (size_t i = 0; i < input->size(); ++i) {
242 Deserialize_(&input->at(i), &result[i]); 353 auto& elem = input->at(i);
354 if (!elem.is_null()) {
355 using UnwrapedUnionType = typename RemoveStructPtr<U>::type;
356 result[i] = UnwrapedUnionType::New();
357 Deserialize_(&elem, result[i].get());
358 }
243 } 359 }
244 output->Swap(&result); 360 output->Swap(&result);
245 } 361 }
246 }; 362 };
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 363
290 } // namespace internal 364 } // namespace internal
291 365
292 template <typename E> 366 template <typename E>
293 inline size_t GetSerializedSize_(const Array<E>& input) { 367 inline size_t GetSerializedSize_(const Array<E>& input) {
294 if (!input) 368 if (!input)
295 return 0; 369 return 0;
296 typedef typename internal::WrapperTraits<E>::DataType F; 370 typedef typename internal::WrapperTraits<E>::DataType F;
297 return internal::ArraySerializer<E, F>::GetSerializedSize(input); 371 return internal::ArraySerializer<E, F>::GetSerializedSize(input);
298 } 372 }
299 373
300 template <typename E, typename F> 374 template <typename E, typename F>
301 inline void SerializeArray_( 375 inline void SerializeArray_(
302 Array<E> input, 376 Array<E>* input,
303 internal::Buffer* buf, 377 internal::Buffer* buf,
304 internal::Array_Data<F>** output, 378 internal::Array_Data<F>** output,
305 const internal::ArrayValidateParams* validate_params) { 379 const internal::ArrayValidateParams* validate_params) {
306 if (input) { 380 if (input && *input) {
307 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( 381 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
308 validate_params->expected_num_elements != 0 && 382 validate_params->expected_num_elements != 0 &&
309 input.size() != validate_params->expected_num_elements, 383 input->size() != validate_params->expected_num_elements,
310 internal::VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER, 384 internal::VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER,
311 internal::MakeMessageWithExpectedArraySize( 385 internal::MakeMessageWithExpectedArraySize(
312 "fixed-size array has wrong number of elements", input.size(), 386 "fixed-size array has wrong number of elements", input->size(),
313 validate_params->expected_num_elements)); 387 validate_params->expected_num_elements));
314 388
315 internal::Array_Data<F>* result = 389 internal::Array_Data<F>* result =
316 internal::Array_Data<F>::New(input.size(), buf); 390 internal::Array_Data<F>::New(input->size(), buf);
317 if (result) { 391 if (result) {
318 internal::ArraySerializer<E, F>::SerializeElements( 392 internal::ArraySerializer<E, F>::SerializeElements(input, buf, result,
319 internal::Forward(input), buf, result, validate_params); 393 validate_params);
320 } 394 }
321 *output = result; 395 *output = result;
322 } else { 396 } else {
323 *output = nullptr; 397 *output = nullptr;
324 } 398 }
325 } 399 }
326 400
327 template <typename E, typename F> 401 template <typename E, typename F>
328 inline void Deserialize_(internal::Array_Data<F>* input, Array<E>* output) { 402 inline void Deserialize_(internal::Array_Data<F>* input, Array<E>* output) {
329 if (input) { 403 if (input) {
330 internal::ArraySerializer<E, F>::DeserializeElements(input, output); 404 internal::ArraySerializer<E, F>::DeserializeElements(input, output);
331 } else { 405 } else {
332 output->reset(); 406 output->reset();
333 } 407 }
334 } 408 }
335 409
336 } // namespace mojo 410 } // namespace mojo
337 411
338 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_ 412 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698