Chromium Code Reviews| Index: mojo/public/cpp/bindings/lib/array_serialization.h |
| diff --git a/mojo/public/cpp/bindings/lib/array_serialization.h b/mojo/public/cpp/bindings/lib/array_serialization.h |
| index 19c3dabc84ade6b964664ff962e02898d125cd22..6c45a28f77ed85449e477e305e59cdf578f56270 100644 |
| --- a/mojo/public/cpp/bindings/lib/array_serialization.h |
| +++ b/mojo/public/cpp/bindings/lib/array_serialization.h |
| @@ -56,23 +56,58 @@ struct GetArraySerializerType { |
| : ArraySerializerType::POD)))); |
| }; |
| -// Used as the UserTypeReader template parameter of ArraySerializer. |
| -template <typename MaybeConstUserType> |
| -class ArrayReader { |
| +template <typename Traits, |
| + typename MaybeConstUserType, |
| + bool HasGetBegin = |
| + HasGetBeginMethod<Traits, MaybeConstUserType>::value> |
| +class ArrayIterator {}; |
| + |
| +// Used as the UserTypeIterator template parameter of ArraySerializer. |
| +template <typename Traits, typename MaybeConstUserType> |
| +class ArrayIterator<Traits, MaybeConstUserType, true> { |
| public: |
| - using UserType = typename std::remove_const<MaybeConstUserType>::type; |
| - using Traits = ArrayTraits<UserType>; |
| + using IteratorType = decltype( |
| + CallGetBeginIfExists<Traits>(std::declval<MaybeConstUserType&>())); |
| + |
| + explicit ArrayIterator(MaybeConstUserType& input) |
| + : input_(input), iter_(CallGetBeginIfExists<Traits>(input)) {} |
| + ~ArrayIterator() {} |
| + |
| + size_t GetSize() const { return Traits::GetSize(input_); } |
| + |
| + using GetNextResult = |
| + decltype(Traits::GetValue(std::declval<IteratorType&>())); |
| + GetNextResult GetNext() { |
| + auto& value = Traits::GetValue(iter_); |
| + Traits::AdvanceIterator(iter_); |
| + return value; |
| + } |
| + |
| + using GetDataIfExistsResult = decltype( |
| + CallGetDataIfExists<Traits>(std::declval<MaybeConstUserType&>())); |
| + GetDataIfExistsResult GetDataIfExists() { |
| + return CallGetDataIfExists<Traits>(input_); |
| + } |
| + |
| + private: |
| + MaybeConstUserType& input_; |
| + IteratorType iter_; |
| +}; |
| - explicit ArrayReader(MaybeConstUserType& input) : input_(input) {} |
| - ~ArrayReader() {} |
| +// Used as the UserTypeIterator template parameter of ArraySerializer. |
| +template <typename Traits, typename MaybeConstUserType> |
| +class ArrayIterator<Traits, MaybeConstUserType, false> { |
| + public: |
| + explicit ArrayIterator(MaybeConstUserType& input) : input_(input), iter_(0) {} |
| + ~ArrayIterator() {} |
| size_t GetSize() const { return Traits::GetSize(input_); } |
| using GetNextResult = |
| decltype(Traits::GetAt(std::declval<MaybeConstUserType&>(), 0)); |
| GetNextResult GetNext() { |
| - DCHECK_LT(index_, Traits::GetSize(input_)); |
| - return Traits::GetAt(input_, index_++); |
| + DCHECK_LT(iter_, Traits::GetSize(input_)); |
| + return Traits::GetAt(input_, iter_++); |
| } |
| using GetDataIfExistsResult = decltype( |
| @@ -83,43 +118,45 @@ class ArrayReader { |
| private: |
| MaybeConstUserType& input_; |
| - size_t index_ = 0; |
| + size_t iter_; |
| }; |
| // ArraySerializer is also used to serialize map keys and values. Therefore, it |
| -// has a UserTypeReader parameter which is an adaptor for reading to hide the |
| +// has a UserTypeIterator parameter which is an adaptor for reading to hide the |
| // difference between ArrayTraits and MapTraits. |
| template <typename MojomType, |
| typename MaybeConstUserType, |
| - typename UserTypeReader, |
| + typename UserTypeIterator, |
| ArraySerializerType type = GetArraySerializerType<MojomType>::value> |
| struct ArraySerializer; |
| // Handles serialization and deserialization of arrays of pod types. |
| template <typename MojomType, |
| typename MaybeConstUserType, |
| - typename UserTypeReader> |
| + typename UserTypeIterator> |
| struct ArraySerializer<MojomType, |
| MaybeConstUserType, |
| - UserTypeReader, |
| + UserTypeIterator, |
| ArraySerializerType::POD> { |
| using UserType = typename std::remove_const<MaybeConstUserType>::type; |
| using Data = typename MojomType::Data_; |
| using DataElement = typename Data::Element; |
| using Element = typename MojomType::Element; |
| using Traits = ArrayTraits<UserType>; |
| + using IteratorType = |
|
yzshen1
2016/06/13 15:18:05
please remove this line.
Fady Samuel
2016/06/13 15:38:11
Done.
|
| + decltype(CallGetBeginIfExists<Traits>(std::declval<UserType&>())); |
| static_assert(std::is_same<Element, DataElement>::value, |
| "Incorrect array serializer"); |
| static_assert(std::is_same<Element, typename Traits::Element>::value, |
| "Incorrect array serializer"); |
| - static size_t GetSerializedSize(UserTypeReader* input, |
| + static size_t GetSerializedSize(UserTypeIterator* input, |
| SerializationContext* context) { |
| return sizeof(Data) + Align(input->GetSize() * sizeof(DataElement)); |
| } |
| - static void SerializeElements(UserTypeReader* input, |
| + static void SerializeElements(UserTypeIterator* input, |
| Buffer* buf, |
| Data* output, |
| const ContainerValidateParams* validate_params, |
| @@ -147,13 +184,14 @@ struct ArraySerializer<MojomType, |
| SerializationContext* context) { |
| if (!Traits::Resize(*output, input->size())) |
| return false; |
| + ArrayIterator<Traits, UserType> iterator(*output); |
| if (input->size()) { |
| - auto data = CallGetDataIfExists<Traits>(*output); |
| + auto data = iterator.GetDataIfExists(); |
| if (data) { |
| memcpy(data, input->storage(), input->size() * sizeof(DataElement)); |
| } else { |
| for (size_t i = 0; i < input->size(); ++i) |
| - Traits::GetAt(*output, i) = input->at(i); |
| + iterator.GetNext() = input->at(i); |
| } |
| } |
| return true; |
| @@ -163,10 +201,10 @@ struct ArraySerializer<MojomType, |
| // Handles serialization and deserialization of arrays of enum types. |
| template <typename MojomType, |
| typename MaybeConstUserType, |
| - typename UserTypeReader> |
| + typename UserTypeIterator> |
| struct ArraySerializer<MojomType, |
| MaybeConstUserType, |
| - UserTypeReader, |
| + UserTypeIterator, |
| ArraySerializerType::ENUM> { |
| using UserType = typename std::remove_const<MaybeConstUserType>::type; |
| using Data = typename MojomType::Data_; |
| @@ -177,12 +215,12 @@ struct ArraySerializer<MojomType, |
| static_assert(sizeof(Element) == sizeof(DataElement), |
| "Incorrect array serializer"); |
| - static size_t GetSerializedSize(UserTypeReader* input, |
| + static size_t GetSerializedSize(UserTypeIterator* input, |
| SerializationContext* context) { |
| return sizeof(Data) + Align(input->GetSize() * sizeof(DataElement)); |
| } |
| - static void SerializeElements(UserTypeReader* input, |
| + static void SerializeElements(UserTypeIterator* input, |
| Buffer* buf, |
| Data* output, |
| const ContainerValidateParams* validate_params, |
| @@ -202,8 +240,9 @@ struct ArraySerializer<MojomType, |
| SerializationContext* context) { |
| if (!Traits::Resize(*output, input->size())) |
| return false; |
| + ArrayIterator<Traits, UserType> iterator(*output); |
| for (size_t i = 0; i < input->size(); ++i) { |
| - if (!Deserialize<Element>(input->at(i), &Traits::GetAt(*output, i))) |
| + if (!Deserialize<Element>(input->at(i), &iterator.GetNext())) |
| return false; |
| } |
| return true; |
| @@ -213,10 +252,10 @@ struct ArraySerializer<MojomType, |
| // Serializes and deserializes arrays of bools. |
| template <typename MojomType, |
| typename MaybeConstUserType, |
| - typename UserTypeReader> |
| + typename UserTypeIterator> |
| struct ArraySerializer<MojomType, |
| MaybeConstUserType, |
| - UserTypeReader, |
| + UserTypeIterator, |
| ArraySerializerType::BOOLEAN> { |
| using UserType = typename std::remove_const<MaybeConstUserType>::type; |
| using Traits = ArrayTraits<UserType>; |
| @@ -225,12 +264,12 @@ struct ArraySerializer<MojomType, |
| static_assert(std::is_same<bool, typename UserType::Element>::value, |
| "Incorrect array serializer"); |
| - static size_t GetSerializedSize(UserTypeReader* input, |
| + static size_t GetSerializedSize(UserTypeIterator* input, |
| SerializationContext* context) { |
| return sizeof(Data) + Align((input->GetSize() + 7) / 8); |
| } |
| - static void SerializeElements(UserTypeReader* input, |
| + static void SerializeElements(UserTypeIterator* input, |
| Buffer* buf, |
| Data* output, |
| const ContainerValidateParams* validate_params, |
| @@ -249,8 +288,9 @@ struct ArraySerializer<MojomType, |
| SerializationContext* context) { |
| if (!Traits::Resize(*output, input->size())) |
| return false; |
| + ArrayIterator<Traits, UserType> iterator(*output); |
| for (size_t i = 0; i < input->size(); ++i) |
| - Traits::GetAt(*output, i) = input->at(i); |
| + iterator.GetNext() = input->at(i); |
| return true; |
| } |
| }; |
| @@ -258,10 +298,10 @@ struct ArraySerializer<MojomType, |
| // Serializes and deserializes arrays of handles. |
| template <typename MojomType, |
| typename MaybeConstUserType, |
| - typename UserTypeReader> |
| + typename UserTypeIterator> |
| struct ArraySerializer<MojomType, |
| MaybeConstUserType, |
| - UserTypeReader, |
| + UserTypeIterator, |
| ArraySerializerType::HANDLE> { |
| using UserType = typename std::remove_const<MaybeConstUserType>::type; |
| using Data = typename MojomType::Data_; |
| @@ -271,13 +311,13 @@ struct ArraySerializer<MojomType, |
| static_assert(std::is_same<Element, typename Traits::Element>::value, |
| "Incorrect array serializer"); |
| - static size_t GetSerializedSize(UserTypeReader* input, |
| + static size_t GetSerializedSize(UserTypeIterator* input, |
| SerializationContext* context) { |
| return sizeof(Data) + |
| Align(input->GetSize() * sizeof(typename Data::Element)); |
| } |
| - static void SerializeElements(UserTypeReader* input, |
| + static void SerializeElements(UserTypeIterator* input, |
| Buffer* buf, |
| Data* output, |
| const ContainerValidateParams* validate_params, |
| @@ -302,8 +342,9 @@ struct ArraySerializer<MojomType, |
| using HandleType = typename Element::RawHandleType; |
| if (!Traits::Resize(*output, input->size())) |
| return false; |
| + ArrayIterator<Traits, UserType> iterator(*output); |
| for (size_t i = 0; i < input->size(); ++i) { |
| - Traits::GetAt(*output, i) = MakeScopedHandle( |
| + iterator.GetNext() = MakeScopedHandle( |
| HandleType(context->handles.TakeHandle(input->at(i)).value())); |
| } |
| return true; |
| @@ -314,10 +355,10 @@ struct ArraySerializer<MojomType, |
| // arrays and maps). |
| template <typename MojomType, |
| typename MaybeConstUserType, |
| - typename UserTypeReader> |
| + typename UserTypeIterator> |
| struct ArraySerializer<MojomType, |
| MaybeConstUserType, |
| - UserTypeReader, |
| + UserTypeIterator, |
| ArraySerializerType::POINTER> { |
| using UserType = typename std::remove_const<MaybeConstUserType>::type; |
| using Data = typename MojomType::Data_; |
| @@ -325,7 +366,7 @@ struct ArraySerializer<MojomType, |
| using Element = typename MojomType::Element; |
| using Traits = ArrayTraits<UserType>; |
| - static size_t GetSerializedSize(UserTypeReader* input, |
| + static size_t GetSerializedSize(UserTypeIterator* input, |
| SerializationContext* context) { |
| size_t element_count = input->GetSize(); |
| size_t size = |
| @@ -337,7 +378,7 @@ struct ArraySerializer<MojomType, |
| return size; |
| } |
| - static void SerializeElements(UserTypeReader* input, |
| + static void SerializeElements(UserTypeIterator* input, |
| Buffer* buf, |
| Data* output, |
| const ContainerValidateParams* validate_params, |
| @@ -362,12 +403,12 @@ struct ArraySerializer<MojomType, |
| bool success = true; |
| if (!Traits::Resize(*output, input->size())) |
| return false; |
| + ArrayIterator<Traits, UserType> iterator(*output); |
| for (size_t i = 0; i < input->size(); ++i) { |
| // Note that we rely on complete deserialization taking place in order to |
| // transfer ownership of all encoded handles. Therefore we don't |
| // short-circuit on failure here. |
| - if (!Deserialize<Element>(input->at(i), &Traits::GetAt(*output, i), |
| - context)) { |
| + if (!Deserialize<Element>(input->at(i), &iterator.GetNext(), context)) { |
| success = false; |
| } |
| } |
| @@ -406,10 +447,10 @@ struct ArraySerializer<MojomType, |
| // Handles serialization and deserialization of arrays of unions. |
| template <typename MojomType, |
| typename MaybeConstUserType, |
| - typename UserTypeReader> |
| + typename UserTypeIterator> |
| struct ArraySerializer<MojomType, |
| MaybeConstUserType, |
| - UserTypeReader, |
| + UserTypeIterator, |
| ArraySerializerType::UNION> { |
| using UserType = typename std::remove_const<MaybeConstUserType>::type; |
| using Data = typename MojomType::Data_; |
| @@ -420,7 +461,7 @@ struct ArraySerializer<MojomType, |
| typename Traits::Element>::value, |
| "Incorrect array serializer"); |
| - static size_t GetSerializedSize(UserTypeReader* input, |
| + static size_t GetSerializedSize(UserTypeIterator* input, |
| SerializationContext* context) { |
| size_t element_count = input->GetSize(); |
| size_t size = sizeof(Data); |
| @@ -432,7 +473,7 @@ struct ArraySerializer<MojomType, |
| return size; |
| } |
| - static void SerializeElements(UserTypeReader* input, |
| + static void SerializeElements(UserTypeIterator* input, |
| Buffer* buf, |
| Data* output, |
| const ContainerValidateParams* validate_params, |
| @@ -455,12 +496,12 @@ struct ArraySerializer<MojomType, |
| bool success = true; |
| if (!Traits::Resize(*output, input->size())) |
| return false; |
| + ArrayIterator<Traits, UserType> iterator(*output); |
| for (size_t i = 0; i < input->size(); ++i) { |
| // Note that we rely on complete deserialization taking place in order to |
| // transfer ownership of all encoded handles. Therefore we don't |
| // short-circuit on failure here. |
| - if (!Deserialize<Element>(&input->at(i), &Traits::GetAt(*output, i), |
| - context)) { |
| + if (!Deserialize<Element>(&input->at(i), &iterator.GetNext(), context)) { |
| success = false; |
| } |
| } |
| @@ -471,18 +512,18 @@ struct ArraySerializer<MojomType, |
| template <typename Element, typename MaybeConstUserType> |
| struct Serializer<Array<Element>, MaybeConstUserType> { |
| using UserType = typename std::remove_const<MaybeConstUserType>::type; |
| + using Traits = ArrayTraits<UserType>; |
| using Impl = ArraySerializer<Array<Element>, |
| MaybeConstUserType, |
| - ArrayReader<MaybeConstUserType>>; |
| - using Traits = ArrayTraits<UserType>; |
| + ArrayIterator<Traits, MaybeConstUserType>>; |
| using Data = typename Array<Element>::Data_; |
| static size_t PrepareToSerialize(MaybeConstUserType& input, |
| SerializationContext* context) { |
| if (CallIsNullIfExists<Traits>(input)) |
| return 0; |
| - ArrayReader<MaybeConstUserType> reader(input); |
| - return Impl::GetSerializedSize(&reader, context); |
| + ArrayIterator<Traits, MaybeConstUserType> iterator(input); |
| + return Impl::GetSerializedSize(&iterator, context); |
| } |
| static void Serialize(MaybeConstUserType& input, |
| @@ -500,8 +541,9 @@ struct Serializer<Array<Element>, MaybeConstUserType> { |
| Traits::GetSize(input), validate_params->expected_num_elements)); |
| Data* result = Data::New(Traits::GetSize(input), buf); |
| if (result) { |
| - ArrayReader<MaybeConstUserType> reader(input); |
| - Impl::SerializeElements(&reader, buf, result, validate_params, context); |
| + ArrayIterator<Traits, MaybeConstUserType> iterator(input); |
| + Impl::SerializeElements(&iterator, buf, result, validate_params, |
| + context); |
| } |
| *output = result; |
| } else { |