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

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

Powered by Google App Engine
This is Rietveld 408576698