| 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..687c35e4c4b60b20893f8531e7c5d9eb8e846eb1 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,25 +118,25 @@ 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_;
|
| @@ -114,12 +149,12 @@ 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(DataElement));
|
| }
|
|
|
| - static void SerializeElements(UserTypeReader* input,
|
| + static void SerializeElements(UserTypeIterator* input,
|
| Buffer* buf,
|
| Data* output,
|
| const ContainerValidateParams* validate_params,
|
| @@ -147,13 +182,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 +199,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 +213,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 +238,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 +250,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 +262,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 +286,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 +296,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 +309,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 +340,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 +353,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 +364,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 +376,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 +401,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 +445,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 +459,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 +471,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 +494,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 +510,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 +539,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 {
|
|
|