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

Unified Diff: mojo/public/cpp/bindings/lib/map_serialization.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/map_serialization.h
diff --git a/mojo/public/cpp/bindings/lib/map_serialization.h b/mojo/public/cpp/bindings/lib/map_serialization.h
index 05062b6ac6cce7dc976f902d9881b64ee8be8ddf..56ef68d3162f90f0ff73707fbb23e92f35ba6ae8 100644
--- a/mojo/public/cpp/bindings/lib/map_serialization.h
+++ b/mojo/public/cpp/bindings/lib/map_serialization.h
@@ -5,195 +5,115 @@
#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_MAP_SERIALIZATION_H_
#define MOJO_PUBLIC_CPP_BINDINGS_LIB_MAP_SERIALIZATION_H_
-#include <stddef.h>
-#include <utility>
-
-#include "mojo/public/cpp/bindings/lib/array_internal.h"
+#include "mojo/public/cpp/bindings/array.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/serialization_forward.h"
#include "mojo/public/cpp/bindings/map.h"
namespace mojo {
namespace internal {
-template <typename MapType,
- typename DataType,
- bool value_is_move_only_type = IsMoveOnlyType<MapType>::value,
- bool is_union =
- IsUnionDataType<typename RemovePointer<DataType>::type>::value>
-struct MapSerializer;
-
-template <typename MapType, typename DataType>
-struct MapSerializer<MapType, DataType, false, false> {
- static size_t GetBaseArraySize(size_t count) {
- return Align(count * sizeof(DataType));
- }
- static size_t GetItemSize(const MapType& item,
- SerializationContext* context) {
- return 0;
- }
-};
-
-template <>
-struct MapSerializer<bool, bool, false, false> {
- static size_t GetBaseArraySize(size_t count) {
- return Align((count + 7) / 8);
- }
- static size_t GetItemSize(bool item, SerializationContext* context) {
- return 0;
- }
-};
-
-template <typename H>
-struct MapSerializer<ScopedHandleBase<H>, Handle_Data, true, false> {
- static size_t GetBaseArraySize(size_t count) {
- return Align(count * sizeof(Handle_Data));
- }
- static size_t GetItemSize(const ScopedHandleBase<H>& item,
- SerializationContext* context) {
- return 0;
- }
-};
-
-// This template must only apply to pointer mojo entity (structs and arrays).
-// This is done by ensuring that GetDataTypeAsArrayElement<S>::Data is a
-// pointer.
-template <typename S>
-struct MapSerializer<
- S,
- typename EnableIf<
- IsPointer<typename GetDataTypeAsArrayElement<S>::Data>::value,
- typename GetDataTypeAsArrayElement<S>::Data>::type,
- true,
- false> {
- typedef
- typename RemovePointer<typename GetDataTypeAsArrayElement<S>::Data>::type
- S_Data;
- static size_t GetBaseArraySize(size_t count) {
- return count * sizeof(Pointer<S_Data>);
- }
- static size_t GetItemSize(const S& item, SerializationContext* context) {
- return GetSerializedSize_(item, context);
- }
-};
+template <typename Key, typename Value>
+struct MapContext {
+ explicit MapContext(bool in_is_null) : is_null(in_is_null) {}
-template <typename U, typename U_Data>
-struct MapSerializer<U, U_Data, true, true> {
- static size_t GetBaseArraySize(size_t count) {
- return count * sizeof(U_Data);
- }
- static size_t GetItemSize(const U& item, SerializationContext* context) {
- return GetSerializedSize_(item, true, context);
- }
+ bool is_null;
+ Array<Key> keys;
+ Array<Value> values;
};
-template <>
-struct MapSerializer<String, String_Data*, false, false> {
- static size_t GetBaseArraySize(size_t count) {
- return count * sizeof(Pointer<String_Data>);
+template <typename Key, typename Value, typename MaybeConstUserType>
+struct Serializer<Map<Key, Value>, MaybeConstUserType> {
+ using UserType = typename std::remove_const<MaybeConstUserType>::type;
+ using UserKey = typename UserType::Key;
+ using UserValue = typename UserType::Value;
+ using Data = typename Map<Key, Value>::Data_;
+
+ static_assert(std::is_same<MaybeConstUserType, UserType>::value,
+ "Only support serialization of non-const Maps.");
+ static_assert(IsSpecializationOf<Map, UserType>::value,
+ "Custom mapping of mojom map is not supported yet.");
+
+ static size_t PrepareToSerialize(UserType& input,
+ SerializationContext* context) {
+ auto map_context = new MapContext<UserKey, UserValue>(input.is_null());
+ if (!context->custom_contexts)
+ context->custom_contexts.reset(new std::queue<void*>());
+ context->custom_contexts->push(map_context);
+
+ if (!input)
+ return 0;
+
+ input.DecomposeMapTo(&map_context->keys, &map_context->values);
+
+ size_t struct_overhead = sizeof(Data);
+ size_t keys_size =
+ internal::PrepareToSerialize<Array<Key>>(map_context->keys, context);
+ size_t values_size = internal::PrepareToSerialize<Array<Value>>(
+ map_context->values, context);
+
+ return struct_overhead + keys_size + values_size;
}
- static size_t GetItemSize(const String& item, SerializationContext* context) {
- return GetSerializedSize_(item, context);
- }
-};
-
-} // 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,
- internal::SerializationContext* context) {
- if (!input)
- return 0;
- typedef typename internal::GetDataTypeAsArrayElement<MapKey>::Data DataKey;
- typedef
- typename internal::GetDataTypeAsArrayElement<MapValue>::Data DataValue;
-
- size_t count = input.size();
- size_t struct_overhead = sizeof(mojo::internal::Map_Data<DataKey, DataValue>);
- size_t key_base_size =
- sizeof(internal::ArrayHeader) +
- internal::MapSerializer<MapKey, DataKey>::GetBaseArraySize(count);
- size_t value_base_size =
- sizeof(internal::ArrayHeader) +
- 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->first, context);
- value_data_size +=
- internal::MapSerializer<MapValue, DataValue>::GetItemSize(it->second,
- context);
- }
+ // We don't need an ArrayValidateParams instance for key validation since
+ // we can deduce it from the Key type. (which can only be primitive types or
+ // non-nullable strings.)
+ static void Serialize(UserType& input,
+ Buffer* buf,
+ Data** output,
+ const ArrayValidateParams* value_validate_params,
+ SerializationContext* context) {
+ std::unique_ptr<MapContext<UserKey, UserValue>> map_context(
+ static_cast<MapContext<UserKey, UserValue>*>(
+ context->custom_contexts->front()));
+ context->custom_contexts->pop();
+
+ if (map_context->is_null) {
+ *output = nullptr;
+ return;
+ }
- return struct_overhead + key_base_size + key_data_size + value_base_size +
- value_data_size;
-}
-
-// We don't need an ArrayValidateParams instance for key validation since
-// we can deduce it from the Key type. (which can only be primitive types or
-// non-nullable strings.)
-template <typename MapKey,
- typename MapValue,
- typename DataKey,
- typename DataValue>
-inline void SerializeMap_(
- Map<MapKey, MapValue> input,
- internal::Buffer* buf,
- internal::Map_Data<DataKey, DataValue>** output,
- const internal::ArrayValidateParams* value_validate_params,
- internal::SerializationContext* context) {
- if (input) {
- internal::Map_Data<DataKey, DataValue>* result =
- internal::Map_Data<DataKey, DataValue>::New(buf);
+ auto result = Data::New(buf);
if (result) {
- Array<MapKey> keys;
- Array<MapValue> values;
- input.DecomposeMapTo(&keys, &values);
- const internal::ArrayValidateParams* key_validate_params =
- internal::MapKeyValidateParamsFactory<DataKey>::Get();
- SerializeArray_(std::move(keys), buf, &result->keys.ptr,
- key_validate_params, context);
- SerializeArray_(std::move(values), buf, &result->values.ptr,
- value_validate_params, context);
+ const ArrayValidateParams* key_validate_params =
+ MapKeyValidateParamsFactory<
+ typename GetDataTypeAsArrayElement<Key>::Data>::Get();
+ internal::Serialize<Array<Key>>(map_context->keys, buf, &result->keys.ptr,
+ key_validate_params, context);
+ internal::Serialize<Array<Value>>(map_context->values, buf,
+ &result->values.ptr,
+ value_validate_params, context);
}
*output = result;
- } else {
- *output = nullptr;
}
-}
-
-template <typename MapKey,
- typename MapValue,
- typename DataKey,
- typename DataValue>
-inline bool Deserialize_(internal::Map_Data<DataKey, DataValue>* input,
- Map<MapKey, MapValue>* output,
- internal::SerializationContext* context) {
- bool success = true;
- if (input) {
- Array<MapKey> keys;
- Array<MapValue> values;
-
- // 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->keys.ptr, &keys, context))
- success = false;
- if (!Deserialize_(input->values.ptr, &values, context))
- success = false;
-
- *output = Map<MapKey, MapValue>(std::move(keys), std::move(values));
- } else {
- *output = nullptr;
+
+ static bool Deserialize(Data* input,
+ UserType* output,
+ SerializationContext* context) {
+ bool success = true;
+ if (input) {
+ Array<UserKey> keys;
+ Array<UserValue> values;
+
+ // 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 (!internal::Deserialize<Array<Key>>(input->keys.ptr, &keys, context))
+ success = false;
+ if (!internal::Deserialize<Array<Value>>(input->values.ptr, &values,
+ context)) {
+ success = false;
+ }
+
+ *output = UserType(std::move(keys), std::move(values));
+ } else {
+ *output = nullptr;
+ }
+ return success;
}
- return success;
-}
+};
+} // namespace internal
} // namespace mojo
#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_MAP_SERIALIZATION_H_
« no previous file with comments | « mojo/public/cpp/bindings/lib/array_serialization_traits.h ('k') | mojo/public/cpp/bindings/lib/native_struct_serialization.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698