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

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

Issue 2058633002: mojo::ArrayTraits: Add Support for Iterators (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed comments Created 4 years, 6 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
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_ 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_ 6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_
7 7
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <string.h> // For |memcpy()|. 9 #include <string.h> // For |memcpy()|.
10 10
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 ? ArraySerializerType::POINTER 49 ? ArraySerializerType::POINTER
50 : (IsHandle<DataElement>::value 50 : (IsHandle<DataElement>::value
51 ? ArraySerializerType::HANDLE 51 ? ArraySerializerType::HANDLE
52 : (std::is_same<Element, bool>::value 52 : (std::is_same<Element, bool>::value
53 ? ArraySerializerType::BOOLEAN 53 ? ArraySerializerType::BOOLEAN
54 : (std::is_enum<Element>::value 54 : (std::is_enum<Element>::value
55 ? ArraySerializerType::ENUM 55 ? ArraySerializerType::ENUM
56 : ArraySerializerType::POD)))); 56 : ArraySerializerType::POD))));
57 }; 57 };
58 58
59 // Used as the UserTypeReader template parameter of ArraySerializer. 59 template <
60 typename Traits,
61 typename MaybeConstUserType,
62 typename IteratorType,
63 typename std::enable_if<
64 HasGetBeginMethod<Traits, MaybeConstUserType>::value>::type* = nullptr>
65 static decltype(Traits::GetValue(std::declval<IteratorType&>())) GetNextHelper(
yzshen1 2016/06/11 00:40:27 Is it possible to merge these two helpers into Arr
Fady Samuel 2016/06/11 16:16:37 I agree it's probably easier to understand althoug
66 MaybeConstUserType& input,
67 IteratorType& iter) {
68 auto& value = Traits::GetValue(iter);
69 Traits::AdvanceIterator(iter);
70 return value;
71 }
72
73 template <
74 typename Traits,
75 typename MaybeConstUserType,
76 typename IteratorType,
77 typename std::enable_if<
78 !HasGetBeginMethod<Traits, MaybeConstUserType>::value>::type* = nullptr>
79 static decltype(Traits::GetAt(std::declval<MaybeConstUserType&>(), 0))
80 GetNextHelper(MaybeConstUserType& input, size_t& index) {
81 DCHECK_LT(index, Traits::GetSize(input));
82 return Traits::GetAt(input, index++);
83 }
84
85 // Used as the UserTypeIterator template parameter of ArraySerializer.
60 template <typename MaybeConstUserType> 86 template <typename MaybeConstUserType>
61 class ArrayReader { 87 class ArrayIterator {
62 public: 88 public:
63 using UserType = typename std::remove_const<MaybeConstUserType>::type; 89 using UserType = typename std::remove_const<MaybeConstUserType>::type;
64 using Traits = ArrayTraits<UserType>; 90 using Traits = ArrayTraits<UserType>;
91 using IteratorType = decltype(
92 CallGetBeginIfExists<Traits>(std::declval<MaybeConstUserType&>()));
65 93
66 explicit ArrayReader(MaybeConstUserType& input) : input_(input) {} 94 explicit ArrayIterator(MaybeConstUserType& input)
67 ~ArrayReader() {} 95 : input_(input), iter_(CallGetBeginIfExists<Traits>(input)) {}
96 ~ArrayIterator() {}
68 97
69 size_t GetSize() const { return Traits::GetSize(input_); } 98 size_t GetSize() const { return Traits::GetSize(input_); }
70 99
71 using GetNextResult = 100 decltype(GetNextHelper<Traits, MaybeConstUserType, IteratorType>(
72 decltype(Traits::GetAt(std::declval<MaybeConstUserType&>(), 0)); 101 std::declval<MaybeConstUserType&>(),
73 GetNextResult GetNext() { 102 std::declval<IteratorType&>()))
74 DCHECK_LT(index_, Traits::GetSize(input_)); 103 GetNext() {
75 return Traits::GetAt(input_, index_++); 104 return GetNextHelper<Traits, MaybeConstUserType, IteratorType>(input_,
105 iter_);
76 } 106 }
77 107
78 using GetDataIfExistsResult = decltype( 108 using GetDataIfExistsResult = decltype(
79 CallGetDataIfExists<Traits>(std::declval<MaybeConstUserType&>())); 109 CallGetDataIfExists<Traits>(std::declval<MaybeConstUserType&>()));
80 GetDataIfExistsResult GetDataIfExists() { 110 GetDataIfExistsResult GetDataIfExists() {
81 return CallGetDataIfExists<Traits>(input_); 111 return CallGetDataIfExists<Traits>(input_);
82 } 112 }
83 113
84 private: 114 private:
85 MaybeConstUserType& input_; 115 MaybeConstUserType& input_;
86 size_t index_ = 0; 116 IteratorType iter_;
87 }; 117 };
88 118
89 // ArraySerializer is also used to serialize map keys and values. Therefore, it 119 // ArraySerializer is also used to serialize map keys and values. Therefore, it
90 // has a UserTypeReader parameter which is an adaptor for reading to hide the 120 // has a UserTypeIterator parameter which is an adaptor for reading to hide the
91 // difference between ArrayTraits and MapTraits. 121 // difference between ArrayTraits and MapTraits.
92 template <typename MojomType, 122 template <typename MojomType,
93 typename MaybeConstUserType, 123 typename MaybeConstUserType,
94 typename UserTypeReader, 124 typename UserTypeIterator,
95 ArraySerializerType type = GetArraySerializerType<MojomType>::value> 125 ArraySerializerType type = GetArraySerializerType<MojomType>::value>
96 struct ArraySerializer; 126 struct ArraySerializer;
97 127
98 // Handles serialization and deserialization of arrays of pod types. 128 // Handles serialization and deserialization of arrays of pod types.
99 template <typename MojomType, 129 template <typename MojomType,
100 typename MaybeConstUserType, 130 typename MaybeConstUserType,
101 typename UserTypeReader> 131 typename UserTypeIterator>
102 struct ArraySerializer<MojomType, 132 struct ArraySerializer<MojomType,
103 MaybeConstUserType, 133 MaybeConstUserType,
104 UserTypeReader, 134 UserTypeIterator,
105 ArraySerializerType::POD> { 135 ArraySerializerType::POD> {
106 using UserType = typename std::remove_const<MaybeConstUserType>::type; 136 using UserType = typename std::remove_const<MaybeConstUserType>::type;
107 using Data = typename MojomType::Data_; 137 using Data = typename MojomType::Data_;
108 using DataElement = typename Data::Element; 138 using DataElement = typename Data::Element;
109 using Element = typename MojomType::Element; 139 using Element = typename MojomType::Element;
110 using Traits = ArrayTraits<UserType>; 140 using Traits = ArrayTraits<UserType>;
141 using IteratorType =
yzshen1 2016/06/11 00:40:27 This is not needed anymore. (and same below)
142 decltype(CallGetBeginIfExists<Traits>(std::declval<UserType&>()));
111 143
112 static_assert(std::is_same<Element, DataElement>::value, 144 static_assert(std::is_same<Element, DataElement>::value,
113 "Incorrect array serializer"); 145 "Incorrect array serializer");
114 static_assert(std::is_same<Element, typename Traits::Element>::value, 146 static_assert(std::is_same<Element, typename Traits::Element>::value,
115 "Incorrect array serializer"); 147 "Incorrect array serializer");
116 148
117 static size_t GetSerializedSize(UserTypeReader* input, 149 static size_t GetSerializedSize(UserTypeIterator* input,
118 SerializationContext* context) { 150 SerializationContext* context) {
119 return sizeof(Data) + Align(input->GetSize() * sizeof(DataElement)); 151 return sizeof(Data) + Align(input->GetSize() * sizeof(DataElement));
120 } 152 }
121 153
122 static void SerializeElements(UserTypeReader* input, 154 static void SerializeElements(UserTypeIterator* input,
123 Buffer* buf, 155 Buffer* buf,
124 Data* output, 156 Data* output,
125 const ContainerValidateParams* validate_params, 157 const ContainerValidateParams* validate_params,
126 SerializationContext* context) { 158 SerializationContext* context) {
127 DCHECK(!validate_params->element_is_nullable) 159 DCHECK(!validate_params->element_is_nullable)
128 << "Primitive type should be non-nullable"; 160 << "Primitive type should be non-nullable";
129 DCHECK(!validate_params->element_validate_params) 161 DCHECK(!validate_params->element_validate_params)
130 << "Primitive type should not have array validate params"; 162 << "Primitive type should not have array validate params";
131 163
132 size_t size = input->GetSize(); 164 size_t size = input->GetSize();
133 if (size == 0) 165 if (size == 0)
134 return; 166 return;
135 167
136 auto data = input->GetDataIfExists(); 168 auto data = input->GetDataIfExists();
137 if (data) { 169 if (data) {
138 memcpy(output->storage(), data, size * sizeof(DataElement)); 170 memcpy(output->storage(), data, size * sizeof(DataElement));
139 } else { 171 } else {
140 for (size_t i = 0; i < size; ++i) 172 for (size_t i = 0; i < size; ++i)
141 output->at(i) = input->GetNext(); 173 output->at(i) = input->GetNext();
142 } 174 }
143 } 175 }
144 176
145 static bool DeserializeElements(Data* input, 177 static bool DeserializeElements(Data* input,
146 UserType* output, 178 UserType* output,
147 SerializationContext* context) { 179 SerializationContext* context) {
148 if (!Traits::Resize(*output, input->size())) 180 if (!Traits::Resize(*output, input->size()))
149 return false; 181 return false;
182 ArrayIterator<UserType> iterator(*output);
150 if (input->size()) { 183 if (input->size()) {
151 auto data = CallGetDataIfExists<Traits>(*output); 184 auto data = iterator.GetDataIfExists();
152 if (data) { 185 if (data) {
153 memcpy(data, input->storage(), input->size() * sizeof(DataElement)); 186 memcpy(data, input->storage(), input->size() * sizeof(DataElement));
154 } else { 187 } else {
155 for (size_t i = 0; i < input->size(); ++i) 188 for (size_t i = 0; i < input->size(); ++i)
156 Traits::GetAt(*output, i) = input->at(i); 189 iterator.GetNext() = input->at(i);
157 } 190 }
158 } 191 }
159 return true; 192 return true;
160 } 193 }
161 }; 194 };
162 195
163 // Handles serialization and deserialization of arrays of enum types. 196 // Handles serialization and deserialization of arrays of enum types.
164 template <typename MojomType, 197 template <typename MojomType,
165 typename MaybeConstUserType, 198 typename MaybeConstUserType,
166 typename UserTypeReader> 199 typename UserTypeIterator>
167 struct ArraySerializer<MojomType, 200 struct ArraySerializer<MojomType,
168 MaybeConstUserType, 201 MaybeConstUserType,
169 UserTypeReader, 202 UserTypeIterator,
170 ArraySerializerType::ENUM> { 203 ArraySerializerType::ENUM> {
171 using UserType = typename std::remove_const<MaybeConstUserType>::type; 204 using UserType = typename std::remove_const<MaybeConstUserType>::type;
172 using Data = typename MojomType::Data_; 205 using Data = typename MojomType::Data_;
173 using DataElement = typename Data::Element; 206 using DataElement = typename Data::Element;
174 using Element = typename MojomType::Element; 207 using Element = typename MojomType::Element;
175 using Traits = ArrayTraits<UserType>; 208 using Traits = ArrayTraits<UserType>;
176 209
177 static_assert(sizeof(Element) == sizeof(DataElement), 210 static_assert(sizeof(Element) == sizeof(DataElement),
178 "Incorrect array serializer"); 211 "Incorrect array serializer");
179 212
180 static size_t GetSerializedSize(UserTypeReader* input, 213 static size_t GetSerializedSize(UserTypeIterator* input,
181 SerializationContext* context) { 214 SerializationContext* context) {
182 return sizeof(Data) + Align(input->GetSize() * sizeof(DataElement)); 215 return sizeof(Data) + Align(input->GetSize() * sizeof(DataElement));
183 } 216 }
184 217
185 static void SerializeElements(UserTypeReader* input, 218 static void SerializeElements(UserTypeIterator* input,
186 Buffer* buf, 219 Buffer* buf,
187 Data* output, 220 Data* output,
188 const ContainerValidateParams* validate_params, 221 const ContainerValidateParams* validate_params,
189 SerializationContext* context) { 222 SerializationContext* context) {
190 DCHECK(!validate_params->element_is_nullable) 223 DCHECK(!validate_params->element_is_nullable)
191 << "Primitive type should be non-nullable"; 224 << "Primitive type should be non-nullable";
192 DCHECK(!validate_params->element_validate_params) 225 DCHECK(!validate_params->element_validate_params)
193 << "Primitive type should not have array validate params"; 226 << "Primitive type should not have array validate params";
194 227
195 size_t size = input->GetSize(); 228 size_t size = input->GetSize();
196 for (size_t i = 0; i < size; ++i) 229 for (size_t i = 0; i < size; ++i)
197 Serialize<Element>(input->GetNext(), output->storage() + i); 230 Serialize<Element>(input->GetNext(), output->storage() + i);
198 } 231 }
199 232
200 static bool DeserializeElements(Data* input, 233 static bool DeserializeElements(Data* input,
201 UserType* output, 234 UserType* output,
202 SerializationContext* context) { 235 SerializationContext* context) {
203 if (!Traits::Resize(*output, input->size())) 236 if (!Traits::Resize(*output, input->size()))
204 return false; 237 return false;
238 ArrayIterator<UserType> iterator(*output);
205 for (size_t i = 0; i < input->size(); ++i) { 239 for (size_t i = 0; i < input->size(); ++i) {
206 if (!Deserialize<Element>(input->at(i), &Traits::GetAt(*output, i))) 240 if (!Deserialize<Element>(input->at(i), &iterator.GetNext()))
207 return false; 241 return false;
208 } 242 }
209 return true; 243 return true;
210 } 244 }
211 }; 245 };
212 246
213 // Serializes and deserializes arrays of bools. 247 // Serializes and deserializes arrays of bools.
214 template <typename MojomType, 248 template <typename MojomType,
215 typename MaybeConstUserType, 249 typename MaybeConstUserType,
216 typename UserTypeReader> 250 typename UserTypeIterator>
217 struct ArraySerializer<MojomType, 251 struct ArraySerializer<MojomType,
218 MaybeConstUserType, 252 MaybeConstUserType,
219 UserTypeReader, 253 UserTypeIterator,
220 ArraySerializerType::BOOLEAN> { 254 ArraySerializerType::BOOLEAN> {
221 using UserType = typename std::remove_const<MaybeConstUserType>::type; 255 using UserType = typename std::remove_const<MaybeConstUserType>::type;
222 using Traits = ArrayTraits<UserType>; 256 using Traits = ArrayTraits<UserType>;
223 using Data = typename MojomType::Data_; 257 using Data = typename MojomType::Data_;
258 using IteratorType =
259 decltype(CallGetBeginIfExists<Traits>(std::declval<UserType&>()));
224 260
225 static_assert(std::is_same<bool, typename UserType::Element>::value, 261 static_assert(std::is_same<bool, typename UserType::Element>::value,
226 "Incorrect array serializer"); 262 "Incorrect array serializer");
227 263
228 static size_t GetSerializedSize(UserTypeReader* input, 264 static size_t GetSerializedSize(UserTypeIterator* input,
229 SerializationContext* context) { 265 SerializationContext* context) {
230 return sizeof(Data) + Align((input->GetSize() + 7) / 8); 266 return sizeof(Data) + Align((input->GetSize() + 7) / 8);
231 } 267 }
232 268
233 static void SerializeElements(UserTypeReader* input, 269 static void SerializeElements(UserTypeIterator* input,
234 Buffer* buf, 270 Buffer* buf,
235 Data* output, 271 Data* output,
236 const ContainerValidateParams* validate_params, 272 const ContainerValidateParams* validate_params,
237 SerializationContext* context) { 273 SerializationContext* context) {
238 DCHECK(!validate_params->element_is_nullable) 274 DCHECK(!validate_params->element_is_nullable)
239 << "Primitive type should be non-nullable"; 275 << "Primitive type should be non-nullable";
240 DCHECK(!validate_params->element_validate_params) 276 DCHECK(!validate_params->element_validate_params)
241 << "Primitive type should not have array validate params"; 277 << "Primitive type should not have array validate params";
242 278
243 size_t size = input->GetSize(); 279 size_t size = input->GetSize();
244 for (size_t i = 0; i < size; ++i) 280 for (size_t i = 0; i < size; ++i)
245 output->at(i) = input->GetNext(); 281 output->at(i) = input->GetNext();
246 } 282 }
247 static bool DeserializeElements(Data* input, 283 static bool DeserializeElements(Data* input,
248 UserType* output, 284 UserType* output,
249 SerializationContext* context) { 285 SerializationContext* context) {
250 if (!Traits::Resize(*output, input->size())) 286 if (!Traits::Resize(*output, input->size()))
251 return false; 287 return false;
288 ArrayIterator<UserType> iterator(*output);
252 for (size_t i = 0; i < input->size(); ++i) 289 for (size_t i = 0; i < input->size(); ++i)
253 Traits::GetAt(*output, i) = input->at(i); 290 iterator.GetNext() = input->at(i);
254 return true; 291 return true;
255 } 292 }
256 }; 293 };
257 294
258 // Serializes and deserializes arrays of handles. 295 // Serializes and deserializes arrays of handles.
259 template <typename MojomType, 296 template <typename MojomType,
260 typename MaybeConstUserType, 297 typename MaybeConstUserType,
261 typename UserTypeReader> 298 typename UserTypeIterator>
262 struct ArraySerializer<MojomType, 299 struct ArraySerializer<MojomType,
263 MaybeConstUserType, 300 MaybeConstUserType,
264 UserTypeReader, 301 UserTypeIterator,
265 ArraySerializerType::HANDLE> { 302 ArraySerializerType::HANDLE> {
266 using UserType = typename std::remove_const<MaybeConstUserType>::type; 303 using UserType = typename std::remove_const<MaybeConstUserType>::type;
267 using Data = typename MojomType::Data_; 304 using Data = typename MojomType::Data_;
268 using Element = typename MojomType::Element; 305 using Element = typename MojomType::Element;
269 using Traits = ArrayTraits<UserType>; 306 using Traits = ArrayTraits<UserType>;
270 307
271 static_assert(std::is_same<Element, typename Traits::Element>::value, 308 static_assert(std::is_same<Element, typename Traits::Element>::value,
272 "Incorrect array serializer"); 309 "Incorrect array serializer");
273 310
274 static size_t GetSerializedSize(UserTypeReader* input, 311 static size_t GetSerializedSize(UserTypeIterator* input,
275 SerializationContext* context) { 312 SerializationContext* context) {
276 return sizeof(Data) + 313 return sizeof(Data) +
277 Align(input->GetSize() * sizeof(typename Data::Element)); 314 Align(input->GetSize() * sizeof(typename Data::Element));
278 } 315 }
279 316
280 static void SerializeElements(UserTypeReader* input, 317 static void SerializeElements(UserTypeIterator* input,
281 Buffer* buf, 318 Buffer* buf,
282 Data* output, 319 Data* output,
283 const ContainerValidateParams* validate_params, 320 const ContainerValidateParams* validate_params,
284 SerializationContext* context) { 321 SerializationContext* context) {
285 DCHECK(!validate_params->element_validate_params) 322 DCHECK(!validate_params->element_validate_params)
286 << "Handle type should not have array validate params"; 323 << "Handle type should not have array validate params";
287 324
288 size_t size = input->GetSize(); 325 size_t size = input->GetSize();
289 for (size_t i = 0; i < size; ++i) { 326 for (size_t i = 0; i < size; ++i) {
290 // Transfer ownership of the handle. 327 // Transfer ownership of the handle.
291 output->at(i) = context->handles.AddHandle(input->GetNext().release()); 328 output->at(i) = context->handles.AddHandle(input->GetNext().release());
292 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( 329 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
293 !validate_params->element_is_nullable && !output->at(i).is_valid(), 330 !validate_params->element_is_nullable && !output->at(i).is_valid(),
294 VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE, 331 VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
295 MakeMessageWithArrayIndex( 332 MakeMessageWithArrayIndex(
296 "invalid handle in array expecting valid handles", size, i)); 333 "invalid handle in array expecting valid handles", size, i));
297 } 334 }
298 } 335 }
299 static bool DeserializeElements(Data* input, 336 static bool DeserializeElements(Data* input,
300 UserType* output, 337 UserType* output,
301 SerializationContext* context) { 338 SerializationContext* context) {
302 using HandleType = typename Element::RawHandleType; 339 using HandleType = typename Element::RawHandleType;
303 if (!Traits::Resize(*output, input->size())) 340 if (!Traits::Resize(*output, input->size()))
304 return false; 341 return false;
342 ArrayIterator<UserType> iterator(*output);
305 for (size_t i = 0; i < input->size(); ++i) { 343 for (size_t i = 0; i < input->size(); ++i) {
306 Traits::GetAt(*output, i) = MakeScopedHandle( 344 iterator.GetNext() = MakeScopedHandle(
307 HandleType(context->handles.TakeHandle(input->at(i)).value())); 345 HandleType(context->handles.TakeHandle(input->at(i)).value()));
308 } 346 }
309 return true; 347 return true;
310 } 348 }
311 }; 349 };
312 350
313 // This template must only apply to pointer mojo entity (strings, structs, 351 // This template must only apply to pointer mojo entity (strings, structs,
314 // arrays and maps). 352 // arrays and maps).
315 template <typename MojomType, 353 template <typename MojomType,
316 typename MaybeConstUserType, 354 typename MaybeConstUserType,
317 typename UserTypeReader> 355 typename UserTypeIterator>
318 struct ArraySerializer<MojomType, 356 struct ArraySerializer<MojomType,
319 MaybeConstUserType, 357 MaybeConstUserType,
320 UserTypeReader, 358 UserTypeIterator,
321 ArraySerializerType::POINTER> { 359 ArraySerializerType::POINTER> {
322 using UserType = typename std::remove_const<MaybeConstUserType>::type; 360 using UserType = typename std::remove_const<MaybeConstUserType>::type;
323 using Data = typename MojomType::Data_; 361 using Data = typename MojomType::Data_;
324 using DataElement = typename Data::Element; 362 using DataElement = typename Data::Element;
325 using Element = typename MojomType::Element; 363 using Element = typename MojomType::Element;
326 using Traits = ArrayTraits<UserType>; 364 using Traits = ArrayTraits<UserType>;
365 using IteratorType =
366 decltype(CallGetBeginIfExists<Traits>(std::declval<UserType&>()));
327 367
328 static size_t GetSerializedSize(UserTypeReader* input, 368 static size_t GetSerializedSize(UserTypeIterator* input,
329 SerializationContext* context) { 369 SerializationContext* context) {
330 size_t element_count = input->GetSize(); 370 size_t element_count = input->GetSize();
331 size_t size = 371 size_t size =
332 sizeof(Data) + 372 sizeof(Data) +
333 element_count * 373 element_count *
334 sizeof(Pointer<typename std::remove_pointer<DataElement>::type>); 374 sizeof(Pointer<typename std::remove_pointer<DataElement>::type>);
335 for (size_t i = 0; i < element_count; ++i) 375 for (size_t i = 0; i < element_count; ++i)
336 size += PrepareToSerialize<Element>(input->GetNext(), context); 376 size += PrepareToSerialize<Element>(input->GetNext(), context);
337 return size; 377 return size;
338 } 378 }
339 379
340 static void SerializeElements(UserTypeReader* input, 380 static void SerializeElements(UserTypeIterator* input,
341 Buffer* buf, 381 Buffer* buf,
342 Data* output, 382 Data* output,
343 const ContainerValidateParams* validate_params, 383 const ContainerValidateParams* validate_params,
344 SerializationContext* context) { 384 SerializationContext* context) {
345 size_t size = input->GetSize(); 385 size_t size = input->GetSize();
346 for (size_t i = 0; i < size; ++i) { 386 for (size_t i = 0; i < size; ++i) {
347 DataElement element; 387 DataElement element;
348 SerializeCaller<Element>::Run(input->GetNext(), buf, &element, 388 SerializeCaller<Element>::Run(input->GetNext(), buf, &element,
349 validate_params->element_validate_params, 389 validate_params->element_validate_params,
350 context); 390 context);
351 output->at(i) = element; 391 output->at(i) = element;
352 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( 392 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
353 !validate_params->element_is_nullable && !element, 393 !validate_params->element_is_nullable && !element,
354 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, 394 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
355 MakeMessageWithArrayIndex("null in array expecting valid pointers", 395 MakeMessageWithArrayIndex("null in array expecting valid pointers",
356 size, i)); 396 size, i));
357 } 397 }
358 } 398 }
359 static bool DeserializeElements(Data* input, 399 static bool DeserializeElements(Data* input,
360 UserType* output, 400 UserType* output,
361 SerializationContext* context) { 401 SerializationContext* context) {
362 bool success = true; 402 bool success = true;
363 if (!Traits::Resize(*output, input->size())) 403 if (!Traits::Resize(*output, input->size()))
364 return false; 404 return false;
405 ArrayIterator<UserType> iterator(*output);
365 for (size_t i = 0; i < input->size(); ++i) { 406 for (size_t i = 0; i < input->size(); ++i) {
366 // Note that we rely on complete deserialization taking place in order to 407 // Note that we rely on complete deserialization taking place in order to
367 // transfer ownership of all encoded handles. Therefore we don't 408 // transfer ownership of all encoded handles. Therefore we don't
368 // short-circuit on failure here. 409 // short-circuit on failure here.
369 if (!Deserialize<Element>(input->at(i), &Traits::GetAt(*output, i), 410 if (!Deserialize<Element>(input->at(i), &iterator.GetNext(), context)) {
370 context)) {
371 success = false; 411 success = false;
372 } 412 }
373 } 413 }
374 return success; 414 return success;
375 } 415 }
376 416
377 private: 417 private:
378 template <typename T, 418 template <typename T,
379 bool is_array_or_map = IsSpecializationOf<Array, T>::value || 419 bool is_array_or_map = IsSpecializationOf<Array, T>::value ||
380 IsSpecializationOf<Map, T>::value> 420 IsSpecializationOf<Map, T>::value>
(...skipping 18 matching lines...) Expand all
399 SerializationContext* context) { 439 SerializationContext* context) {
400 Serialize<T>(std::forward<InputElementType>(input), buf, output, 440 Serialize<T>(std::forward<InputElementType>(input), buf, output,
401 validate_params, context); 441 validate_params, context);
402 } 442 }
403 }; 443 };
404 }; 444 };
405 445
406 // Handles serialization and deserialization of arrays of unions. 446 // Handles serialization and deserialization of arrays of unions.
407 template <typename MojomType, 447 template <typename MojomType,
408 typename MaybeConstUserType, 448 typename MaybeConstUserType,
409 typename UserTypeReader> 449 typename UserTypeIterator>
410 struct ArraySerializer<MojomType, 450 struct ArraySerializer<MojomType,
411 MaybeConstUserType, 451 MaybeConstUserType,
412 UserTypeReader, 452 UserTypeIterator,
413 ArraySerializerType::UNION> { 453 ArraySerializerType::UNION> {
414 using UserType = typename std::remove_const<MaybeConstUserType>::type; 454 using UserType = typename std::remove_const<MaybeConstUserType>::type;
415 using Data = typename MojomType::Data_; 455 using Data = typename MojomType::Data_;
416 using Element = typename MojomType::Element; 456 using Element = typename MojomType::Element;
417 using Traits = ArrayTraits<UserType>; 457 using Traits = ArrayTraits<UserType>;
458 using IteratorType =
459 decltype(CallGetBeginIfExists<Traits>(std::declval<UserType&>()));
418 460
419 static_assert(std::is_same<typename MojomType::Element, 461 static_assert(std::is_same<typename MojomType::Element,
420 typename Traits::Element>::value, 462 typename Traits::Element>::value,
421 "Incorrect array serializer"); 463 "Incorrect array serializer");
422 464
423 static size_t GetSerializedSize(UserTypeReader* input, 465 static size_t GetSerializedSize(UserTypeIterator* input,
424 SerializationContext* context) { 466 SerializationContext* context) {
425 size_t element_count = input->GetSize(); 467 size_t element_count = input->GetSize();
426 size_t size = sizeof(Data); 468 size_t size = sizeof(Data);
427 for (size_t i = 0; i < element_count; ++i) { 469 for (size_t i = 0; i < element_count; ++i) {
428 // Call with |inlined| set to false, so that it will account for both the 470 // Call with |inlined| set to false, so that it will account for both the
429 // data in the union and the space in the array used to hold the union. 471 // data in the union and the space in the array used to hold the union.
430 size += PrepareToSerialize<Element>(input->GetNext(), false, context); 472 size += PrepareToSerialize<Element>(input->GetNext(), false, context);
431 } 473 }
432 return size; 474 return size;
433 } 475 }
434 476
435 static void SerializeElements(UserTypeReader* input, 477 static void SerializeElements(UserTypeIterator* input,
436 Buffer* buf, 478 Buffer* buf,
437 Data* output, 479 Data* output,
438 const ContainerValidateParams* validate_params, 480 const ContainerValidateParams* validate_params,
439 SerializationContext* context) { 481 SerializationContext* context) {
440 size_t size = input->GetSize(); 482 size_t size = input->GetSize();
441 for (size_t i = 0; i < size; ++i) { 483 for (size_t i = 0; i < size; ++i) {
442 typename Data::Element* result = output->storage() + i; 484 typename Data::Element* result = output->storage() + i;
443 Serialize<Element>(input->GetNext(), buf, &result, true, context); 485 Serialize<Element>(input->GetNext(), buf, &result, true, context);
444 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( 486 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
445 !validate_params->element_is_nullable && output->at(i).is_null(), 487 !validate_params->element_is_nullable && output->at(i).is_null(),
446 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, 488 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
447 MakeMessageWithArrayIndex("null in array expecting valid unions", 489 MakeMessageWithArrayIndex("null in array expecting valid unions",
448 size, i)); 490 size, i));
449 } 491 }
450 } 492 }
451 493
452 static bool DeserializeElements(Data* input, 494 static bool DeserializeElements(Data* input,
453 UserType* output, 495 UserType* output,
454 SerializationContext* context) { 496 SerializationContext* context) {
455 bool success = true; 497 bool success = true;
456 if (!Traits::Resize(*output, input->size())) 498 if (!Traits::Resize(*output, input->size()))
457 return false; 499 return false;
500 ArrayIterator<UserType> iterator(*output);
458 for (size_t i = 0; i < input->size(); ++i) { 501 for (size_t i = 0; i < input->size(); ++i) {
459 // Note that we rely on complete deserialization taking place in order to 502 // Note that we rely on complete deserialization taking place in order to
460 // transfer ownership of all encoded handles. Therefore we don't 503 // transfer ownership of all encoded handles. Therefore we don't
461 // short-circuit on failure here. 504 // short-circuit on failure here.
462 if (!Deserialize<Element>(&input->at(i), &Traits::GetAt(*output, i), 505 if (!Deserialize<Element>(&input->at(i), &iterator.GetNext(), context)) {
463 context)) {
464 success = false; 506 success = false;
465 } 507 }
466 } 508 }
467 return success; 509 return success;
468 } 510 }
469 }; 511 };
470 512
471 template <typename Element, typename MaybeConstUserType> 513 template <typename Element, typename MaybeConstUserType>
472 struct Serializer<Array<Element>, MaybeConstUserType> { 514 struct Serializer<Array<Element>, MaybeConstUserType> {
473 using UserType = typename std::remove_const<MaybeConstUserType>::type; 515 using UserType = typename std::remove_const<MaybeConstUserType>::type;
474 using Impl = ArraySerializer<Array<Element>, 516 using Impl = ArraySerializer<Array<Element>,
475 MaybeConstUserType, 517 MaybeConstUserType,
476 ArrayReader<MaybeConstUserType>>; 518 ArrayIterator<MaybeConstUserType>>;
477 using Traits = ArrayTraits<UserType>; 519 using Traits = ArrayTraits<UserType>;
478 using Data = typename Array<Element>::Data_; 520 using Data = typename Array<Element>::Data_;
479 521
480 static size_t PrepareToSerialize(MaybeConstUserType& input, 522 static size_t PrepareToSerialize(MaybeConstUserType& input,
481 SerializationContext* context) { 523 SerializationContext* context) {
482 if (CallIsNullIfExists<Traits>(input)) 524 if (CallIsNullIfExists<Traits>(input))
483 return 0; 525 return 0;
484 ArrayReader<MaybeConstUserType> reader(input); 526 ArrayIterator<MaybeConstUserType> iterator(input);
485 return Impl::GetSerializedSize(&reader, context); 527 return Impl::GetSerializedSize(&iterator, context);
486 } 528 }
487 529
488 static void Serialize(MaybeConstUserType& input, 530 static void Serialize(MaybeConstUserType& input,
489 Buffer* buf, 531 Buffer* buf,
490 Data** output, 532 Data** output,
491 const ContainerValidateParams* validate_params, 533 const ContainerValidateParams* validate_params,
492 SerializationContext* context) { 534 SerializationContext* context) {
493 if (!CallIsNullIfExists<Traits>(input)) { 535 if (!CallIsNullIfExists<Traits>(input)) {
494 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( 536 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
495 validate_params->expected_num_elements != 0 && 537 validate_params->expected_num_elements != 0 &&
496 Traits::GetSize(input) != validate_params->expected_num_elements, 538 Traits::GetSize(input) != validate_params->expected_num_elements,
497 internal::VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER, 539 internal::VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER,
498 internal::MakeMessageWithExpectedArraySize( 540 internal::MakeMessageWithExpectedArraySize(
499 "fixed-size array has wrong number of elements", 541 "fixed-size array has wrong number of elements",
500 Traits::GetSize(input), validate_params->expected_num_elements)); 542 Traits::GetSize(input), validate_params->expected_num_elements));
501 Data* result = Data::New(Traits::GetSize(input), buf); 543 Data* result = Data::New(Traits::GetSize(input), buf);
502 if (result) { 544 if (result) {
503 ArrayReader<MaybeConstUserType> reader(input); 545 ArrayIterator<MaybeConstUserType> iterator(input);
504 Impl::SerializeElements(&reader, buf, result, validate_params, context); 546 Impl::SerializeElements(&iterator, buf, result, validate_params,
547 context);
505 } 548 }
506 *output = result; 549 *output = result;
507 } else { 550 } else {
508 *output = nullptr; 551 *output = nullptr;
509 } 552 }
510 } 553 }
511 554
512 static bool Deserialize(Data* input, 555 static bool Deserialize(Data* input,
513 UserType* output, 556 UserType* output,
514 SerializationContext* context) { 557 SerializationContext* context) {
515 if (!input) 558 if (!input)
516 return CallSetToNullIfExists<Traits>(output); 559 return CallSetToNullIfExists<Traits>(output);
517 return Impl::DeserializeElements(input, output, context); 560 return Impl::DeserializeElements(input, output, context);
518 } 561 }
519 }; 562 };
520 563
521 } // namespace internal 564 } // namespace internal
522 } // namespace mojo 565 } // namespace mojo
523 566
524 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_ 567 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698