Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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_ |
| OLD | NEW |