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

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
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 GetDataIfAvailableResult =
69 decltype(Traits::GetData(std::declval<MaybeConstUserType&>()));
70 GetDataIfAvailableResult GetDataIfAvailable() {
71 return Traits::GetData(input_);
Ken Rockot(use gerrit already) 2016/05/27 16:07:39 If this can work in the general case (returning nu
yzshen1 2016/05/28 00:23:07 I made the GetData() function of ArrayTraits optio
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->GetDataIfAvailable();
128 if (data) {
129 memcpy(output->storage(), data, size * sizeof(DataElement));
130 } else {
131 for (size_t i = 0; i < size; ++i)
Ken Rockot(use gerrit already) 2016/05/27 16:07:39 Nice, this should also be useful for things like b
yzshen1 2016/05/28 00:23:07 Done.
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 memcpy(Traits::GetData(*output), input->storage(),
102 input->size() * sizeof(DataElement)); 142 input->size() * sizeof(DataElement));
103 } 143 }
104 return true; 144 return true;
105 } 145 }
106 }; 146 };
107 147
108 // Serializes and deserializes arrays of bools. 148 // Serializes and deserializes arrays of bools.
109 template <typename MojomType, typename MaybeConstUserType> 149 template <typename MojomType,
150 typename MaybeConstUserType,
151 typename UserTypeReader>
110 struct ArraySerializer<MojomType, 152 struct ArraySerializer<MojomType,
111 MaybeConstUserType, 153 MaybeConstUserType,
154 UserTypeReader,
112 ArraySerializerType::BOOLEAN> { 155 ArraySerializerType::BOOLEAN> {
113 using UserType = typename std::remove_const<MaybeConstUserType>::type; 156 using UserType = typename std::remove_const<MaybeConstUserType>::type;
114 using Traits = ArrayTraits<UserType>; 157 using Traits = ArrayTraits<UserType>;
115 using Data = typename MojomType::Data_; 158 using Data = typename MojomType::Data_;
116 159
117 static_assert(std::is_same<bool, typename UserType::Element>::value, 160 static_assert(std::is_same<bool, typename UserType::Element>::value,
118 "Incorrect array serializer"); 161 "Incorrect array serializer");
119 162
120 static size_t GetSerializedSize(MaybeConstUserType& input, 163 static size_t GetSerializedSize(UserTypeReader* input,
121 SerializationContext* context) { 164 SerializationContext* context) {
122 return sizeof(Data) + Align((Traits::GetSize(input) + 7) / 8); 165 return sizeof(Data) + Align((input->GetSize() + 7) / 8);
123 } 166 }
124 167
125 static void SerializeElements(MaybeConstUserType& input, 168 static void SerializeElements(UserTypeReader* input,
126 Buffer* buf, 169 Buffer* buf,
127 Data* output, 170 Data* output,
128 const ArrayValidateParams* validate_params, 171 const ArrayValidateParams* validate_params,
129 SerializationContext* context) { 172 SerializationContext* context) {
130 DCHECK(!validate_params->element_is_nullable) 173 DCHECK(!validate_params->element_is_nullable)
131 << "Primitive type should be non-nullable"; 174 << "Primitive type should be non-nullable";
132 DCHECK(!validate_params->element_validate_params) 175 DCHECK(!validate_params->element_validate_params)
133 << "Primitive type should not have array validate params"; 176 << "Primitive type should not have array validate params";
134 177
135 // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy? 178 size_t size = input->GetSize();
136 size_t size = Traits::GetSize(input);
137 for (size_t i = 0; i < size; ++i) 179 for (size_t i = 0; i < size; ++i)
138 output->at(i) = Traits::GetAt(input, i); 180 output->at(i) = input->GetNext();
139 } 181 }
140 static bool DeserializeElements(Data* input, 182 static bool DeserializeElements(Data* input,
141 UserType* output, 183 UserType* output,
142 SerializationContext* context) { 184 SerializationContext* context) {
143 Traits::Resize(*output, input->size()); 185 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) 186 for (size_t i = 0; i < input->size(); ++i)
146 Traits::GetAt(*output, i) = input->at(i); 187 Traits::GetAt(*output, i) = input->at(i);
147 return true; 188 return true;
148 } 189 }
149 }; 190 };
150 191
151 // Serializes and deserializes arrays of handles. 192 // Serializes and deserializes arrays of handles.
152 template <typename MojomType, typename MaybeConstUserType> 193 template <typename MojomType,
194 typename MaybeConstUserType,
195 typename UserTypeReader>
153 struct ArraySerializer<MojomType, 196 struct ArraySerializer<MojomType,
154 MaybeConstUserType, 197 MaybeConstUserType,
198 UserTypeReader,
155 ArraySerializerType::HANDLE> { 199 ArraySerializerType::HANDLE> {
156 using UserType = typename std::remove_const<MaybeConstUserType>::type; 200 using UserType = typename std::remove_const<MaybeConstUserType>::type;
157 using Data = typename MojomType::Data_; 201 using Data = typename MojomType::Data_;
158 using Element = typename MojomType::Element; 202 using Element = typename MojomType::Element;
159 using Traits = ArrayTraits<UserType>; 203 using Traits = ArrayTraits<UserType>;
160 204
161 static_assert(std::is_same<Element, typename Traits::Element>::value, 205 static_assert(std::is_same<Element, typename Traits::Element>::value,
162 "Incorrect array serializer"); 206 "Incorrect array serializer");
163 207
164 static size_t GetSerializedSize(MaybeConstUserType& input, 208 static size_t GetSerializedSize(UserTypeReader* input,
165 SerializationContext* context) { 209 SerializationContext* context) {
166 return sizeof(Data) + 210 return sizeof(Data) +
167 Align(Traits::GetSize(input) * sizeof(typename Data::Element)); 211 Align(input->GetSize() * sizeof(typename Data::Element));
168 } 212 }
169 213
170 static void SerializeElements(MaybeConstUserType& input, 214 static void SerializeElements(UserTypeReader* input,
171 Buffer* buf, 215 Buffer* buf,
172 Data* output, 216 Data* output,
173 const ArrayValidateParams* validate_params, 217 const ArrayValidateParams* validate_params,
174 SerializationContext* context) { 218 SerializationContext* context) {
175 DCHECK(!validate_params->element_validate_params) 219 DCHECK(!validate_params->element_validate_params)
176 << "Handle type should not have array validate params"; 220 << "Handle type should not have array validate params";
177 221
178 size_t size = Traits::GetSize(input); 222 size_t size = input->GetSize();
179 for (size_t i = 0; i < size; ++i) { 223 for (size_t i = 0; i < size; ++i) {
180 // Transfer ownership of the handle. 224 // Transfer ownership of the handle.
181 output->at(i) = 225 output->at(i) = context->handles.AddHandle(input->GetNext().release());
182 context->handles.AddHandle(Traits::GetAt(input, i).release());
183 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( 226 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
184 !validate_params->element_is_nullable && !output->at(i).is_valid(), 227 !validate_params->element_is_nullable && !output->at(i).is_valid(),
185 VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE, 228 VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
186 MakeMessageWithArrayIndex( 229 MakeMessageWithArrayIndex(
187 "invalid handle in array expecting valid handles", size, i)); 230 "invalid handle in array expecting valid handles", size, i));
188 } 231 }
189 } 232 }
190 static bool DeserializeElements(Data* input, 233 static bool DeserializeElements(Data* input,
191 UserType* output, 234 UserType* output,
192 SerializationContext* context) { 235 SerializationContext* context) {
193 using HandleType = typename Element::RawHandleType; 236 using HandleType = typename Element::RawHandleType;
194 Traits::Resize(*output, input->size()); 237 Traits::Resize(*output, input->size());
195 for (size_t i = 0; i < input->size(); ++i) { 238 for (size_t i = 0; i < input->size(); ++i) {
196 Traits::GetAt(*output, i) = MakeScopedHandle( 239 Traits::GetAt(*output, i) = MakeScopedHandle(
197 HandleType(context->handles.TakeHandle(input->at(i)).value())); 240 HandleType(context->handles.TakeHandle(input->at(i)).value()));
198 } 241 }
199 return true; 242 return true;
200 } 243 }
201 }; 244 };
202 245
203 // This template must only apply to pointer mojo entity (strings, structs, 246 // This template must only apply to pointer mojo entity (strings, structs,
204 // arrays and maps). 247 // arrays and maps).
205 template <typename MojomType, typename MaybeConstUserType> 248 template <typename MojomType,
249 typename MaybeConstUserType,
250 typename UserTypeReader>
206 struct ArraySerializer<MojomType, 251 struct ArraySerializer<MojomType,
207 MaybeConstUserType, 252 MaybeConstUserType,
253 UserTypeReader,
208 ArraySerializerType::POINTER> { 254 ArraySerializerType::POINTER> {
209 using UserType = typename std::remove_const<MaybeConstUserType>::type; 255 using UserType = typename std::remove_const<MaybeConstUserType>::type;
210 using Data = typename MojomType::Data_; 256 using Data = typename MojomType::Data_;
211 using DataElement = typename Data::Element; 257 using DataElement = typename Data::Element;
212 using Element = typename MojomType::Element; 258 using Element = typename MojomType::Element;
213 using Traits = ArrayTraits<UserType>; 259 using Traits = ArrayTraits<UserType>;
214 260
215 static size_t GetSerializedSize(MaybeConstUserType& input, 261 static size_t GetSerializedSize(UserTypeReader* input,
216 SerializationContext* context) { 262 SerializationContext* context) {
217 size_t element_count = Traits::GetSize(input); 263 size_t element_count = input->GetSize();
218 size_t size = 264 size_t size =
219 sizeof(Data) + 265 sizeof(Data) +
220 element_count * 266 element_count *
221 sizeof(Pointer<typename std::remove_pointer<DataElement>::type>); 267 sizeof(Pointer<typename std::remove_pointer<DataElement>::type>);
222 for (size_t i = 0; i < element_count; ++i) 268 for (size_t i = 0; i < element_count; ++i)
223 size += PrepareToSerialize<Element>(Traits::GetAt(input, i), context); 269 size += PrepareToSerialize<Element>(input->GetNext(), context);
224 return size; 270 return size;
225 } 271 }
226 272
227 static void SerializeElements(MaybeConstUserType& input, 273 static void SerializeElements(UserTypeReader* input,
228 Buffer* buf, 274 Buffer* buf,
229 Data* output, 275 Data* output,
230 const ArrayValidateParams* validate_params, 276 const ArrayValidateParams* validate_params,
231 SerializationContext* context) { 277 SerializationContext* context) {
232 size_t size = Traits::GetSize(input); 278 size_t size = input->GetSize();
233 for (size_t i = 0; i < size; ++i) { 279 for (size_t i = 0; i < size; ++i) {
234 DataElement element; 280 DataElement element;
235 SerializeCaller<Element>::Run(Traits::GetAt(input, i), buf, &element, 281 SerializeCaller<Element>::Run(input->GetNext(), buf, &element,
236 validate_params->element_validate_params, 282 validate_params->element_validate_params,
237 context); 283 context);
238 output->at(i) = element; 284 output->at(i) = element;
239 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( 285 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
240 !validate_params->element_is_nullable && !element, 286 !validate_params->element_is_nullable && !element,
241 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, 287 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
242 MakeMessageWithArrayIndex("null in array expecting valid pointers", 288 MakeMessageWithArrayIndex("null in array expecting valid pointers",
243 size, i)); 289 size, i));
244 } 290 }
245 } 291 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 DataElement* output, 329 DataElement* output,
284 const ArrayValidateParams* validate_params, 330 const ArrayValidateParams* validate_params,
285 SerializationContext* context) { 331 SerializationContext* context) {
286 Serialize<T>(std::forward<InputElementType>(input), buf, output, 332 Serialize<T>(std::forward<InputElementType>(input), buf, output,
287 validate_params, context); 333 validate_params, context);
288 } 334 }
289 }; 335 };
290 }; 336 };
291 337
292 // Handles serialization and deserialization of arrays of unions. 338 // Handles serialization and deserialization of arrays of unions.
293 template <typename MojomType, typename MaybeConstUserType> 339 template <typename MojomType,
340 typename MaybeConstUserType,
341 typename UserTypeReader>
294 struct ArraySerializer<MojomType, 342 struct ArraySerializer<MojomType,
295 MaybeConstUserType, 343 MaybeConstUserType,
344 UserTypeReader,
296 ArraySerializerType::UNION> { 345 ArraySerializerType::UNION> {
297 using UserType = typename std::remove_const<MaybeConstUserType>::type; 346 using UserType = typename std::remove_const<MaybeConstUserType>::type;
298 using Data = typename MojomType::Data_; 347 using Data = typename MojomType::Data_;
299 using Element = typename MojomType::Element; 348 using Element = typename MojomType::Element;
300 using Traits = ArrayTraits<UserType>; 349 using Traits = ArrayTraits<UserType>;
301 350
302 static_assert(std::is_same<typename MojomType::Element, 351 static_assert(std::is_same<typename MojomType::Element,
303 typename Traits::Element>::value, 352 typename Traits::Element>::value,
304 "Incorrect array serializer"); 353 "Incorrect array serializer");
305 354
306 static size_t GetSerializedSize(MaybeConstUserType& input, 355 static size_t GetSerializedSize(UserTypeReader* input,
307 SerializationContext* context) { 356 SerializationContext* context) {
308 size_t element_count = Traits::GetSize(input); 357 size_t element_count = input->GetSize();
309 size_t size = sizeof(Data); 358 size_t size = sizeof(Data);
310 for (size_t i = 0; i < element_count; ++i) { 359 for (size_t i = 0; i < element_count; ++i) {
311 // Call with |inlined| set to false, so that it will account for both the 360 // 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. 361 // data in the union and the space in the array used to hold the union.
313 size += 362 size += PrepareToSerialize<Element>(input->GetNext(), false, context);
314 PrepareToSerialize<Element>(Traits::GetAt(input, i), false, context);
315 } 363 }
316 return size; 364 return size;
317 } 365 }
318 366
319 static void SerializeElements(MaybeConstUserType& input, 367 static void SerializeElements(UserTypeReader* input,
320 Buffer* buf, 368 Buffer* buf,
321 Data* output, 369 Data* output,
322 const ArrayValidateParams* validate_params, 370 const ArrayValidateParams* validate_params,
323 SerializationContext* context) { 371 SerializationContext* context) {
324 size_t size = Traits::GetSize(input); 372 size_t size = input->GetSize();
325 for (size_t i = 0; i < size; ++i) { 373 for (size_t i = 0; i < size; ++i) {
326 typename Data::Element* result = output->storage() + i; 374 typename Data::Element* result = output->storage() + i;
327 Serialize<Element>(Traits::GetAt(input, i), buf, &result, true, context); 375 Serialize<Element>(input->GetNext(), buf, &result, true, context);
328 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( 376 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
329 !validate_params->element_is_nullable && output->at(i).is_null(), 377 !validate_params->element_is_nullable && output->at(i).is_null(),
330 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, 378 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
331 MakeMessageWithArrayIndex("null in array expecting valid unions", 379 MakeMessageWithArrayIndex("null in array expecting valid unions",
332 size, i)); 380 size, i));
333 } 381 }
334 } 382 }
335 383
336 static bool DeserializeElements(Data* input, 384 static bool DeserializeElements(Data* input,
337 UserType* output, 385 UserType* output,
338 SerializationContext* context) { 386 SerializationContext* context) {
339 bool success = true; 387 bool success = true;
340 Traits::Resize(*output, input->size()); 388 Traits::Resize(*output, input->size());
341 for (size_t i = 0; i < input->size(); ++i) { 389 for (size_t i = 0; i < input->size(); ++i) {
342 // Note that we rely on complete deserialization taking place in order to 390 // Note that we rely on complete deserialization taking place in order to
343 // transfer ownership of all encoded handles. Therefore we don't 391 // transfer ownership of all encoded handles. Therefore we don't
344 // short-circuit on failure here. 392 // short-circuit on failure here.
345 if (!Deserialize<Element>(&input->at(i), &Traits::GetAt(*output, i), 393 if (!Deserialize<Element>(&input->at(i), &Traits::GetAt(*output, i),
346 context)) { 394 context)) {
347 success = false; 395 success = false;
348 } 396 }
349 } 397 }
350 return success; 398 return success;
351 } 399 }
352 }; 400 };
353 401
354 template <typename Element, typename MaybeConstUserType> 402 template <typename Element, typename MaybeConstUserType>
355 struct Serializer<Array<Element>, MaybeConstUserType> { 403 struct Serializer<Array<Element>, MaybeConstUserType> {
356 using UserType = typename std::remove_const<MaybeConstUserType>::type; 404 using UserType = typename std::remove_const<MaybeConstUserType>::type;
357 using Impl = ArraySerializer<Array<Element>, MaybeConstUserType>; 405 using Impl = ArraySerializer<Array<Element>,
406 MaybeConstUserType,
407 ArrayReader<MaybeConstUserType>>;
358 using Traits = ArrayTraits<UserType>; 408 using Traits = ArrayTraits<UserType>;
359 using Data = typename Array<Element>::Data_; 409 using Data = typename Array<Element>::Data_;
360 410
361 static size_t PrepareToSerialize(MaybeConstUserType& input, 411 static size_t PrepareToSerialize(MaybeConstUserType& input,
362 SerializationContext* context) { 412 SerializationContext* context) {
363 if (CallIsNullIfExists<Traits>(input)) 413 if (CallIsNullIfExists<Traits>(input))
364 return 0; 414 return 0;
365 return Impl::GetSerializedSize(input, context); 415 ArrayReader<MaybeConstUserType> reader(input);
416 return Impl::GetSerializedSize(&reader, context);
366 } 417 }
367 418
368 static void Serialize(MaybeConstUserType& input, 419 static void Serialize(MaybeConstUserType& input,
369 Buffer* buf, 420 Buffer* buf,
370 Data** output, 421 Data** output,
371 const ArrayValidateParams* validate_params, 422 const ArrayValidateParams* validate_params,
372 SerializationContext* context) { 423 SerializationContext* context) {
373 if (!CallIsNullIfExists<Traits>(input)) { 424 if (!CallIsNullIfExists<Traits>(input)) {
374 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( 425 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
375 validate_params->expected_num_elements != 0 && 426 validate_params->expected_num_elements != 0 &&
376 Traits::GetSize(input) != validate_params->expected_num_elements, 427 Traits::GetSize(input) != validate_params->expected_num_elements,
377 internal::VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER, 428 internal::VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER,
378 internal::MakeMessageWithExpectedArraySize( 429 internal::MakeMessageWithExpectedArraySize(
379 "fixed-size array has wrong number of elements", 430 "fixed-size array has wrong number of elements",
380 Traits::GetSize(input), validate_params->expected_num_elements)); 431 Traits::GetSize(input), validate_params->expected_num_elements));
381 Data* result = Data::New(Traits::GetSize(input), buf); 432 Data* result = Data::New(Traits::GetSize(input), buf);
382 if (result) 433 if (result) {
383 Impl::SerializeElements(input, buf, result, validate_params, context); 434 ArrayReader<MaybeConstUserType> reader(input);
435 Impl::SerializeElements(&reader, buf, result, validate_params, context);
436 }
384 *output = result; 437 *output = result;
385 } else { 438 } else {
386 *output = nullptr; 439 *output = nullptr;
387 } 440 }
388 } 441 }
389 442
390 static bool Deserialize(Data* input, 443 static bool Deserialize(Data* input,
391 UserType* output, 444 UserType* output,
392 SerializationContext* context) { 445 SerializationContext* context) {
393 if (!input) 446 if (!input)
394 return CallSetToNullIfExists<Traits>(output); 447 return CallSetToNullIfExists<Traits>(output);
395 return Impl::DeserializeElements(input, output, context); 448 return Impl::DeserializeElements(input, output, context);
396 } 449 }
397 }; 450 };
398 451
399 } // namespace internal 452 } // namespace internal
400 } // namespace mojo 453 } // namespace mojo
401 454
402 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_ 455 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698