aboutsummaryrefslogtreecommitdiff
path: root/mojo/public/cpp/bindings/lib/array_internal.h
diff options
context:
space:
mode:
Diffstat (limited to 'mojo/public/cpp/bindings/lib/array_internal.h')
-rw-r--r--mojo/public/cpp/bindings/lib/array_internal.h368
1 files changed, 0 insertions, 368 deletions
diff --git a/mojo/public/cpp/bindings/lib/array_internal.h b/mojo/public/cpp/bindings/lib/array_internal.h
deleted file mode 100644
index eecfcfb..0000000
--- a/mojo/public/cpp/bindings/lib/array_internal.h
+++ /dev/null
@@ -1,368 +0,0 @@
-// Copyright 2013 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_INTERNAL_H_
-#define MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <limits>
-#include <new>
-
-#include "base/logging.h"
-#include "mojo/public/c/system/macros.h"
-#include "mojo/public/cpp/bindings/bindings_export.h"
-#include "mojo/public/cpp/bindings/lib/bindings_internal.h"
-#include "mojo/public/cpp/bindings/lib/buffer.h"
-#include "mojo/public/cpp/bindings/lib/serialization_util.h"
-#include "mojo/public/cpp/bindings/lib/template_util.h"
-#include "mojo/public/cpp/bindings/lib/validate_params.h"
-#include "mojo/public/cpp/bindings/lib/validation_context.h"
-#include "mojo/public/cpp/bindings/lib/validation_errors.h"
-#include "mojo/public/cpp/bindings/lib/validation_util.h"
-
-namespace mojo {
-namespace internal {
-
-template <typename K, typename V>
-class Map_Data;
-
-MOJO_CPP_BINDINGS_EXPORT std::string
-MakeMessageWithArrayIndex(const char* message, size_t size, size_t index);
-
-MOJO_CPP_BINDINGS_EXPORT std::string MakeMessageWithExpectedArraySize(
- const char* message,
- size_t size,
- size_t expected_size);
-
-template <typename T>
-struct ArrayDataTraits {
- using StorageType = T;
- using Ref = T&;
- using ConstRef = const T&;
-
- static const uint32_t kMaxNumElements =
- (std::numeric_limits<uint32_t>::max() - sizeof(ArrayHeader)) /
- sizeof(StorageType);
-
- static uint32_t GetStorageSize(uint32_t num_elements) {
- DCHECK(num_elements <= kMaxNumElements);
- return sizeof(ArrayHeader) + sizeof(StorageType) * num_elements;
- }
- static Ref ToRef(StorageType* storage, size_t offset) {
- return storage[offset];
- }
- static ConstRef ToConstRef(const StorageType* storage, size_t offset) {
- return storage[offset];
- }
-};
-
-// Specialization of Arrays for bools, optimized for space. It has the
-// following differences from a generalized Array:
-// * Each element takes up a single bit of memory.
-// * Accessing a non-const single element uses a helper class |BitRef|, which
-// emulates a reference to a bool.
-template <>
-struct ArrayDataTraits<bool> {
- // Helper class to emulate a reference to a bool, used for direct element
- // access.
- class MOJO_CPP_BINDINGS_EXPORT BitRef {
- public:
- ~BitRef();
- BitRef& operator=(bool value);
- BitRef& operator=(const BitRef& value);
- operator bool() const;
-
- private:
- friend struct ArrayDataTraits<bool>;
- BitRef(uint8_t* storage, uint8_t mask);
- BitRef();
- uint8_t* storage_;
- uint8_t mask_;
- };
-
- // Because each element consumes only 1/8 byte.
- static const uint32_t kMaxNumElements = std::numeric_limits<uint32_t>::max();
-
- using StorageType = uint8_t;
- using Ref = BitRef;
- using ConstRef = bool;
-
- static uint32_t GetStorageSize(uint32_t num_elements) {
- return sizeof(ArrayHeader) + ((num_elements + 7) / 8);
- }
- static BitRef ToRef(StorageType* storage, size_t offset) {
- return BitRef(&storage[offset / 8], 1 << (offset % 8));
- }
- static bool ToConstRef(const StorageType* storage, size_t offset) {
- return (storage[offset / 8] & (1 << (offset % 8))) != 0;
- }
-};
-
-// What follows is code to support the serialization/validation of
-// Array_Data<T>. There are four interesting cases: arrays of primitives,
-// arrays of handles/interfaces, arrays of objects and arrays of unions.
-// Arrays of objects are represented as arrays of pointers to objects. Arrays
-// of unions are inlined so they are not pointers, but comparing with primitives
-// they require more work for serialization/validation.
-//
-// TODO(yzshen): Validation code should be organzied in a way similar to
-// Serializer<>, or merged into it. It should be templatized with the mojo
-// data view type instead of the data type, that way we can use MojomTypeTraits
-// to determine the categories.
-
-template <typename T, bool is_union, bool is_handle_or_interface>
-struct ArraySerializationHelper;
-
-template <typename T>
-struct ArraySerializationHelper<T, false, false> {
- using ElementType = typename ArrayDataTraits<T>::StorageType;
-
- static bool ValidateElements(const ArrayHeader* header,
- const ElementType* elements,
- ValidationContext* validation_context,
- const ContainerValidateParams* validate_params) {
- 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 (!validate_params->validate_enum_func)
- return true;
-
- // Enum validation.
- for (uint32_t i = 0; i < header->num_elements; ++i) {
- if (!validate_params->validate_enum_func(elements[i], validation_context))
- return false;
- }
- return true;
- }
-};
-
-template <typename T>
-struct ArraySerializationHelper<T, false, true> {
- using ElementType = typename ArrayDataTraits<T>::StorageType;
-
- static bool ValidateElements(const ArrayHeader* header,
- const ElementType* elements,
- ValidationContext* validation_context,
- const ContainerValidateParams* validate_params) {
- DCHECK(!validate_params->element_validate_params)
- << "Handle or interface type should not have array validate params";
-
- for (uint32_t i = 0; i < header->num_elements; ++i) {
- if (!validate_params->element_is_nullable &&
- !IsHandleOrInterfaceValid(elements[i])) {
- static const ValidationError kError =
- std::is_same<T, Interface_Data>::value ||
- std::is_same<T, Handle_Data>::value
- ? VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE
- : VALIDATION_ERROR_UNEXPECTED_INVALID_INTERFACE_ID;
- ReportValidationError(
- validation_context, kError,
- MakeMessageWithArrayIndex(
- "invalid handle or interface ID in array expecting valid "
- "handles or interface IDs",
- header->num_elements, i)
- .c_str());
- return false;
- }
- if (!ValidateHandleOrInterface(elements[i], validation_context))
- return false;
- }
- return true;
- }
-};
-
-template <typename T>
-struct ArraySerializationHelper<Pointer<T>, false, false> {
- using ElementType = typename ArrayDataTraits<Pointer<T>>::StorageType;
-
- static bool ValidateElements(const ArrayHeader* header,
- const ElementType* elements,
- ValidationContext* validation_context,
- const ContainerValidateParams* validate_params) {
- for (uint32_t i = 0; i < header->num_elements; ++i) {
- if (!validate_params->element_is_nullable && !elements[i].offset) {
- ReportValidationError(
- validation_context,
- VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
- MakeMessageWithArrayIndex("null in array expecting valid pointers",
- header->num_elements,
- i).c_str());
- return false;
- }
- if (!ValidateCaller<T>::Run(elements[i], validation_context,
- validate_params->element_validate_params)) {
- return false;
- }
- }
- return true;
- }
-
- private:
- template <typename U,
- bool is_array_or_map = IsSpecializationOf<Array_Data, U>::value ||
- IsSpecializationOf<Map_Data, U>::value>
- struct ValidateCaller {
- static bool Run(const Pointer<U>& data,
- ValidationContext* validation_context,
- const ContainerValidateParams* validate_params) {
- DCHECK(!validate_params)
- << "Struct type should not have array validate params";
-
- return ValidateStruct(data, validation_context);
- }
- };
-
- template <typename U>
- struct ValidateCaller<U, true> {
- static bool Run(const Pointer<U>& data,
- ValidationContext* validation_context,
- const ContainerValidateParams* validate_params) {
- return ValidateContainer(data, validation_context, validate_params);
- }
- };
-};
-
-template <typename U>
-struct ArraySerializationHelper<U, true, false> {
- using ElementType = typename ArrayDataTraits<U>::StorageType;
-
- static bool ValidateElements(const ArrayHeader* header,
- const ElementType* elements,
- ValidationContext* validation_context,
- const ContainerValidateParams* validate_params) {
- for (uint32_t i = 0; i < header->num_elements; ++i) {
- if (!validate_params->element_is_nullable && elements[i].is_null()) {
- ReportValidationError(
- validation_context,
- VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
- MakeMessageWithArrayIndex("null in array expecting valid unions",
- header->num_elements, i)
- .c_str());
- return false;
- }
- if (!ValidateInlinedUnion(elements[i], validation_context))
- return false;
- }
- return true;
- }
-};
-
-template <typename T>
-class Array_Data {
- public:
- using Traits = ArrayDataTraits<T>;
- using StorageType = typename Traits::StorageType;
- using Ref = typename Traits::Ref;
- using ConstRef = typename Traits::ConstRef;
- using Helper = ArraySerializationHelper<
- T,
- IsUnionDataType<T>::value,
- std::is_same<T, AssociatedInterface_Data>::value ||
- std::is_same<T, AssociatedEndpointHandle_Data>::value ||
- std::is_same<T, Interface_Data>::value ||
- std::is_same<T, Handle_Data>::value>;
- using Element = T;
-
- // Returns null if |num_elements| or the corresponding storage size cannot be
- // stored in uint32_t.
- static Array_Data<T>* New(size_t num_elements, Buffer* buf) {
- if (num_elements > Traits::kMaxNumElements)
- return nullptr;
-
- uint32_t num_bytes =
- Traits::GetStorageSize(static_cast<uint32_t>(num_elements));
- return new (buf->Allocate(num_bytes))
- Array_Data<T>(num_bytes, static_cast<uint32_t>(num_elements));
- }
-
- static bool Validate(const void* data,
- ValidationContext* validation_context,
- const ContainerValidateParams* validate_params) {
- if (!data)
- return true;
- if (!IsAligned(data)) {
- ReportValidationError(validation_context,
- VALIDATION_ERROR_MISALIGNED_OBJECT);
- return false;
- }
- if (!validation_context->IsValidRange(data, sizeof(ArrayHeader))) {
- ReportValidationError(validation_context,
- VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE);
- return false;
- }
- const ArrayHeader* header = static_cast<const ArrayHeader*>(data);
- if (header->num_elements > Traits::kMaxNumElements ||
- header->num_bytes < Traits::GetStorageSize(header->num_elements)) {
- ReportValidationError(validation_context,
- VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER);
- return false;
- }
- if (validate_params->expected_num_elements != 0 &&
- header->num_elements != validate_params->expected_num_elements) {
- ReportValidationError(
- validation_context,
- VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER,
- MakeMessageWithExpectedArraySize(
- "fixed-size array has wrong number of elements",
- header->num_elements,
- validate_params->expected_num_elements).c_str());
- return false;
- }
- if (!validation_context->ClaimMemory(data, header->num_bytes)) {
- ReportValidationError(validation_context,
- VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE);
- return false;
- }
-
- const Array_Data<T>* object = static_cast<const Array_Data<T>*>(data);
- return Helper::ValidateElements(&object->header_, object->storage(),
- validation_context, validate_params);
- }
-
- size_t size() const { return header_.num_elements; }
-
- Ref at(size_t offset) {
- DCHECK(offset < static_cast<size_t>(header_.num_elements));
- return Traits::ToRef(storage(), offset);
- }
-
- ConstRef at(size_t offset) const {
- DCHECK(offset < static_cast<size_t>(header_.num_elements));
- return Traits::ToConstRef(storage(), offset);
- }
-
- StorageType* storage() {
- return reinterpret_cast<StorageType*>(reinterpret_cast<char*>(this) +
- sizeof(*this));
- }
-
- const StorageType* storage() const {
- return reinterpret_cast<const StorageType*>(
- reinterpret_cast<const char*>(this) + sizeof(*this));
- }
-
- private:
- Array_Data(uint32_t num_bytes, uint32_t num_elements) {
- header_.num_bytes = num_bytes;
- header_.num_elements = num_elements;
- }
- ~Array_Data() = delete;
-
- internal::ArrayHeader header_;
-
- // Elements of type internal::ArrayDataTraits<T>::StorageType follow.
-};
-static_assert(sizeof(Array_Data<char>) == 8, "Bad sizeof(Array_Data)");
-
-// UTF-8 encoded
-using String_Data = Array_Data<char>;
-
-} // namespace internal
-} // namespace mojo
-
-#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_