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

Side by Side Diff: mojo/public/cpp/bindings/lib/map_serialization.h

Issue 2250183003: Make the fuchsia mojo/public repo the source of truth. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 4 years, 4 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_MAP_SERIALIZATION_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_MAP_SERIALIZATION_H_
7
8 #include <type_traits>
9
10 #include "mojo/public/cpp/bindings/lib/array_internal.h"
11 #include "mojo/public/cpp/bindings/lib/array_serialization.h"
12 #include "mojo/public/cpp/bindings/lib/bindings_internal.h"
13 #include "mojo/public/cpp/bindings/lib/iterator_util.h"
14 #include "mojo/public/cpp/bindings/lib/map_data_internal.h"
15 #include "mojo/public/cpp/bindings/lib/map_internal.h"
16 #include "mojo/public/cpp/bindings/lib/string_serialization.h"
17 #include "mojo/public/cpp/bindings/lib/template_util.h"
18 #include "mojo/public/cpp/bindings/map.h"
19
20 namespace mojo {
21 namespace internal {
22
23 template <typename MapType,
24 typename DataType,
25 bool value_is_move_only_type = IsMoveOnlyType<MapType>::value,
26 bool is_union = IsUnionDataType<
27 typename std::remove_pointer<DataType>::type>::value>
28 struct MapSerializer;
29
30 template <typename MapType, typename DataType>
31 struct MapSerializer<MapType, DataType, false, false> {
32 static size_t GetBaseArraySize(size_t count) {
33 return Align(count * sizeof(DataType));
34 }
35 static size_t GetItemSize(const MapType& item) { return 0; }
36 };
37
38 template <>
39 struct MapSerializer<bool, bool, false, false> {
40 static size_t GetBaseArraySize(size_t count) {
41 return Align((count + 7) / 8);
42 }
43 static size_t GetItemSize(bool item) { return 0; }
44 };
45
46 template <typename H>
47 struct MapSerializer<ScopedHandleBase<H>, H, true, false> {
48 static size_t GetBaseArraySize(size_t count) {
49 return Align(count * sizeof(H));
50 }
51 static size_t GetItemSize(const ScopedHandleBase<H>& item) { return 0; }
52 };
53
54 // This template must only apply to pointer mojo entity (structs and arrays).
55 // This is done by ensuring that WrapperTraits<S>::DataType is a pointer.
56 template <typename S>
57 struct MapSerializer<
58 S,
59 typename std::enable_if<
60 std::is_pointer<typename WrapperTraits<S>::DataType>::value,
61 typename WrapperTraits<S>::DataType>::type,
62 true,
63 false> {
64 typedef
65 typename std::remove_pointer<typename WrapperTraits<S>::DataType>::type
66 S_Data;
67 static size_t GetBaseArraySize(size_t count) {
68 return count * sizeof(StructPointer<S_Data>);
69 }
70 static size_t GetItemSize(const S& item) {
71 return item ? GetSerializedSize_(*UnwrapConstStructPtr<S>::value(item)) : 0;
72 }
73 };
74
75 template <typename U, typename U_Data>
76 struct MapSerializer<U, U_Data, true, true> {
77 static size_t GetBaseArraySize(size_t count) {
78 // GetSerializedSize_ (called in GetItemSize()) will account for
79 // sizeof(U_Data), so prevent double counting by having this count be 0.
80 return 0;
81 }
82 static size_t GetItemSize(const U& item) { return GetSerializedSize_(item); }
83 };
84
85 template <>
86 struct MapSerializer<String, String_Data*, false, false> {
87 static size_t GetBaseArraySize(size_t count) {
88 return count * sizeof(StringPointer);
89 }
90 static size_t GetItemSize(const String& item) {
91 return GetSerializedSize_(item);
92 }
93 };
94
95 } // namespace internal
96
97 // TODO(erg): This can't go away yet. We still need to calculate out the size
98 // of a struct header, and two arrays.
99 template <typename MapKey, typename MapValue>
100 inline size_t GetSerializedSize_(const Map<MapKey, MapValue>& input) {
101 if (!input)
102 return 0;
103 typedef typename internal::WrapperTraits<MapKey>::DataType DataKey;
104 typedef typename internal::WrapperTraits<MapValue>::DataType DataValue;
105
106 size_t count = input.size();
107 size_t struct_overhead = sizeof(mojo::internal::Map_Data<DataKey, DataValue>);
108 size_t key_base_size =
109 sizeof(internal::ArrayHeader) +
110 internal::MapSerializer<MapKey, DataKey>::GetBaseArraySize(count);
111 size_t value_base_size =
112 sizeof(internal::ArrayHeader) +
113 internal::MapSerializer<MapValue, DataValue>::GetBaseArraySize(count);
114
115 size_t key_data_size = 0;
116 size_t value_data_size = 0;
117 for (auto it = input.cbegin(); it != input.cend(); ++it) {
118 key_data_size +=
119 internal::MapSerializer<MapKey, DataKey>::GetItemSize(it.GetKey());
120 value_data_size +=
121 internal::MapSerializer<MapValue, DataValue>::GetItemSize(
122 it.GetValue());
123 }
124
125 return struct_overhead + key_base_size + key_data_size + value_base_size +
126 value_data_size;
127 }
128
129 // SerializeMap_ will return ValidationError::NONE on success and set
130 // |output| accordingly. On failure, |input| will be partially serialized into
131 // |output| up until an error occurs (which is propagated up and returned by
132 // SerializeMap_), in which case |buf| is also partially consumed.
133 //
134 // We don't need an ArrayValidateParams instance for key validation since
135 // we can deduce it from the Key type. (which can only be primitive types or
136 // non-nullable strings.)
137 template <typename MapKey,
138 typename MapValue,
139 typename DataKey,
140 typename DataValue>
141 inline internal::ValidationError SerializeMap_(
142 Map<MapKey, MapValue>* input,
143 internal::Buffer* buf,
144 internal::Map_Data<DataKey, DataValue>** output,
145 const internal::ArrayValidateParams* value_validate_params) {
146 if (input->is_null()) {
147 // |input| could be a nullable map, in which case |output| is serialized as
148 // null, which is valid.
149 *output = nullptr;
150 return internal::ValidationError::NONE;
151 }
152
153 internal::Map_Data<DataKey, DataValue>* result =
154 internal::Map_Data<DataKey, DataValue>::New(buf);
155
156 // We *must* serialize the keys before we allocate an Array_Data for the
157 // values.
158 internal::Array_Data<DataKey>* keys_data =
159 internal::Array_Data<DataKey>::New(input->size(), buf);
160 result->keys.ptr = keys_data;
161
162 internal::MapKeyIterator<MapKey, MapValue> key_iter(input);
163 const internal::ArrayValidateParams* key_validate_params =
164 internal::MapKeyValidateParamsFactory<DataKey>::Get();
165
166 auto keys_retval =
167 internal::ArraySerializer<MapKey, DataKey>::SerializeElements(
168 key_iter.begin(), input->size(), buf, result->keys.ptr,
169 key_validate_params);
170 if (keys_retval != internal::ValidationError::NONE)
171 return keys_retval;
172
173 // Now we try allocate an Array_Data for the values
174 internal::Array_Data<DataValue>* values_data =
175 internal::Array_Data<DataValue>::New(input->size(), buf);
176 result->values.ptr = values_data;
177
178 internal::MapValueIterator<MapKey, MapValue> value_iter(input);
179
180 auto values_retval =
181 internal::ArraySerializer<MapValue, DataValue>::SerializeElements(
182 value_iter.begin(), input->size(), buf, result->values.ptr,
183 value_validate_params);
184 if (values_retval != internal::ValidationError::NONE)
185 return values_retval;
186
187 *output = result;
188 return internal::ValidationError::NONE;
189 }
190
191 template <typename MapKey,
192 typename MapValue,
193 typename DataKey,
194 typename DataValue>
195 inline void Deserialize_(internal::Map_Data<DataKey, DataValue>* input,
196 Map<MapKey, MapValue>* output) {
197 if (input) {
198 Array<MapKey> keys;
199 Array<MapValue> values;
200
201 Deserialize_(input->keys.ptr, &keys);
202 Deserialize_(input->values.ptr, &values);
203
204 *output = Map<MapKey, MapValue>(keys.Pass(), values.Pass());
205 } else {
206 output->reset();
207 }
208 }
209
210 } // namespace mojo
211
212 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_MAP_SERIALIZATION_H_
OLDNEW
« no previous file with comments | « mojo/public/cpp/bindings/lib/map_internal.h ('k') | mojo/public/cpp/bindings/lib/map_serialization_forward.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698