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 { |