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

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

Issue 1953493002: Mojo C++ bindings: custom type mapping for array - part 2 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@21_simplify
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
Index: mojo/public/cpp/bindings/lib/array_serialization_traits.h
diff --git a/mojo/public/cpp/bindings/lib/array_serialization_traits.h b/mojo/public/cpp/bindings/lib/array_serialization_traits.h
deleted file mode 100644
index 88d69fb19c2e016286f7b7a7f731de61987cefdf..0000000000000000000000000000000000000000
--- a/mojo/public/cpp/bindings/lib/array_serialization_traits.h
+++ /dev/null
@@ -1,522 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_TRAITS_H_
-#define MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_TRAITS_H_
-
-#include <stddef.h>
-#include <string.h> // For |memcpy()|.
-
-#include <limits>
-#include <type_traits>
-#include <utility>
-#include <vector>
-
-#include "base/logging.h"
-#include "mojo/public/cpp/bindings/lib/array_internal.h"
-#include "mojo/public/cpp/bindings/lib/serialization_forward.h"
-#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 {
-
-enum class ArraySerializerType {
- BOOLEAN,
- // Except boolean.
- POD,
- HANDLE,
- POINTER,
- UNION
-};
-
-template <typename T>
-struct GetArraySerializerType {
- static const ArraySerializerType value =
- IsUnionDataType<T>::value
- ? ArraySerializerType::UNION
- : (std::is_pointer<T>::value
- ? ArraySerializerType::POINTER
- : (IsHandle<T>::value ? ArraySerializerType::HANDLE
- : (std::is_same<T, bool>::value
- ? ArraySerializerType::BOOLEAN
- : ArraySerializerType::POD)));
-};
-
-template <typename MojomType,
- typename UserType,
- ArraySerializerType type =
- GetArraySerializerType<typename MojomType::Data_::Element>::value>
-struct ArraySerializer;
-
-// Handles serialization and deserialization of arrays of pod types.
-template <typename MojomType, typename UserType>
-struct ArraySerializer<MojomType, UserType, ArraySerializerType::POD> {
- using Data = typename MojomType::Data_;
- using DataElement = typename Data::Element;
- using Element = typename MojomType::Element;
- using Traits = ArrayTraits<UserType>;
- using UserElement = typename Traits::Element;
-
- static_assert(sizeof(Element) == sizeof(DataElement),
- "Incorrect array serializer");
- static_assert(std::is_same<Element, UserElement>::value,
- "Incorrect array serializer");
-
- static size_t GetSerializedSize(const UserType& input,
- SerializationContext* context) {
- return sizeof(Data) + Align(Traits::GetSize(input) * sizeof(DataElement));
- }
-
- static void SerializeElements(UserType input,
- Buffer* buf,
- Data* output,
- const ArrayValidateParams* validate_params,
- SerializationContext* context) {
- DCHECK(!validate_params->element_is_nullable)
- << "Primitive type should be non-nullable";
- 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));
- }
- }
-
- static bool DeserializeElements(Data* input,
- UserType* output,
- SerializationContext* context) {
- Traits::Resize(*output, input->size());
- if (input->size()) {
- memcpy(Traits::GetData(*output), input->storage(),
- input->size() * sizeof(DataElement));
- }
- return true;
- }
-};
-
-// Serializes and deserializes arrays of bools.
-template <typename MojomType, typename UserType>
-struct ArraySerializer<MojomType, UserType, ArraySerializerType::BOOLEAN> {
- using Traits = ArrayTraits<UserType>;
- using Data = typename MojomType::Data_;
-
- static_assert(std::is_same<bool, typename UserType::Element>::value,
- "Incorrect array serializer");
-
- static size_t GetSerializedSize(const UserType& input,
- SerializationContext* context) {
- return sizeof(Data) + Align((Traits::GetSize(input) + 7) / 8);
- }
-
- static void SerializeElements(UserType input,
- Buffer* buf,
- Data* output,
- const ArrayValidateParams* validate_params,
- SerializationContext* context) {
- DCHECK(!validate_params->element_is_nullable)
- << "Primitive type should be non-nullable";
- 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);
- for (size_t i = 0; i < size; ++i)
- output->at(i) = Traits::GetAt(input, i);
- }
- 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;
- }
-};
-
-// Serializes and deserializes arrays of handles.
-template <typename MojomType, typename UserType>
-struct ArraySerializer<MojomType, UserType, ArraySerializerType::HANDLE> {
- using Data = typename MojomType::Data_;
- using DataElement = typename Data::Element;
- using Element = typename MojomType::Element;
- using Traits = ArrayTraits<UserType>;
- using UserElement = typename Traits::Element;
-
- static_assert(std::is_same<Element, UserElement>::value,
- "Incorrect array serializer");
-
- static size_t GetSerializedSize(const UserType& input,
- SerializationContext* context) {
- return sizeof(Data) + Align(Traits::GetSize(input) * sizeof(DataElement));
- }
-
- static void SerializeElements(UserType input,
- Buffer* buf,
- Data* output,
- const ArrayValidateParams* validate_params,
- SerializationContext* context) {
- DCHECK(!validate_params->element_validate_params)
- << "Handle type should not have array validate params";
-
- size_t size = Traits::GetSize(input);
- for (size_t i = 0; i < size; ++i) {
- // Transfer ownership of the handle.
- output->at(i) =
- context->handles.AddHandle(Traits::GetAt(input, i).release());
- MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
- !validate_params->element_is_nullable && !output->at(i).is_valid(),
- VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
- MakeMessageWithArrayIndex(
- "invalid handle in array expecting valid handles", size, i));
- }
- }
- static bool DeserializeElements(Data* input,
- UserType* output,
- SerializationContext* context) {
- using HandleType = typename Element::RawHandleType;
- Traits::Resize(*output, input->size());
- for (size_t i = 0; i < input->size(); ++i) {
- Traits::GetAt(*output, i) = MakeScopedHandle(HandleType(
- context->handles.TakeHandle(input->at(i)).value()));
- }
- return true;
- }
-};
-
-// This template must only apply to pointer mojo entity (strings, structs,
-// arrays and maps).
-template <typename MojomType, typename UserType>
-struct ArraySerializer<MojomType, UserType, ArraySerializerType::POINTER> {
- using Data = typename MojomType::Data_;
- using DataElement = typename Data::Element;
- using Element = typename MojomType::Element;
- using Traits = ArrayTraits<UserType>;
- using UserElement = typename Traits::Element;
-
- static size_t GetSerializedSize(const UserType& input,
- SerializationContext* context) {
- size_t element_count = Traits::GetSize(input);
- 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 += GetSerializedSize_(Traits::GetAt(input, i), context);
- return size;
- }
-
- static void SerializeElements(UserType input,
- Buffer* buf,
- Data* output,
- const ArrayValidateParams* validate_params,
- SerializationContext* context) {
- size_t size = Traits::GetSize(input);
- for (size_t i = 0; i < size; ++i) {
- DataElement element;
- SerializeCaller<Element>::Run(
- std::move(Traits::GetAt(input, i)), buf, &element,
- validate_params->element_validate_params, context);
- output->at(i) = element;
- MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
- !validate_params->element_is_nullable && !element,
- VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
- MakeMessageWithArrayIndex("null in array expecting valid pointers",
- size, i));
- }
- }
- static bool DeserializeElements(Data* input,
- UserType* output,
- SerializationContext* context) {
- bool success = true;
- Traits::Resize(*output, input->size());
- 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_(input->at(i), &Traits::GetAt(*output, i), context))
- success = false;
- }
- return success;
- }
-
- private:
- template <typename T,
- bool is_array = IsSpecializationOf<Array, T>::value ||
- IsSpecializationOf<WTFArray, T>::value,
- bool is_string = std::is_same<T, String>::value ||
- std::is_same<T, WTF::String>::value>
- struct SerializeCaller {
- static void Run(T input,
- Buffer* buf,
- DataElement* output,
- const ArrayValidateParams* validate_params,
- SerializationContext* context) {
- DCHECK(!validate_params)
- << "Struct type should not have array validate params";
-
- Serialize_(std::move(input), buf, output, context);
- }
- };
-
- template <typename T>
- struct SerializeCaller<T, true, false> {
- static void Run(T input,
- Buffer* buf,
- DataElement* output,
- const ArrayValidateParams* validate_params,
- SerializationContext* context) {
- SerializeArray_(std::move(input), buf, output, validate_params, context);
- }
- };
-
- template <typename T, typename U>
- struct SerializeCaller<Map<T, U>, false, false> {
- static void Run(Map<T, U> input,
- Buffer* buf,
- DataElement* output,
- const ArrayValidateParams* validate_params,
- SerializationContext* context) {
- SerializeMap_(std::move(input), buf, output, validate_params, context);
- }
- };
-
- template <typename T>
- struct SerializeCaller<T, false, true> {
- static void Run(const T& input,
- Buffer* buf,
- DataElement* output,
- const ArrayValidateParams* validate_params,
- SerializationContext* context) {
- DCHECK(validate_params && !validate_params->element_validate_params &&
- !validate_params->element_is_nullable &&
- validate_params->expected_num_elements == 0)
- << "String type has unexpected array validate params";
-
- Serialize_(input, buf, output, context);
- }
- };
-};
-
-// Handles serialization and deserialization of arrays of unions.
-template <typename MojomType, typename UserType>
-struct ArraySerializer<MojomType, UserType, ArraySerializerType::UNION> {
- using Data = typename MojomType::Data_;
- using DataElement = typename Data::Element;
- using Element = typename MojomType::Element;
- using Traits = ArrayTraits<UserType>;
- using UserElement = typename Traits::Element;
-
- static_assert(std::is_same<Element, UserElement>::value,
- "Incorrect array serializer");
-
- static size_t GetSerializedSize(const UserType& input,
- SerializationContext* context) {
- size_t element_count = Traits::GetSize(input);
- size_t size = sizeof(Data);
- for (size_t i = 0; i < element_count; ++i) {
- // Call GetSerializedSize_ 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 += GetSerializedSize_(Traits::GetAt(input, i), false, context);
- }
- return size;
- }
-
- static void SerializeElements(UserType input,
- Buffer* buf,
- Data* output,
- const ArrayValidateParams* validate_params,
- SerializationContext* context) {
- size_t size = Traits::GetSize(input);
- for (size_t i = 0; i < size; ++i) {
- DataElement* result = output->storage() + i;
- SerializeUnion_(std::move(Traits::GetAt(input, i)), buf, &result, true,
- context);
- MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
- !validate_params->element_is_nullable && output->at(i).is_null(),
- VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
- MakeMessageWithArrayIndex("null in array expecting valid unions",
- size, i));
- }
- }
-
- static bool DeserializeElements(Data* input,
- UserType* output,
- SerializationContext* context) {
- bool success = true;
- Traits::Resize(*output, input->size());
- 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_(&input->at(i), &Traits::GetAt(*output, i), context))
- success = false;
- }
- return success;
- }
-};
-
-// Another layer of abstraction to switch between standard mojom type
-// serializers and native-only serializers.
-template <typename MojomType,
- typename UserType,
- bool use_native =
- ShouldUseNativeSerializer<typename MojomType::Element>::value>
-struct ArraySerializationStrategy;
-
-// Serialization strategy for standard mojom types. This branches further
-// by choosing an ArraySerializer specialization from above.
-template <typename MojomType, typename UserType>
-struct ArraySerializationStrategy<MojomType, UserType, false> {
- using Serializer = ArraySerializer<MojomType, UserType>;
- using Traits = ArrayTraits<UserType>;
- using Data = typename MojomType::Data_;
-
- static size_t GetSerializedSize(const UserType& input,
- SerializationContext* context) {
- DCHECK(!Traits::IsNull(input));
- return Serializer::GetSerializedSize(input, context);
- }
-
- static void Serialize(UserType input,
- Buffer* buf,
- Data** output,
- const ArrayValidateParams* validate_params,
- SerializationContext* context) {
- DCHECK(!Traits::IsNull(input));
- Data* result = Data::New(Traits::GetSize(input), buf);
- if (result) {
- Serializer::SerializeElements(std::move(input), buf, result,
- validate_params, context);
- }
- *output = result;
- }
-
- static bool Deserialize(Data* input,
- UserType* output,
- SerializationContext* context) {
- DCHECK(input);
- return Serializer::DeserializeElements(input, output, context);
- }
-};
-
-// Serialization for arrays of native-only types, which are opaquely serialized
-// as arrays of uint8_t arrays.
-template <typename MojomType, typename UserType>
-struct ArraySerializationStrategy<MojomType, UserType, true> {
- using Traits = ArrayTraits<UserType>;
- using Data = typename MojomType::Data_;
- using Element = typename MojomType::Element;
-
- static_assert(
- std::is_same<Data, Array_Data<NativeStruct_Data*>>::value,
- "Mismatched types for serializing array of native-only structs.");
-
- static size_t GetSerializedSize(const UserType& input,
- SerializationContext* context) {
- DCHECK(!Traits::IsNull(input));
-
- size_t element_count = Traits::GetSize(input);
- DCHECK_LE(element_count, std::numeric_limits<uint32_t>::max());
- size_t size = ArrayDataTraits<NativeStruct_Data*>::GetStorageSize(
- static_cast<uint32_t>(element_count));
- for (size_t i = 0; i < element_count; ++i) {
- size_t element_size =
- PrepareToSerialize<NativeStructPtr>(Traits::GetAt(input, i), context);
- DCHECK_LT(element_size, std::numeric_limits<uint32_t>::max());
- size += static_cast<uint32_t>(element_size);
- }
- return size;
- }
-
- static void Serialize(UserType input,
- Buffer* buf,
- Data** output,
- const ArrayValidateParams* validate_params,
- SerializationContext* context) {
- DCHECK(!Traits::IsNull(input));
- DCHECK(validate_params);
- // TODO(rockot): We may want to support nullable (i.e. std::unique_ptr<T>)
- // elements here.
- DCHECK(!validate_params->element_is_nullable);
- size_t element_count = Traits::GetSize(input);
- Data* result = Data::New(element_count, buf);
- for (size_t i = 0; i < element_count; ++i)
- internal::Serialize<NativeStructPtr>(Traits::GetAt(input, i), buf,
- &result->at(i), context);
- *output = result;
- }
-
- static bool Deserialize(Data* input,
- UserType* output,
- SerializationContext* context) {
- DCHECK(input);
-
- Traits::Resize(*output, input->size());
- bool success = true;
- for (size_t i = 0; i < input->size(); ++i) {
- // We don't short-circuit on failure since we can't know what the native
- // type's ParamTraits' expectations are.
- if (!internal::Deserialize<NativeStructPtr>(
- input->at(i), &Traits::GetAt(*output, i), context))
- success = false;
- }
- return success;
- }
-};
-
-template <typename MojomType, typename UserType>
-struct ArraySerializationImpl {
- using Traits = ArrayTraits<UserType>;
- using Strategy = ArraySerializationStrategy<MojomType, UserType>;
-
- static size_t GetSerializedSize(const UserType& input,
- SerializationContext* context) {
- if (Traits::IsNull(input))
- return 0;
- return Strategy::GetSerializedSize(input, context);
- }
-
- static void Serialize(UserType input,
- internal::Buffer* buf,
- typename MojomType::Data_** output,
- const internal::ArrayValidateParams* validate_params,
- SerializationContext* context) {
- if (!Traits::IsNull(input)) {
- MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
- validate_params->expected_num_elements != 0 &&
- Traits::GetSize(input) != validate_params->expected_num_elements,
- internal::VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER,
- internal::MakeMessageWithExpectedArraySize(
- "fixed-size array has wrong number of elements",
- Traits::GetSize(input), validate_params->expected_num_elements));
- Strategy::Serialize(std::move(input), buf, output, validate_params,
- context);
- } else {
- *output = nullptr;
- }
- }
-
- static bool Deserialize(typename MojomType::Data_* input,
- UserType* output,
- internal::SerializationContext* context) {
- if (input)
- return Strategy::Deserialize(input, output, context);
- Traits::SetToNull(*output);
- return true;
- }
-};
-
-} // namespace internal
-
-} // namespace mojo
-
-#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_TRAITS_H_
« no previous file with comments | « mojo/public/cpp/bindings/lib/array_serialization.h ('k') | mojo/public/cpp/bindings/lib/map_serialization.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698