| Index: mojo/public/cpp/bindings/lib/map_serialization.h
|
| diff --git a/mojo/public/cpp/bindings/lib/map_serialization.h b/mojo/public/cpp/bindings/lib/map_serialization.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..00e7e6f7ecc010cf760e04051705283baee38ac7
|
| --- /dev/null
|
| +++ b/mojo/public/cpp/bindings/lib/map_serialization.h
|
| @@ -0,0 +1,197 @@
|
| +// Copyright 2014 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_MAP_SERIALIZATION_H_
|
| +#define MOJO_PUBLIC_CPP_BINDINGS_LIB_MAP_SERIALIZATION_H_
|
| +
|
| +#include "mojo/public/cpp/bindings/lib/array_internal.h"
|
| +#include "mojo/public/cpp/bindings/lib/map_data_internal.h"
|
| +#include "mojo/public/cpp/bindings/lib/map_internal.h"
|
| +#include "mojo/public/cpp/bindings/lib/string_serialization.h"
|
| +#include "mojo/public/cpp/bindings/map.h"
|
| +
|
| +namespace mojo {
|
| +
|
| +template <typename Key, typename Value>
|
| +inline size_t GetSerializedSize_(const Map<Key, Value>& input);
|
| +
|
| +template <typename ValidateParams, typename E, typename F>
|
| +inline void SerializeArray_(Array<E> input,
|
| + internal::Buffer* buf,
|
| + internal::Array_Data<F>** output);
|
| +
|
| +namespace internal {
|
| +
|
| +template <typename MapType,
|
| + typename DataType,
|
| + bool kValueIsMoveOnlyType = IsMoveOnlyType<MapType>::value>
|
| +struct MapSerializer;
|
| +
|
| +template <typename MapType, typename DataType>
|
| +struct MapSerializer<MapType, DataType, false> {
|
| + static size_t GetHeaderSize() { return sizeof(Array_Data<DataType>); }
|
| + static size_t GetBaseArraySize(size_t count) {
|
| + return Align(count * sizeof(DataType));
|
| + }
|
| + static size_t GetItemSize(const MapType& item) { return 0; }
|
| +};
|
| +
|
| +template <>
|
| +struct MapSerializer<bool, bool, false> {
|
| + static size_t GetHeaderSize() { return sizeof(Array_Data<bool>); }
|
| + static size_t GetBaseArraySize(size_t count) {
|
| + return Align((count + 7) / 8);
|
| + }
|
| + static size_t GetItemSize(bool item) { return 0; }
|
| +};
|
| +
|
| +template <typename H>
|
| +struct MapSerializer<ScopedHandleBase<H>, H, true> {
|
| + static size_t GetHeaderSize() { return sizeof(Array_Data<H>); }
|
| + static size_t GetBaseArraySize(size_t count) {
|
| + return Align(count * sizeof(H));
|
| + }
|
| + static size_t GetItemSize(const H& item) { return 0; }
|
| +};
|
| +
|
| +template <typename S>
|
| +struct MapSerializer<S, typename S::Data_*, true> {
|
| + static size_t GetHeaderSize() {
|
| + return sizeof(Array_Data<typename S::Data_*>);
|
| + }
|
| + static size_t GetBaseArraySize(size_t count) {
|
| + return count * sizeof(internal::StructPointer<typename S::Data_>);
|
| + }
|
| + static size_t GetItemSize(const S& item) { return GetSerializedSize_(item); }
|
| +};
|
| +
|
| +template <>
|
| +struct MapSerializer<String, String_Data*, false> {
|
| + static size_t GetHeaderSize() { return sizeof(Array_Data<String_Data*>); }
|
| + static size_t GetBaseArraySize(size_t count) {
|
| + return count * sizeof(internal::StringPointer);
|
| + }
|
| + static size_t GetItemSize(const String& item) {
|
| + return GetSerializedSize_(item);
|
| + }
|
| +};
|
| +
|
| +template <typename MapKey,
|
| + typename MapValue,
|
| + typename DataKey,
|
| + typename DataValue>
|
| +struct SizeAccumulator {
|
| + SizeAccumulator(size_t* data_size) : size(data_size) {}
|
| + size_t* size;
|
| +
|
| + void operator()(const MapKey& key, const MapValue& value) {
|
| + *size += internal::MapSerializer<MapKey, DataKey>::GetItemSize(key);
|
| + *size += internal::MapSerializer<MapValue, DataValue>::GetItemSize(value);
|
| + }
|
| +};
|
| +
|
| +template <typename MapKey>
|
| +struct MapKeyValidateParams {
|
| + public:
|
| + typedef NoValidateParams ElementValidateParams;
|
| + static const uint32_t expected_num_elements = 0;
|
| + static const bool element_is_nullable = false;
|
| +};
|
| +
|
| +template <>
|
| +struct MapKeyValidateParams<String> {
|
| + public:
|
| + typedef ArrayValidateParams<0, false, NoValidateParams> ElementValidateParams;
|
| + static const uint32_t expected_num_elements = 0;
|
| + static const bool element_is_nullable = false;
|
| +};
|
| +
|
| +} // namespace internal
|
| +
|
| +// TODO(erg): This can't go away yet. We still need to calculate out the size
|
| +// of a struct header, and two arrays.
|
| +template <typename MapKey, typename MapValue>
|
| +inline size_t GetSerializedSize_(const Map<MapKey, MapValue>& input) {
|
| + if (!input)
|
| + return 0;
|
| + typedef typename internal::WrapperTraits<MapKey>::DataType DataKey;
|
| + typedef typename internal::WrapperTraits<MapValue>::DataType DataValue;
|
| +
|
| + size_t count = input.size();
|
| + size_t struct_overhead = sizeof(mojo::internal::Map_Data<DataKey, DataValue>);
|
| + size_t key_base_size =
|
| + internal::MapSerializer<MapKey, DataKey>::GetHeaderSize() +
|
| + internal::MapSerializer<MapKey, DataKey>::GetBaseArraySize(count);
|
| + size_t value_base_size =
|
| + internal::MapSerializer<MapValue, DataValue>::GetHeaderSize() +
|
| + internal::MapSerializer<MapValue, DataValue>::GetBaseArraySize(count);
|
| +
|
| + size_t key_data_size = 0;
|
| + size_t value_data_size = 0;
|
| + for (auto it = input.begin(); it != input.end(); ++it) {
|
| + key_data_size +=
|
| + internal::MapSerializer<MapKey, DataKey>::GetItemSize(it.GetKey());
|
| + value_data_size +=
|
| + internal::MapSerializer<MapValue, DataValue>::GetItemSize(
|
| + it.GetValue());
|
| + }
|
| +
|
| + return struct_overhead + key_base_size + key_data_size +
|
| + // SOME SORT OF ALIGNMENT GOES HERE?
|
| + value_base_size + value_data_size;
|
| +}
|
| +
|
| +// We don't need a KeyValidateParams, because we konw exactly what params are
|
| +// needed. (Keys are primitive types or non-nullable strings.)
|
| +template <typename ValueValidateParams,
|
| + typename KeyWrapperType,
|
| + typename ValueWrapperType,
|
| + typename KeySerializationType,
|
| + typename ValueSerializationType>
|
| +inline void SerializeMap_(
|
| + Map<KeyWrapperType, ValueWrapperType> input,
|
| + internal::Buffer* buf,
|
| + internal::Map_Data<KeySerializationType, ValueSerializationType>** output) {
|
| + if (input) {
|
| + internal::Map_Data<KeySerializationType, ValueSerializationType>* result =
|
| + internal::Map_Data<KeySerializationType, ValueSerializationType>::New(
|
| + buf);
|
| + if (result) {
|
| + Array<KeyWrapperType> keys;
|
| + Array<ValueWrapperType> values;
|
| + input.DecomposeMapTo(&keys, &values);
|
| + SerializeArray_<internal::MapKeyValidateParams<KeyWrapperType>>(
|
| + keys.Pass(), buf, &result->first.ptr);
|
| + SerializeArray_<ValueValidateParams>(
|
| + values.Pass(), buf, &result->second.ptr);
|
| + }
|
| + *output = result;
|
| + } else {
|
| + *output = nullptr;
|
| + }
|
| +}
|
| +
|
| +template <typename KeyWrapperType,
|
| + typename ValueWrapperType,
|
| + typename KeySerializationType,
|
| + typename ValueSerializationType>
|
| +inline void Deserialize_(
|
| + internal::Map_Data<KeySerializationType, ValueSerializationType>* input,
|
| + Map<KeyWrapperType, ValueWrapperType>* output) {
|
| + if (input) {
|
| + Array<KeyWrapperType> keys;
|
| + Array<ValueWrapperType> values;
|
| +
|
| + Deserialize_(input->first.ptr, &keys);
|
| + Deserialize_(input->second.ptr, &values);
|
| +
|
| + *output = Map<KeyWrapperType, ValueWrapperType>(keys.Pass(), values.Pass());
|
| + } else {
|
| + output->reset();
|
| + }
|
| +}
|
| +
|
| +} // namespace mojo
|
| +
|
| +#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_MAP_SERIALIZATION_H_
|
|
|