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

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

Issue 2014403002: Mojo C++ bindings: custom type mapping of map (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 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
« no previous file with comments | « mojo/public/cpp/bindings/array_traits.h ('k') | mojo/public/cpp/bindings/lib/map_internal.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <stddef.h> 8 #include <stddef.h>
9 #include <string.h> // For |memcpy()|. 9 #include <string.h> // For |memcpy()|.
10 10
11 #include <limits> 11 #include <limits>
12 #include <type_traits> 12 #include <type_traits>
13 #include <utility> 13 #include <utility>
14 #include <vector> 14 #include <vector>
15 15
16 #include "base/logging.h" 16 #include "base/logging.h"
17 #include "mojo/public/cpp/bindings/array.h" 17 #include "mojo/public/cpp/bindings/array.h"
18 #include "mojo/public/cpp/bindings/lib/array_internal.h" 18 #include "mojo/public/cpp/bindings/lib/array_internal.h"
19 #include "mojo/public/cpp/bindings/lib/serialization_forward.h" 19 #include "mojo/public/cpp/bindings/lib/serialization_forward.h"
20 #include "mojo/public/cpp/bindings/lib/template_util.h" 20 #include "mojo/public/cpp/bindings/lib/template_util.h"
21 #include "mojo/public/cpp/bindings/lib/validation_errors.h" 21 #include "mojo/public/cpp/bindings/lib/validation_errors.h"
22 22
23 namespace WTF {
24 class String;
25 }
26
27 namespace mojo { 23 namespace mojo {
28 namespace internal { 24 namespace internal {
29 25
30 enum class ArraySerializerType { 26 enum class ArraySerializerType {
31 BOOLEAN, 27 BOOLEAN,
32 // Except boolean. 28 // Except boolean.
33 POD, 29 POD,
34 HANDLE, 30 HANDLE,
35 // String, array, map and struct. 31 // String, array, map and struct.
36 POINTER, 32 POINTER,
37 UNION 33 UNION
38 }; 34 };
39 35
40 template <typename T> 36 template <typename T>
41 struct GetArraySerializerType { 37 struct GetArraySerializerType {
42 static const ArraySerializerType value = 38 static const ArraySerializerType value =
43 IsUnionDataType<T>::value 39 IsUnionDataType<T>::value
44 ? ArraySerializerType::UNION 40 ? ArraySerializerType::UNION
45 : (std::is_pointer<T>::value 41 : (std::is_pointer<T>::value
46 ? ArraySerializerType::POINTER 42 ? ArraySerializerType::POINTER
47 : (IsHandle<T>::value ? ArraySerializerType::HANDLE 43 : (IsHandle<T>::value ? ArraySerializerType::HANDLE
48 : (std::is_same<T, bool>::value 44 : (std::is_same<T, bool>::value
49 ? ArraySerializerType::BOOLEAN 45 ? ArraySerializerType::BOOLEAN
50 : ArraySerializerType::POD))); 46 : ArraySerializerType::POD)));
51 }; 47 };
52 48
49 // Used as the UserTypeReader template parameter of ArraySerializer.
50 template <typename MaybeConstUserType>
51 class ArrayReader {
52 public:
53 using UserType = typename std::remove_const<MaybeConstUserType>::type;
54 using Traits = ArrayTraits<UserType>;
55
56 explicit ArrayReader(MaybeConstUserType& input) : input_(input) {}
57 ~ArrayReader() {}
58
59 size_t GetSize() const { return Traits::GetSize(input_); }
60
61 using GetNextResult =
62 decltype(Traits::GetAt(std::declval<MaybeConstUserType&>(), 0));
63 GetNextResult GetNext() {
64 DCHECK_LT(index_, Traits::GetSize(input_));
65 return Traits::GetAt(input_, index_++);
66 }
67
68 using GetDataIfExistsResult = decltype(
69 CallGetDataIfExists<Traits>(std::declval<MaybeConstUserType&>()));
70 GetDataIfExistsResult GetDataIfExists() {
71 return CallGetDataIfExists<Traits>(input_);
72 }
73
74 private:
75 MaybeConstUserType& input_;
76 size_t index_ = 0;
77 };
78
79 // ArraySerializer is also used to serialize map keys and values. Therefore, it
80 // has a UserTypeReader parameter which is an adaptor for reading to hide the
81 // difference between ArrayTraits and MapTraits.
53 template <typename MojomType, 82 template <typename MojomType,
54 typename MaybeConstUserType, 83 typename MaybeConstUserType,
84 typename UserTypeReader,
55 ArraySerializerType type = 85 ArraySerializerType type =
56 GetArraySerializerType<typename MojomType::Data_::Element>::value> 86 GetArraySerializerType<typename MojomType::Data_::Element>::value>
57 struct ArraySerializer; 87 struct ArraySerializer;
58 88
59 // Handles serialization and deserialization of arrays of pod types. 89 // Handles serialization and deserialization of arrays of pod types.
60 template <typename MojomType, typename MaybeConstUserType> 90 template <typename MojomType,
91 typename MaybeConstUserType,
92 typename UserTypeReader>
61 struct ArraySerializer<MojomType, 93 struct ArraySerializer<MojomType,
62 MaybeConstUserType, 94 MaybeConstUserType,
95 UserTypeReader,
63 ArraySerializerType::POD> { 96 ArraySerializerType::POD> {
64 using UserType = typename std::remove_const<MaybeConstUserType>::type; 97 using UserType = typename std::remove_const<MaybeConstUserType>::type;
65 using Data = typename MojomType::Data_; 98 using Data = typename MojomType::Data_;
66 using DataElement = typename Data::Element; 99 using DataElement = typename Data::Element;
67 using Element = typename MojomType::Element; 100 using Element = typename MojomType::Element;
68 using Traits = ArrayTraits<UserType>; 101 using Traits = ArrayTraits<UserType>;
69 102
70 static_assert(sizeof(Element) == sizeof(DataElement), 103 static_assert(sizeof(Element) == sizeof(DataElement),
71 "Incorrect array serializer"); 104 "Incorrect array serializer");
72 static_assert(std::is_same<Element, typename Traits::Element>::value, 105 static_assert(std::is_same<Element, typename Traits::Element>::value,
73 "Incorrect array serializer"); 106 "Incorrect array serializer");
74 107
75 static size_t GetSerializedSize(MaybeConstUserType& input, 108 static size_t GetSerializedSize(UserTypeReader* input,
76 SerializationContext* context) { 109 SerializationContext* context) {
77 return sizeof(Data) + Align(Traits::GetSize(input) * sizeof(DataElement)); 110 return sizeof(Data) + Align(input->GetSize() * sizeof(DataElement));
78 } 111 }
79 112
80 static void SerializeElements(MaybeConstUserType& input, 113 static void SerializeElements(UserTypeReader* input,
81 Buffer* buf, 114 Buffer* buf,
82 Data* output, 115 Data* output,
83 const ArrayValidateParams* validate_params, 116 const ArrayValidateParams* validate_params,
84 SerializationContext* context) { 117 SerializationContext* context) {
85 DCHECK(!validate_params->element_is_nullable) 118 DCHECK(!validate_params->element_is_nullable)
86 << "Primitive type should be non-nullable"; 119 << "Primitive type should be non-nullable";
87 DCHECK(!validate_params->element_validate_params) 120 DCHECK(!validate_params->element_validate_params)
88 << "Primitive type should not have array validate params"; 121 << "Primitive type should not have array validate params";
89 122
90 if (Traits::GetSize(input)) { 123 size_t size = input->GetSize();
91 memcpy(output->storage(), Traits::GetData(input), 124 if (size == 0)
92 Traits::GetSize(input) * sizeof(DataElement)); 125 return;
126
127 auto data = input->GetDataIfExists();
128 if (data) {
129 memcpy(output->storage(), data, size * sizeof(DataElement));
130 } else {
131 for (size_t i = 0; i < size; ++i)
132 output->at(i) = static_cast<DataElement>(input->GetNext());
93 } 133 }
94 } 134 }
95 135
96 static bool DeserializeElements(Data* input, 136 static bool DeserializeElements(Data* input,
97 UserType* output, 137 UserType* output,
98 SerializationContext* context) { 138 SerializationContext* context) {
99 Traits::Resize(*output, input->size()); 139 Traits::Resize(*output, input->size());
100 if (input->size()) { 140 if (input->size()) {
101 memcpy(Traits::GetData(*output), input->storage(), 141 auto data = CallGetDataIfExists<Traits>(*output);
102 input->size() * sizeof(DataElement)); 142 if (data) {
143 memcpy(data, input->storage(), input->size() * sizeof(DataElement));
144 } else {
145 for (size_t i = 0; i < input->size(); ++i)
146 Traits::GetAt(*output, i) = static_cast<Element>(input->at(i));
147 }
103 } 148 }
104 return true; 149 return true;
105 } 150 }
106 }; 151 };
107 152
108 // Serializes and deserializes arrays of bools. 153 // Serializes and deserializes arrays of bools.
109 template <typename MojomType, typename MaybeConstUserType> 154 template <typename MojomType,
155 typename MaybeConstUserType,
156 typename UserTypeReader>
110 struct ArraySerializer<MojomType, 157 struct ArraySerializer<MojomType,
111 MaybeConstUserType, 158 MaybeConstUserType,
159 UserTypeReader,
112 ArraySerializerType::BOOLEAN> { 160 ArraySerializerType::BOOLEAN> {
113 using UserType = typename std::remove_const<MaybeConstUserType>::type; 161 using UserType = typename std::remove_const<MaybeConstUserType>::type;
114 using Traits = ArrayTraits<UserType>; 162 using Traits = ArrayTraits<UserType>;
115 using Data = typename MojomType::Data_; 163 using Data = typename MojomType::Data_;
116 164
117 static_assert(std::is_same<bool, typename UserType::Element>::value, 165 static_assert(std::is_same<bool, typename UserType::Element>::value,
118 "Incorrect array serializer"); 166 "Incorrect array serializer");
119 167
120 static size_t GetSerializedSize(MaybeConstUserType& input, 168 static size_t GetSerializedSize(UserTypeReader* input,
121 SerializationContext* context) { 169 SerializationContext* context) {
122 return sizeof(Data) + Align((Traits::GetSize(input) + 7) / 8); 170 return sizeof(Data) + Align((input->GetSize() + 7) / 8);
123 } 171 }
124 172
125 static void SerializeElements(MaybeConstUserType& input, 173 static void SerializeElements(UserTypeReader* input,
126 Buffer* buf, 174 Buffer* buf,
127 Data* output, 175 Data* output,
128 const ArrayValidateParams* validate_params, 176 const ArrayValidateParams* validate_params,
129 SerializationContext* context) { 177 SerializationContext* context) {
130 DCHECK(!validate_params->element_is_nullable) 178 DCHECK(!validate_params->element_is_nullable)
131 << "Primitive type should be non-nullable"; 179 << "Primitive type should be non-nullable";
132 DCHECK(!validate_params->element_validate_params) 180 DCHECK(!validate_params->element_validate_params)
133 << "Primitive type should not have array validate params"; 181 << "Primitive type should not have array validate params";
134 182
135 // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy? 183 size_t size = input->GetSize();
136 size_t size = Traits::GetSize(input);
137 for (size_t i = 0; i < size; ++i) 184 for (size_t i = 0; i < size; ++i)
138 output->at(i) = Traits::GetAt(input, i); 185 output->at(i) = input->GetNext();
139 } 186 }
140 static bool DeserializeElements(Data* input, 187 static bool DeserializeElements(Data* input,
141 UserType* output, 188 UserType* output,
142 SerializationContext* context) { 189 SerializationContext* context) {
143 Traits::Resize(*output, input->size()); 190 Traits::Resize(*output, input->size());
144 // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy?
145 for (size_t i = 0; i < input->size(); ++i) 191 for (size_t i = 0; i < input->size(); ++i)
146 Traits::GetAt(*output, i) = input->at(i); 192 Traits::GetAt(*output, i) = input->at(i);
147 return true; 193 return true;
148 } 194 }
149 }; 195 };
150 196
151 // Serializes and deserializes arrays of handles. 197 // Serializes and deserializes arrays of handles.
152 template <typename MojomType, typename MaybeConstUserType> 198 template <typename MojomType,
199 typename MaybeConstUserType,
200 typename UserTypeReader>
153 struct ArraySerializer<MojomType, 201 struct ArraySerializer<MojomType,
154 MaybeConstUserType, 202 MaybeConstUserType,
203 UserTypeReader,
155 ArraySerializerType::HANDLE> { 204 ArraySerializerType::HANDLE> {
156 using UserType = typename std::remove_const<MaybeConstUserType>::type; 205 using UserType = typename std::remove_const<MaybeConstUserType>::type;
157 using Data = typename MojomType::Data_; 206 using Data = typename MojomType::Data_;
158 using Element = typename MojomType::Element; 207 using Element = typename MojomType::Element;
159 using Traits = ArrayTraits<UserType>; 208 using Traits = ArrayTraits<UserType>;
160 209
161 static_assert(std::is_same<Element, typename Traits::Element>::value, 210 static_assert(std::is_same<Element, typename Traits::Element>::value,
162 "Incorrect array serializer"); 211 "Incorrect array serializer");
163 212
164 static size_t GetSerializedSize(MaybeConstUserType& input, 213 static size_t GetSerializedSize(UserTypeReader* input,
165 SerializationContext* context) { 214 SerializationContext* context) {
166 return sizeof(Data) + 215 return sizeof(Data) +
167 Align(Traits::GetSize(input) * sizeof(typename Data::Element)); 216 Align(input->GetSize() * sizeof(typename Data::Element));
168 } 217 }
169 218
170 static void SerializeElements(MaybeConstUserType& input, 219 static void SerializeElements(UserTypeReader* input,
171 Buffer* buf, 220 Buffer* buf,
172 Data* output, 221 Data* output,
173 const ArrayValidateParams* validate_params, 222 const ArrayValidateParams* validate_params,
174 SerializationContext* context) { 223 SerializationContext* context) {
175 DCHECK(!validate_params->element_validate_params) 224 DCHECK(!validate_params->element_validate_params)
176 << "Handle type should not have array validate params"; 225 << "Handle type should not have array validate params";
177 226
178 size_t size = Traits::GetSize(input); 227 size_t size = input->GetSize();
179 for (size_t i = 0; i < size; ++i) { 228 for (size_t i = 0; i < size; ++i) {
180 // Transfer ownership of the handle. 229 // Transfer ownership of the handle.
181 output->at(i) = 230 output->at(i) = context->handles.AddHandle(input->GetNext().release());
182 context->handles.AddHandle(Traits::GetAt(input, i).release());
183 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( 231 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
184 !validate_params->element_is_nullable && !output->at(i).is_valid(), 232 !validate_params->element_is_nullable && !output->at(i).is_valid(),
185 VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE, 233 VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
186 MakeMessageWithArrayIndex( 234 MakeMessageWithArrayIndex(
187 "invalid handle in array expecting valid handles", size, i)); 235 "invalid handle in array expecting valid handles", size, i));
188 } 236 }
189 } 237 }
190 static bool DeserializeElements(Data* input, 238 static bool DeserializeElements(Data* input,
191 UserType* output, 239 UserType* output,
192 SerializationContext* context) { 240 SerializationContext* context) {
193 using HandleType = typename Element::RawHandleType; 241 using HandleType = typename Element::RawHandleType;
194 Traits::Resize(*output, input->size()); 242 Traits::Resize(*output, input->size());
195 for (size_t i = 0; i < input->size(); ++i) { 243 for (size_t i = 0; i < input->size(); ++i) {
196 Traits::GetAt(*output, i) = MakeScopedHandle( 244 Traits::GetAt(*output, i) = MakeScopedHandle(
197 HandleType(context->handles.TakeHandle(input->at(i)).value())); 245 HandleType(context->handles.TakeHandle(input->at(i)).value()));
198 } 246 }
199 return true; 247 return true;
200 } 248 }
201 }; 249 };
202 250
203 // This template must only apply to pointer mojo entity (strings, structs, 251 // This template must only apply to pointer mojo entity (strings, structs,
204 // arrays and maps). 252 // arrays and maps).
205 template <typename MojomType, typename MaybeConstUserType> 253 template <typename MojomType,
254 typename MaybeConstUserType,
255 typename UserTypeReader>
206 struct ArraySerializer<MojomType, 256 struct ArraySerializer<MojomType,
207 MaybeConstUserType, 257 MaybeConstUserType,
258 UserTypeReader,
208 ArraySerializerType::POINTER> { 259 ArraySerializerType::POINTER> {
209 using UserType = typename std::remove_const<MaybeConstUserType>::type; 260 using UserType = typename std::remove_const<MaybeConstUserType>::type;
210 using Data = typename MojomType::Data_; 261 using Data = typename MojomType::Data_;
211 using DataElement = typename Data::Element; 262 using DataElement = typename Data::Element;
212 using Element = typename MojomType::Element; 263 using Element = typename MojomType::Element;
213 using Traits = ArrayTraits<UserType>; 264 using Traits = ArrayTraits<UserType>;
214 265
215 static size_t GetSerializedSize(MaybeConstUserType& input, 266 static size_t GetSerializedSize(UserTypeReader* input,
216 SerializationContext* context) { 267 SerializationContext* context) {
217 size_t element_count = Traits::GetSize(input); 268 size_t element_count = input->GetSize();
218 size_t size = 269 size_t size =
219 sizeof(Data) + 270 sizeof(Data) +
220 element_count * 271 element_count *
221 sizeof(Pointer<typename std::remove_pointer<DataElement>::type>); 272 sizeof(Pointer<typename std::remove_pointer<DataElement>::type>);
222 for (size_t i = 0; i < element_count; ++i) 273 for (size_t i = 0; i < element_count; ++i)
223 size += PrepareToSerialize<Element>(Traits::GetAt(input, i), context); 274 size += PrepareToSerialize<Element>(input->GetNext(), context);
224 return size; 275 return size;
225 } 276 }
226 277
227 static void SerializeElements(MaybeConstUserType& input, 278 static void SerializeElements(UserTypeReader* input,
228 Buffer* buf, 279 Buffer* buf,
229 Data* output, 280 Data* output,
230 const ArrayValidateParams* validate_params, 281 const ArrayValidateParams* validate_params,
231 SerializationContext* context) { 282 SerializationContext* context) {
232 size_t size = Traits::GetSize(input); 283 size_t size = input->GetSize();
233 for (size_t i = 0; i < size; ++i) { 284 for (size_t i = 0; i < size; ++i) {
234 DataElement element; 285 DataElement element;
235 SerializeCaller<Element>::Run(Traits::GetAt(input, i), buf, &element, 286 SerializeCaller<Element>::Run(input->GetNext(), buf, &element,
236 validate_params->element_validate_params, 287 validate_params->element_validate_params,
237 context); 288 context);
238 output->at(i) = element; 289 output->at(i) = element;
239 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( 290 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
240 !validate_params->element_is_nullable && !element, 291 !validate_params->element_is_nullable && !element,
241 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, 292 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
242 MakeMessageWithArrayIndex("null in array expecting valid pointers", 293 MakeMessageWithArrayIndex("null in array expecting valid pointers",
243 size, i)); 294 size, i));
244 } 295 }
245 } 296 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 DataElement* output, 334 DataElement* output,
284 const ArrayValidateParams* validate_params, 335 const ArrayValidateParams* validate_params,
285 SerializationContext* context) { 336 SerializationContext* context) {
286 Serialize<T>(std::forward<InputElementType>(input), buf, output, 337 Serialize<T>(std::forward<InputElementType>(input), buf, output,
287 validate_params, context); 338 validate_params, context);
288 } 339 }
289 }; 340 };
290 }; 341 };
291 342
292 // Handles serialization and deserialization of arrays of unions. 343 // Handles serialization and deserialization of arrays of unions.
293 template <typename MojomType, typename MaybeConstUserType> 344 template <typename MojomType,
345 typename MaybeConstUserType,
346 typename UserTypeReader>
294 struct ArraySerializer<MojomType, 347 struct ArraySerializer<MojomType,
295 MaybeConstUserType, 348 MaybeConstUserType,
349 UserTypeReader,
296 ArraySerializerType::UNION> { 350 ArraySerializerType::UNION> {
297 using UserType = typename std::remove_const<MaybeConstUserType>::type; 351 using UserType = typename std::remove_const<MaybeConstUserType>::type;
298 using Data = typename MojomType::Data_; 352 using Data = typename MojomType::Data_;
299 using Element = typename MojomType::Element; 353 using Element = typename MojomType::Element;
300 using Traits = ArrayTraits<UserType>; 354 using Traits = ArrayTraits<UserType>;
301 355
302 static_assert(std::is_same<typename MojomType::Element, 356 static_assert(std::is_same<typename MojomType::Element,
303 typename Traits::Element>::value, 357 typename Traits::Element>::value,
304 "Incorrect array serializer"); 358 "Incorrect array serializer");
305 359
306 static size_t GetSerializedSize(MaybeConstUserType& input, 360 static size_t GetSerializedSize(UserTypeReader* input,
307 SerializationContext* context) { 361 SerializationContext* context) {
308 size_t element_count = Traits::GetSize(input); 362 size_t element_count = input->GetSize();
309 size_t size = sizeof(Data); 363 size_t size = sizeof(Data);
310 for (size_t i = 0; i < element_count; ++i) { 364 for (size_t i = 0; i < element_count; ++i) {
311 // Call with |inlined| set to false, so that it will account for both the 365 // Call with |inlined| set to false, so that it will account for both the
312 // data in the union and the space in the array used to hold the union. 366 // data in the union and the space in the array used to hold the union.
313 size += 367 size += PrepareToSerialize<Element>(input->GetNext(), false, context);
314 PrepareToSerialize<Element>(Traits::GetAt(input, i), false, context);
315 } 368 }
316 return size; 369 return size;
317 } 370 }
318 371
319 static void SerializeElements(MaybeConstUserType& input, 372 static void SerializeElements(UserTypeReader* input,
320 Buffer* buf, 373 Buffer* buf,
321 Data* output, 374 Data* output,
322 const ArrayValidateParams* validate_params, 375 const ArrayValidateParams* validate_params,
323 SerializationContext* context) { 376 SerializationContext* context) {
324 size_t size = Traits::GetSize(input); 377 size_t size = input->GetSize();
325 for (size_t i = 0; i < size; ++i) { 378 for (size_t i = 0; i < size; ++i) {
326 typename Data::Element* result = output->storage() + i; 379 typename Data::Element* result = output->storage() + i;
327 Serialize<Element>(Traits::GetAt(input, i), buf, &result, true, context); 380 Serialize<Element>(input->GetNext(), buf, &result, true, context);
328 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( 381 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
329 !validate_params->element_is_nullable && output->at(i).is_null(), 382 !validate_params->element_is_nullable && output->at(i).is_null(),
330 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, 383 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
331 MakeMessageWithArrayIndex("null in array expecting valid unions", 384 MakeMessageWithArrayIndex("null in array expecting valid unions",
332 size, i)); 385 size, i));
333 } 386 }
334 } 387 }
335 388
336 static bool DeserializeElements(Data* input, 389 static bool DeserializeElements(Data* input,
337 UserType* output, 390 UserType* output,
338 SerializationContext* context) { 391 SerializationContext* context) {
339 bool success = true; 392 bool success = true;
340 Traits::Resize(*output, input->size()); 393 Traits::Resize(*output, input->size());
341 for (size_t i = 0; i < input->size(); ++i) { 394 for (size_t i = 0; i < input->size(); ++i) {
342 // Note that we rely on complete deserialization taking place in order to 395 // Note that we rely on complete deserialization taking place in order to
343 // transfer ownership of all encoded handles. Therefore we don't 396 // transfer ownership of all encoded handles. Therefore we don't
344 // short-circuit on failure here. 397 // short-circuit on failure here.
345 if (!Deserialize<Element>(&input->at(i), &Traits::GetAt(*output, i), 398 if (!Deserialize<Element>(&input->at(i), &Traits::GetAt(*output, i),
346 context)) { 399 context)) {
347 success = false; 400 success = false;
348 } 401 }
349 } 402 }
350 return success; 403 return success;
351 } 404 }
352 }; 405 };
353 406
354 template <typename Element, typename MaybeConstUserType> 407 template <typename Element, typename MaybeConstUserType>
355 struct Serializer<Array<Element>, MaybeConstUserType> { 408 struct Serializer<Array<Element>, MaybeConstUserType> {
356 using UserType = typename std::remove_const<MaybeConstUserType>::type; 409 using UserType = typename std::remove_const<MaybeConstUserType>::type;
357 using Impl = ArraySerializer<Array<Element>, MaybeConstUserType>; 410 using Impl = ArraySerializer<Array<Element>,
411 MaybeConstUserType,
412 ArrayReader<MaybeConstUserType>>;
358 using Traits = ArrayTraits<UserType>; 413 using Traits = ArrayTraits<UserType>;
359 using Data = typename Array<Element>::Data_; 414 using Data = typename Array<Element>::Data_;
360 415
361 static size_t PrepareToSerialize(MaybeConstUserType& input, 416 static size_t PrepareToSerialize(MaybeConstUserType& input,
362 SerializationContext* context) { 417 SerializationContext* context) {
363 if (CallIsNullIfExists<Traits>(input)) 418 if (CallIsNullIfExists<Traits>(input))
364 return 0; 419 return 0;
365 return Impl::GetSerializedSize(input, context); 420 ArrayReader<MaybeConstUserType> reader(input);
421 return Impl::GetSerializedSize(&reader, context);
366 } 422 }
367 423
368 static void Serialize(MaybeConstUserType& input, 424 static void Serialize(MaybeConstUserType& input,
369 Buffer* buf, 425 Buffer* buf,
370 Data** output, 426 Data** output,
371 const ArrayValidateParams* validate_params, 427 const ArrayValidateParams* validate_params,
372 SerializationContext* context) { 428 SerializationContext* context) {
373 if (!CallIsNullIfExists<Traits>(input)) { 429 if (!CallIsNullIfExists<Traits>(input)) {
374 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( 430 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
375 validate_params->expected_num_elements != 0 && 431 validate_params->expected_num_elements != 0 &&
376 Traits::GetSize(input) != validate_params->expected_num_elements, 432 Traits::GetSize(input) != validate_params->expected_num_elements,
377 internal::VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER, 433 internal::VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER,
378 internal::MakeMessageWithExpectedArraySize( 434 internal::MakeMessageWithExpectedArraySize(
379 "fixed-size array has wrong number of elements", 435 "fixed-size array has wrong number of elements",
380 Traits::GetSize(input), validate_params->expected_num_elements)); 436 Traits::GetSize(input), validate_params->expected_num_elements));
381 Data* result = Data::New(Traits::GetSize(input), buf); 437 Data* result = Data::New(Traits::GetSize(input), buf);
382 if (result) 438 if (result) {
383 Impl::SerializeElements(input, buf, result, validate_params, context); 439 ArrayReader<MaybeConstUserType> reader(input);
440 Impl::SerializeElements(&reader, buf, result, validate_params, context);
441 }
384 *output = result; 442 *output = result;
385 } else { 443 } else {
386 *output = nullptr; 444 *output = nullptr;
387 } 445 }
388 } 446 }
389 447
390 static bool Deserialize(Data* input, 448 static bool Deserialize(Data* input,
391 UserType* output, 449 UserType* output,
392 SerializationContext* context) { 450 SerializationContext* context) {
393 if (!input) 451 if (!input)
394 return CallSetToNullIfExists<Traits>(output); 452 return CallSetToNullIfExists<Traits>(output);
395 return Impl::DeserializeElements(input, output, context); 453 return Impl::DeserializeElements(input, output, context);
396 } 454 }
397 }; 455 };
398 456
399 } // namespace internal 457 } // namespace internal
400 } // namespace mojo 458 } // namespace mojo
401 459
402 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_ 460 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_
OLDNEW
« no previous file with comments | « mojo/public/cpp/bindings/array_traits.h ('k') | mojo/public/cpp/bindings/lib/map_internal.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698