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