OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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_ |
OLD | NEW |