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