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

Unified Diff: mojo/public/cpp/bindings/lib/array_serialization.h

Issue 2014403002: Mojo C++ bindings: custom type mapping of map (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « mojo/public/cpp/bindings/array_traits.h ('k') | mojo/public/cpp/bindings/lib/map_internal.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 3b4033b4fdfa47cb6bd14af92f131f041cfb89e6..83d94ce1fbcd351acbac03f86271aa21dbc8277c 100644
--- a/mojo/public/cpp/bindings/lib/array_serialization.h
+++ b/mojo/public/cpp/bindings/lib/array_serialization.h
@@ -20,10 +20,6 @@
#include "mojo/public/cpp/bindings/lib/template_util.h"
#include "mojo/public/cpp/bindings/lib/validation_errors.h"
-namespace WTF {
-class String;
-}
-
namespace mojo {
namespace internal {
@@ -50,16 +46,53 @@ struct GetArraySerializerType {
: ArraySerializerType::POD)));
};
+// Used as the UserTypeReader template parameter of ArraySerializer.
+template <typename MaybeConstUserType>
+class ArrayReader {
+ public:
+ using UserType = typename std::remove_const<MaybeConstUserType>::type;
+ using Traits = ArrayTraits<UserType>;
+
+ explicit ArrayReader(MaybeConstUserType& input) : input_(input) {}
+ ~ArrayReader() {}
+
+ 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_++);
+ }
+
+ using GetDataIfExistsResult = decltype(
+ CallGetDataIfExists<Traits>(std::declval<MaybeConstUserType&>()));
+ GetDataIfExistsResult GetDataIfExists() {
+ return CallGetDataIfExists<Traits>(input_);
+ }
+
+ private:
+ MaybeConstUserType& input_;
+ size_t index_ = 0;
+};
+
+// 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
+// difference between ArrayTraits and MapTraits.
template <typename MojomType,
typename MaybeConstUserType,
+ typename UserTypeReader,
ArraySerializerType type =
GetArraySerializerType<typename MojomType::Data_::Element>::value>
struct ArraySerializer;
// Handles serialization and deserialization of arrays of pod types.
-template <typename MojomType, typename MaybeConstUserType>
+template <typename MojomType,
+ typename MaybeConstUserType,
+ typename UserTypeReader>
struct ArraySerializer<MojomType,
MaybeConstUserType,
+ UserTypeReader,
ArraySerializerType::POD> {
using UserType = typename std::remove_const<MaybeConstUserType>::type;
using Data = typename MojomType::Data_;
@@ -72,12 +105,12 @@ struct ArraySerializer<MojomType,
static_assert(std::is_same<Element, typename Traits::Element>::value,
"Incorrect array serializer");
- static size_t GetSerializedSize(MaybeConstUserType& input,
+ static size_t GetSerializedSize(UserTypeReader* input,
SerializationContext* context) {
- return sizeof(Data) + Align(Traits::GetSize(input) * sizeof(DataElement));
+ return sizeof(Data) + Align(input->GetSize() * sizeof(DataElement));
}
- static void SerializeElements(MaybeConstUserType& input,
+ static void SerializeElements(UserTypeReader* input,
Buffer* buf,
Data* output,
const ArrayValidateParams* validate_params,
@@ -87,9 +120,16 @@ struct ArraySerializer<MojomType,
DCHECK(!validate_params->element_validate_params)
<< "Primitive type should not have array validate params";
- if (Traits::GetSize(input)) {
- memcpy(output->storage(), Traits::GetData(input),
- Traits::GetSize(input) * sizeof(DataElement));
+ size_t size = input->GetSize();
+ if (size == 0)
+ return;
+
+ auto data = input->GetDataIfExists();
+ if (data) {
+ memcpy(output->storage(), data, size * sizeof(DataElement));
+ } else {
+ for (size_t i = 0; i < size; ++i)
+ output->at(i) = static_cast<DataElement>(input->GetNext());
}
}
@@ -98,17 +138,25 @@ struct ArraySerializer<MojomType,
SerializationContext* context) {
Traits::Resize(*output, input->size());
if (input->size()) {
- memcpy(Traits::GetData(*output), input->storage(),
- input->size() * sizeof(DataElement));
+ auto data = CallGetDataIfExists<Traits>(*output);
+ if (data) {
+ memcpy(data, input->storage(), input->size() * sizeof(DataElement));
+ } else {
+ for (size_t i = 0; i < input->size(); ++i)
+ Traits::GetAt(*output, i) = static_cast<Element>(input->at(i));
+ }
}
return true;
}
};
// Serializes and deserializes arrays of bools.
-template <typename MojomType, typename MaybeConstUserType>
+template <typename MojomType,
+ typename MaybeConstUserType,
+ typename UserTypeReader>
struct ArraySerializer<MojomType,
MaybeConstUserType,
+ UserTypeReader,
ArraySerializerType::BOOLEAN> {
using UserType = typename std::remove_const<MaybeConstUserType>::type;
using Traits = ArrayTraits<UserType>;
@@ -117,12 +165,12 @@ struct ArraySerializer<MojomType,
static_assert(std::is_same<bool, typename UserType::Element>::value,
"Incorrect array serializer");
- static size_t GetSerializedSize(MaybeConstUserType& input,
+ static size_t GetSerializedSize(UserTypeReader* input,
SerializationContext* context) {
- return sizeof(Data) + Align((Traits::GetSize(input) + 7) / 8);
+ return sizeof(Data) + Align((input->GetSize() + 7) / 8);
}
- static void SerializeElements(MaybeConstUserType& input,
+ static void SerializeElements(UserTypeReader* input,
Buffer* buf,
Data* output,
const ArrayValidateParams* validate_params,
@@ -132,16 +180,14 @@ struct ArraySerializer<MojomType,
DCHECK(!validate_params->element_validate_params)
<< "Primitive type should not have array validate params";
- // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy?
- size_t size = Traits::GetSize(input);
+ size_t size = input->GetSize();
for (size_t i = 0; i < size; ++i)
- output->at(i) = Traits::GetAt(input, i);
+ output->at(i) = input->GetNext();
}
static bool DeserializeElements(Data* input,
UserType* output,
SerializationContext* context) {
Traits::Resize(*output, input->size());
- // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy?
for (size_t i = 0; i < input->size(); ++i)
Traits::GetAt(*output, i) = input->at(i);
return true;
@@ -149,9 +195,12 @@ struct ArraySerializer<MojomType,
};
// Serializes and deserializes arrays of handles.
-template <typename MojomType, typename MaybeConstUserType>
+template <typename MojomType,
+ typename MaybeConstUserType,
+ typename UserTypeReader>
struct ArraySerializer<MojomType,
MaybeConstUserType,
+ UserTypeReader,
ArraySerializerType::HANDLE> {
using UserType = typename std::remove_const<MaybeConstUserType>::type;
using Data = typename MojomType::Data_;
@@ -161,13 +210,13 @@ struct ArraySerializer<MojomType,
static_assert(std::is_same<Element, typename Traits::Element>::value,
"Incorrect array serializer");
- static size_t GetSerializedSize(MaybeConstUserType& input,
+ static size_t GetSerializedSize(UserTypeReader* input,
SerializationContext* context) {
return sizeof(Data) +
- Align(Traits::GetSize(input) * sizeof(typename Data::Element));
+ Align(input->GetSize() * sizeof(typename Data::Element));
}
- static void SerializeElements(MaybeConstUserType& input,
+ static void SerializeElements(UserTypeReader* input,
Buffer* buf,
Data* output,
const ArrayValidateParams* validate_params,
@@ -175,11 +224,10 @@ struct ArraySerializer<MojomType,
DCHECK(!validate_params->element_validate_params)
<< "Handle type should not have array validate params";
- size_t size = Traits::GetSize(input);
+ size_t size = input->GetSize();
for (size_t i = 0; i < size; ++i) {
// Transfer ownership of the handle.
- output->at(i) =
- context->handles.AddHandle(Traits::GetAt(input, i).release());
+ output->at(i) = context->handles.AddHandle(input->GetNext().release());
MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
!validate_params->element_is_nullable && !output->at(i).is_valid(),
VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
@@ -202,9 +250,12 @@ struct ArraySerializer<MojomType,
// This template must only apply to pointer mojo entity (strings, structs,
// arrays and maps).
-template <typename MojomType, typename MaybeConstUserType>
+template <typename MojomType,
+ typename MaybeConstUserType,
+ typename UserTypeReader>
struct ArraySerializer<MojomType,
MaybeConstUserType,
+ UserTypeReader,
ArraySerializerType::POINTER> {
using UserType = typename std::remove_const<MaybeConstUserType>::type;
using Data = typename MojomType::Data_;
@@ -212,27 +263,27 @@ struct ArraySerializer<MojomType,
using Element = typename MojomType::Element;
using Traits = ArrayTraits<UserType>;
- static size_t GetSerializedSize(MaybeConstUserType& input,
+ static size_t GetSerializedSize(UserTypeReader* input,
SerializationContext* context) {
- size_t element_count = Traits::GetSize(input);
+ size_t element_count = input->GetSize();
size_t size =
sizeof(Data) +
element_count *
sizeof(Pointer<typename std::remove_pointer<DataElement>::type>);
for (size_t i = 0; i < element_count; ++i)
- size += PrepareToSerialize<Element>(Traits::GetAt(input, i), context);
+ size += PrepareToSerialize<Element>(input->GetNext(), context);
return size;
}
- static void SerializeElements(MaybeConstUserType& input,
+ static void SerializeElements(UserTypeReader* input,
Buffer* buf,
Data* output,
const ArrayValidateParams* validate_params,
SerializationContext* context) {
- size_t size = Traits::GetSize(input);
+ size_t size = input->GetSize();
for (size_t i = 0; i < size; ++i) {
DataElement element;
- SerializeCaller<Element>::Run(Traits::GetAt(input, i), buf, &element,
+ SerializeCaller<Element>::Run(input->GetNext(), buf, &element,
validate_params->element_validate_params,
context);
output->at(i) = element;
@@ -290,9 +341,12 @@ struct ArraySerializer<MojomType,
};
// Handles serialization and deserialization of arrays of unions.
-template <typename MojomType, typename MaybeConstUserType>
+template <typename MojomType,
+ typename MaybeConstUserType,
+ typename UserTypeReader>
struct ArraySerializer<MojomType,
MaybeConstUserType,
+ UserTypeReader,
ArraySerializerType::UNION> {
using UserType = typename std::remove_const<MaybeConstUserType>::type;
using Data = typename MojomType::Data_;
@@ -303,28 +357,27 @@ struct ArraySerializer<MojomType,
typename Traits::Element>::value,
"Incorrect array serializer");
- static size_t GetSerializedSize(MaybeConstUserType& input,
+ static size_t GetSerializedSize(UserTypeReader* input,
SerializationContext* context) {
- size_t element_count = Traits::GetSize(input);
+ size_t element_count = input->GetSize();
size_t size = sizeof(Data);
for (size_t i = 0; i < element_count; ++i) {
// Call with |inlined| set to false, so that it will account for both the
// data in the union and the space in the array used to hold the union.
- size +=
- PrepareToSerialize<Element>(Traits::GetAt(input, i), false, context);
+ size += PrepareToSerialize<Element>(input->GetNext(), false, context);
}
return size;
}
- static void SerializeElements(MaybeConstUserType& input,
+ static void SerializeElements(UserTypeReader* input,
Buffer* buf,
Data* output,
const ArrayValidateParams* validate_params,
SerializationContext* context) {
- size_t size = Traits::GetSize(input);
+ size_t size = input->GetSize();
for (size_t i = 0; i < size; ++i) {
typename Data::Element* result = output->storage() + i;
- Serialize<Element>(Traits::GetAt(input, i), buf, &result, true, context);
+ Serialize<Element>(input->GetNext(), buf, &result, true, context);
MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
!validate_params->element_is_nullable && output->at(i).is_null(),
VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
@@ -354,7 +407,9 @@ struct ArraySerializer<MojomType,
template <typename Element, typename MaybeConstUserType>
struct Serializer<Array<Element>, MaybeConstUserType> {
using UserType = typename std::remove_const<MaybeConstUserType>::type;
- using Impl = ArraySerializer<Array<Element>, MaybeConstUserType>;
+ using Impl = ArraySerializer<Array<Element>,
+ MaybeConstUserType,
+ ArrayReader<MaybeConstUserType>>;
using Traits = ArrayTraits<UserType>;
using Data = typename Array<Element>::Data_;
@@ -362,7 +417,8 @@ struct Serializer<Array<Element>, MaybeConstUserType> {
SerializationContext* context) {
if (CallIsNullIfExists<Traits>(input))
return 0;
- return Impl::GetSerializedSize(input, context);
+ ArrayReader<MaybeConstUserType> reader(input);
+ return Impl::GetSerializedSize(&reader, context);
}
static void Serialize(MaybeConstUserType& input,
@@ -379,8 +435,10 @@ struct Serializer<Array<Element>, MaybeConstUserType> {
"fixed-size array has wrong number of elements",
Traits::GetSize(input), validate_params->expected_num_elements));
Data* result = Data::New(Traits::GetSize(input), buf);
- if (result)
- Impl::SerializeElements(input, buf, result, validate_params, context);
+ if (result) {
+ ArrayReader<MaybeConstUserType> reader(input);
+ Impl::SerializeElements(&reader, buf, result, validate_params, context);
+ }
*output = result;
} else {
*output = nullptr;
« no previous file with comments | « mojo/public/cpp/bindings/array_traits.h ('k') | mojo/public/cpp/bindings/lib/map_internal.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698