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

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

Issue 2058633002: mojo::ArrayTraits: Add Support for Iterators (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased 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
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 ? ArraySerializerType::POINTER 49 ? ArraySerializerType::POINTER
50 : (IsHandle<DataElement>::value 50 : (IsHandle<DataElement>::value
51 ? ArraySerializerType::HANDLE 51 ? ArraySerializerType::HANDLE
52 : (std::is_same<Element, bool>::value 52 : (std::is_same<Element, bool>::value
53 ? ArraySerializerType::BOOLEAN 53 ? ArraySerializerType::BOOLEAN
54 : (std::is_enum<Element>::value 54 : (std::is_enum<Element>::value
55 ? ArraySerializerType::ENUM 55 ? ArraySerializerType::ENUM
56 : ArraySerializerType::POD)))); 56 : ArraySerializerType::POD))));
57 }; 57 };
58 58
59 template <
60 typename Traits,
61 typename MaybeConstUserType,
62 typename IteratorType,
63 typename std::enable_if<
64 HasGetBeginMethod<Traits, MaybeConstUserType>::value>::type* = nullptr>
65 static decltype(Traits::GetValue(std::declval<IteratorType&>())) GetNextHelper(
66 MaybeConstUserType& input,
67 IteratorType& iter) {
68 auto& value = Traits::GetValue(iter);
yzshen1 2016/06/10 16:21:32 Please update the comments in array_traits.h
Fady Samuel 2016/06/10 19:05:33 Done.
69 Traits::AdvanceIterator(iter);
70 return value;
71 }
72
73 template <
74 typename Traits,
75 typename MaybeConstUserType,
76 typename IteratorType,
77 typename std::enable_if<
78 !HasGetBeginMethod<Traits, MaybeConstUserType>::value>::type* = nullptr>
79 static decltype(Traits::GetAt(std::declval<MaybeConstUserType&>(), 0))
80 GetNextHelper(MaybeConstUserType& input, size_t& index) {
81 DCHECK_LT(index, Traits::GetSize(input));
82 return Traits::GetAt(input, index++);
83 }
84
59 // Used as the UserTypeReader template parameter of ArraySerializer. 85 // Used as the UserTypeReader template parameter of ArraySerializer.
60 template <typename MaybeConstUserType> 86 template <typename MaybeConstUserType>
61 class ArrayReader { 87 class ArrayReader {
yzshen1 2016/06/10 16:21:32 Maybe we should change this to ArrayIterator and l
Fady Samuel 2016/06/10 19:05:33 Done. I'm not sure how to get rid of GetNextHelper
62 public: 88 public:
63 using UserType = typename std::remove_const<MaybeConstUserType>::type; 89 using UserType = typename std::remove_const<MaybeConstUserType>::type;
64 using Traits = ArrayTraits<UserType>; 90 using Traits = ArrayTraits<UserType>;
91 using IteratorType = decltype(
92 CallGetBeginIfExists<Traits>(std::declval<MaybeConstUserType&>()));
65 93
66 explicit ArrayReader(MaybeConstUserType& input) : input_(input) {} 94 explicit ArrayReader(MaybeConstUserType& input)
95 : input_(input), iter_(CallGetBeginIfExists<Traits>(input)) {}
67 ~ArrayReader() {} 96 ~ArrayReader() {}
68 97
69 size_t GetSize() const { return Traits::GetSize(input_); } 98 size_t GetSize() const { return Traits::GetSize(input_); }
70 99
71 using GetNextResult = 100 decltype(GetNextHelper<Traits, MaybeConstUserType, IteratorType>(
72 decltype(Traits::GetAt(std::declval<MaybeConstUserType&>(), 0)); 101 std::declval<MaybeConstUserType&>(),
73 GetNextResult GetNext() { 102 std::declval<IteratorType&>()))
74 DCHECK_LT(index_, Traits::GetSize(input_)); 103 GetNext() {
75 return Traits::GetAt(input_, index_++); 104 return GetNextHelper<Traits, MaybeConstUserType, IteratorType>(input_,
105 iter_);
76 } 106 }
77 107
78 using GetDataIfExistsResult = decltype( 108 using GetDataIfExistsResult = decltype(
79 CallGetDataIfExists<Traits>(std::declval<MaybeConstUserType&>())); 109 CallGetDataIfExists<Traits>(std::declval<MaybeConstUserType&>()));
80 GetDataIfExistsResult GetDataIfExists() { 110 GetDataIfExistsResult GetDataIfExists() {
81 return CallGetDataIfExists<Traits>(input_); 111 return CallGetDataIfExists<Traits>(input_);
82 } 112 }
83 113
84 private: 114 private:
85 MaybeConstUserType& input_; 115 MaybeConstUserType& input_;
86 size_t index_ = 0; 116 IteratorType iter_;
87 }; 117 };
88 118
89 // ArraySerializer is also used to serialize map keys and values. Therefore, it 119 // ArraySerializer is also used to serialize map keys and values. Therefore, it
90 // has a UserTypeReader parameter which is an adaptor for reading to hide the 120 // has a UserTypeReader parameter which is an adaptor for reading to hide the
91 // difference between ArrayTraits and MapTraits. 121 // difference between ArrayTraits and MapTraits.
92 template <typename MojomType, 122 template <typename MojomType,
93 typename MaybeConstUserType, 123 typename MaybeConstUserType,
94 typename UserTypeReader, 124 typename UserTypeReader,
95 ArraySerializerType type = GetArraySerializerType<MojomType>::value> 125 ArraySerializerType type = GetArraySerializerType<MojomType>::value>
96 struct ArraySerializer; 126 struct ArraySerializer;
97 127
98 // Handles serialization and deserialization of arrays of pod types. 128 // Handles serialization and deserialization of arrays of pod types.
99 template <typename MojomType, 129 template <typename MojomType,
100 typename MaybeConstUserType, 130 typename MaybeConstUserType,
101 typename UserTypeReader> 131 typename UserTypeReader>
102 struct ArraySerializer<MojomType, 132 struct ArraySerializer<MojomType,
103 MaybeConstUserType, 133 MaybeConstUserType,
104 UserTypeReader, 134 UserTypeReader,
105 ArraySerializerType::POD> { 135 ArraySerializerType::POD> {
106 using UserType = typename std::remove_const<MaybeConstUserType>::type; 136 using UserType = typename std::remove_const<MaybeConstUserType>::type;
107 using Data = typename MojomType::Data_; 137 using Data = typename MojomType::Data_;
108 using DataElement = typename Data::Element; 138 using DataElement = typename Data::Element;
109 using Element = typename MojomType::Element; 139 using Element = typename MojomType::Element;
110 using Traits = ArrayTraits<UserType>; 140 using Traits = ArrayTraits<UserType>;
141 using IteratorType =
142 decltype(CallGetBeginIfExists<Traits>(std::declval<UserType&>()));
111 143
112 static_assert(std::is_same<Element, DataElement>::value, 144 static_assert(std::is_same<Element, DataElement>::value,
113 "Incorrect array serializer"); 145 "Incorrect array serializer");
114 static_assert(std::is_same<Element, typename Traits::Element>::value, 146 static_assert(std::is_same<Element, typename Traits::Element>::value,
115 "Incorrect array serializer"); 147 "Incorrect array serializer");
116 148
117 static size_t GetSerializedSize(UserTypeReader* input, 149 static size_t GetSerializedSize(UserTypeReader* input,
118 SerializationContext* context) { 150 SerializationContext* context) {
119 return sizeof(Data) + Align(input->GetSize() * sizeof(DataElement)); 151 return sizeof(Data) + Align(input->GetSize() * sizeof(DataElement));
120 } 152 }
(...skipping 24 matching lines...) Expand all
145 static bool DeserializeElements(Data* input, 177 static bool DeserializeElements(Data* input,
146 UserType* output, 178 UserType* output,
147 SerializationContext* context) { 179 SerializationContext* context) {
148 if (!Traits::Resize(*output, input->size())) 180 if (!Traits::Resize(*output, input->size()))
149 return false; 181 return false;
150 if (input->size()) { 182 if (input->size()) {
151 auto data = CallGetDataIfExists<Traits>(*output); 183 auto data = CallGetDataIfExists<Traits>(*output);
152 if (data) { 184 if (data) {
153 memcpy(data, input->storage(), input->size() * sizeof(DataElement)); 185 memcpy(data, input->storage(), input->size() * sizeof(DataElement));
154 } else { 186 } else {
155 for (size_t i = 0; i < input->size(); ++i) 187 IteratorType iter = CallGetBeginIfExists<Traits>(*output);
156 Traits::GetAt(*output, i) = input->at(i); 188 for (size_t i = 0; i < input->size(); ++i) {
189 GetNextHelper<Traits, MaybeConstUserType, IteratorType>(
190 *output, iter) = input->at(i);
191 }
157 } 192 }
158 } 193 }
159 return true; 194 return true;
160 } 195 }
161 }; 196 };
162 197
163 // Handles serialization and deserialization of arrays of enum types. 198 // Handles serialization and deserialization of arrays of enum types.
164 template <typename MojomType, 199 template <typename MojomType,
165 typename MaybeConstUserType, 200 typename MaybeConstUserType,
166 typename UserTypeReader> 201 typename UserTypeReader>
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 template <typename MojomType, 249 template <typename MojomType,
215 typename MaybeConstUserType, 250 typename MaybeConstUserType,
216 typename UserTypeReader> 251 typename UserTypeReader>
217 struct ArraySerializer<MojomType, 252 struct ArraySerializer<MojomType,
218 MaybeConstUserType, 253 MaybeConstUserType,
219 UserTypeReader, 254 UserTypeReader,
220 ArraySerializerType::BOOLEAN> { 255 ArraySerializerType::BOOLEAN> {
221 using UserType = typename std::remove_const<MaybeConstUserType>::type; 256 using UserType = typename std::remove_const<MaybeConstUserType>::type;
222 using Traits = ArrayTraits<UserType>; 257 using Traits = ArrayTraits<UserType>;
223 using Data = typename MojomType::Data_; 258 using Data = typename MojomType::Data_;
259 using IteratorType =
260 decltype(CallGetBeginIfExists<Traits>(std::declval<UserType&>()));
224 261
225 static_assert(std::is_same<bool, typename UserType::Element>::value, 262 static_assert(std::is_same<bool, typename UserType::Element>::value,
226 "Incorrect array serializer"); 263 "Incorrect array serializer");
227 264
228 static size_t GetSerializedSize(UserTypeReader* input, 265 static size_t GetSerializedSize(UserTypeReader* input,
229 SerializationContext* context) { 266 SerializationContext* context) {
230 return sizeof(Data) + Align((input->GetSize() + 7) / 8); 267 return sizeof(Data) + Align((input->GetSize() + 7) / 8);
231 } 268 }
232 269
233 static void SerializeElements(UserTypeReader* input, 270 static void SerializeElements(UserTypeReader* input,
234 Buffer* buf, 271 Buffer* buf,
235 Data* output, 272 Data* output,
236 const ContainerValidateParams* validate_params, 273 const ContainerValidateParams* validate_params,
237 SerializationContext* context) { 274 SerializationContext* context) {
238 DCHECK(!validate_params->element_is_nullable) 275 DCHECK(!validate_params->element_is_nullable)
239 << "Primitive type should be non-nullable"; 276 << "Primitive type should be non-nullable";
240 DCHECK(!validate_params->element_validate_params) 277 DCHECK(!validate_params->element_validate_params)
241 << "Primitive type should not have array validate params"; 278 << "Primitive type should not have array validate params";
242 279
243 size_t size = input->GetSize(); 280 size_t size = input->GetSize();
244 for (size_t i = 0; i < size; ++i) 281 for (size_t i = 0; i < size; ++i)
245 output->at(i) = input->GetNext(); 282 output->at(i) = input->GetNext();
246 } 283 }
247 static bool DeserializeElements(Data* input, 284 static bool DeserializeElements(Data* input,
248 UserType* output, 285 UserType* output,
249 SerializationContext* context) { 286 SerializationContext* context) {
250 if (!Traits::Resize(*output, input->size())) 287 if (!Traits::Resize(*output, input->size()))
251 return false; 288 return false;
252 for (size_t i = 0; i < input->size(); ++i) 289 IteratorType iter = CallGetBeginIfExists<Traits>(*output);
253 Traits::GetAt(*output, i) = input->at(i); 290 for (size_t i = 0; i < input->size(); ++i) {
291 GetNextHelper<Traits, MaybeConstUserType, IteratorType>(*output, iter) =
292 input->at(i);
293 }
254 return true; 294 return true;
255 } 295 }
256 }; 296 };
257 297
258 // Serializes and deserializes arrays of handles. 298 // Serializes and deserializes arrays of handles.
259 template <typename MojomType, 299 template <typename MojomType,
260 typename MaybeConstUserType, 300 typename MaybeConstUserType,
261 typename UserTypeReader> 301 typename UserTypeReader>
262 struct ArraySerializer<MojomType, 302 struct ArraySerializer<MojomType,
263 MaybeConstUserType, 303 MaybeConstUserType,
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 typename UserTypeReader> 357 typename UserTypeReader>
318 struct ArraySerializer<MojomType, 358 struct ArraySerializer<MojomType,
319 MaybeConstUserType, 359 MaybeConstUserType,
320 UserTypeReader, 360 UserTypeReader,
321 ArraySerializerType::POINTER> { 361 ArraySerializerType::POINTER> {
322 using UserType = typename std::remove_const<MaybeConstUserType>::type; 362 using UserType = typename std::remove_const<MaybeConstUserType>::type;
323 using Data = typename MojomType::Data_; 363 using Data = typename MojomType::Data_;
324 using DataElement = typename Data::Element; 364 using DataElement = typename Data::Element;
325 using Element = typename MojomType::Element; 365 using Element = typename MojomType::Element;
326 using Traits = ArrayTraits<UserType>; 366 using Traits = ArrayTraits<UserType>;
367 using IteratorType =
368 decltype(CallGetBeginIfExists<Traits>(std::declval<UserType&>()));
327 369
328 static size_t GetSerializedSize(UserTypeReader* input, 370 static size_t GetSerializedSize(UserTypeReader* input,
329 SerializationContext* context) { 371 SerializationContext* context) {
330 size_t element_count = input->GetSize(); 372 size_t element_count = input->GetSize();
331 size_t size = 373 size_t size =
332 sizeof(Data) + 374 sizeof(Data) +
333 element_count * 375 element_count *
334 sizeof(Pointer<typename std::remove_pointer<DataElement>::type>); 376 sizeof(Pointer<typename std::remove_pointer<DataElement>::type>);
335 for (size_t i = 0; i < element_count; ++i) 377 for (size_t i = 0; i < element_count; ++i)
336 size += PrepareToSerialize<Element>(input->GetNext(), context); 378 size += PrepareToSerialize<Element>(input->GetNext(), context);
(...skipping 18 matching lines...) Expand all
355 MakeMessageWithArrayIndex("null in array expecting valid pointers", 397 MakeMessageWithArrayIndex("null in array expecting valid pointers",
356 size, i)); 398 size, i));
357 } 399 }
358 } 400 }
359 static bool DeserializeElements(Data* input, 401 static bool DeserializeElements(Data* input,
360 UserType* output, 402 UserType* output,
361 SerializationContext* context) { 403 SerializationContext* context) {
362 bool success = true; 404 bool success = true;
363 if (!Traits::Resize(*output, input->size())) 405 if (!Traits::Resize(*output, input->size()))
364 return false; 406 return false;
407 IteratorType iter = CallGetBeginIfExists<Traits>(*output);
365 for (size_t i = 0; i < input->size(); ++i) { 408 for (size_t i = 0; i < input->size(); ++i) {
366 // Note that we rely on complete deserialization taking place in order to 409 // Note that we rely on complete deserialization taking place in order to
367 // transfer ownership of all encoded handles. Therefore we don't 410 // transfer ownership of all encoded handles. Therefore we don't
368 // short-circuit on failure here. 411 // short-circuit on failure here.
369 if (!Deserialize<Element>(input->at(i), &Traits::GetAt(*output, i), 412 if (!Deserialize<Element>(
370 context)) { 413 input->at(i),
414 &GetNextHelper<Traits, MaybeConstUserType, IteratorType>(*output,
415 iter),
416 context)) {
371 success = false; 417 success = false;
372 } 418 }
373 } 419 }
374 return success; 420 return success;
375 } 421 }
376 422
377 private: 423 private:
378 template <typename T, 424 template <typename T,
379 bool is_array_or_map = IsSpecializationOf<Array, T>::value || 425 bool is_array_or_map = IsSpecializationOf<Array, T>::value ||
380 IsSpecializationOf<Map, T>::value> 426 IsSpecializationOf<Map, T>::value>
(...skipping 27 matching lines...) Expand all
408 typename MaybeConstUserType, 454 typename MaybeConstUserType,
409 typename UserTypeReader> 455 typename UserTypeReader>
410 struct ArraySerializer<MojomType, 456 struct ArraySerializer<MojomType,
411 MaybeConstUserType, 457 MaybeConstUserType,
412 UserTypeReader, 458 UserTypeReader,
413 ArraySerializerType::UNION> { 459 ArraySerializerType::UNION> {
414 using UserType = typename std::remove_const<MaybeConstUserType>::type; 460 using UserType = typename std::remove_const<MaybeConstUserType>::type;
415 using Data = typename MojomType::Data_; 461 using Data = typename MojomType::Data_;
416 using Element = typename MojomType::Element; 462 using Element = typename MojomType::Element;
417 using Traits = ArrayTraits<UserType>; 463 using Traits = ArrayTraits<UserType>;
464 using IteratorType =
465 decltype(CallGetBeginIfExists<Traits>(std::declval<UserType&>()));
418 466
419 static_assert(std::is_same<typename MojomType::Element, 467 static_assert(std::is_same<typename MojomType::Element,
420 typename Traits::Element>::value, 468 typename Traits::Element>::value,
421 "Incorrect array serializer"); 469 "Incorrect array serializer");
422 470
423 static size_t GetSerializedSize(UserTypeReader* input, 471 static size_t GetSerializedSize(UserTypeReader* input,
424 SerializationContext* context) { 472 SerializationContext* context) {
425 size_t element_count = input->GetSize(); 473 size_t element_count = input->GetSize();
426 size_t size = sizeof(Data); 474 size_t size = sizeof(Data);
427 for (size_t i = 0; i < element_count; ++i) { 475 for (size_t i = 0; i < element_count; ++i) {
(...skipping 20 matching lines...) Expand all
448 size, i)); 496 size, i));
449 } 497 }
450 } 498 }
451 499
452 static bool DeserializeElements(Data* input, 500 static bool DeserializeElements(Data* input,
453 UserType* output, 501 UserType* output,
454 SerializationContext* context) { 502 SerializationContext* context) {
455 bool success = true; 503 bool success = true;
456 if (!Traits::Resize(*output, input->size())) 504 if (!Traits::Resize(*output, input->size()))
457 return false; 505 return false;
506 IteratorType iter = CallGetBeginIfExists<Traits>(*output);
458 for (size_t i = 0; i < input->size(); ++i) { 507 for (size_t i = 0; i < input->size(); ++i) {
459 // Note that we rely on complete deserialization taking place in order to 508 // Note that we rely on complete deserialization taking place in order to
460 // transfer ownership of all encoded handles. Therefore we don't 509 // transfer ownership of all encoded handles. Therefore we don't
461 // short-circuit on failure here. 510 // short-circuit on failure here.
462 if (!Deserialize<Element>(&input->at(i), &Traits::GetAt(*output, i), 511 if (!Deserialize<Element>(
463 context)) { 512 &input->at(i),
513 &GetNextHelper<Traits, MaybeConstUserType, IteratorType>(*output,
514 iter),
515 context)) {
464 success = false; 516 success = false;
465 } 517 }
466 } 518 }
467 return success; 519 return success;
468 } 520 }
469 }; 521 };
470 522
471 template <typename Element, typename MaybeConstUserType> 523 template <typename Element, typename MaybeConstUserType>
472 struct Serializer<Array<Element>, MaybeConstUserType> { 524 struct Serializer<Array<Element>, MaybeConstUserType> {
473 using UserType = typename std::remove_const<MaybeConstUserType>::type; 525 using UserType = typename std::remove_const<MaybeConstUserType>::type;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 if (!input) 567 if (!input)
516 return CallSetToNullIfExists<Traits>(output); 568 return CallSetToNullIfExists<Traits>(output);
517 return Impl::DeserializeElements(input, output, context); 569 return Impl::DeserializeElements(input, output, context);
518 } 570 }
519 }; 571 };
520 572
521 } // namespace internal 573 } // namespace internal
522 } // namespace mojo 574 } // namespace mojo
523 575
524 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_ 576 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_
OLDNEW
« no previous file with comments | « no previous file | mojo/public/cpp/bindings/lib/serialization_util.h » ('j') | mojo/public/cpp/bindings/lib/serialization_util.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698