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 <string.h> // For |memcpy()|. | 8 #include <string.h> // For |memcpy()|. |
9 | 9 |
10 #include <utility> | 10 #include <utility> |
(...skipping 12 matching lines...) Expand all Loading... |
23 inline size_t GetSerializedSize_(const Array<E>& input); | 23 inline size_t GetSerializedSize_(const Array<E>& input); |
24 | 24 |
25 template <typename E, typename F> | 25 template <typename E, typename F> |
26 inline void SerializeArray_( | 26 inline void SerializeArray_( |
27 Array<E> input, | 27 Array<E> input, |
28 internal::Buffer* buf, | 28 internal::Buffer* buf, |
29 internal::Array_Data<F>** output, | 29 internal::Array_Data<F>** output, |
30 const internal::ArrayValidateParams* validate_params); | 30 const internal::ArrayValidateParams* validate_params); |
31 | 31 |
32 template <typename E, typename F> | 32 template <typename E, typename F> |
33 inline void Deserialize_(internal::Array_Data<F>* data, | 33 inline bool Deserialize_(internal::Array_Data<F>* data, |
34 Array<E>* output, | 34 Array<E>* output, |
35 internal::SerializationContext* context); | 35 internal::SerializationContext* context); |
36 | 36 |
37 namespace internal { | 37 namespace internal { |
38 | 38 |
39 template <typename E, | 39 template <typename E, |
40 typename F, | 40 typename F, |
41 bool is_union = | 41 bool is_union = |
42 IsUnionDataType<typename RemovePointer<F>::type>::value> | 42 IsUnionDataType<typename RemovePointer<F>::type>::value> |
43 struct ArraySerializer; | 43 struct ArraySerializer; |
(...skipping 11 matching lines...) Expand all Loading... |
55 Array_Data<F>* output, | 55 Array_Data<F>* output, |
56 const ArrayValidateParams* validate_params) { | 56 const ArrayValidateParams* validate_params) { |
57 MOJO_DCHECK(!validate_params->element_is_nullable) | 57 MOJO_DCHECK(!validate_params->element_is_nullable) |
58 << "Primitive type should be non-nullable"; | 58 << "Primitive type should be non-nullable"; |
59 MOJO_DCHECK(!validate_params->element_validate_params) | 59 MOJO_DCHECK(!validate_params->element_validate_params) |
60 << "Primitive type should not have array validate params"; | 60 << "Primitive type should not have array validate params"; |
61 | 61 |
62 if (input.size()) | 62 if (input.size()) |
63 memcpy(output->storage(), &input.storage()[0], input.size() * sizeof(E)); | 63 memcpy(output->storage(), &input.storage()[0], input.size() * sizeof(E)); |
64 } | 64 } |
65 static void DeserializeElements(Array_Data<F>* input, | 65 static bool DeserializeElements(Array_Data<F>* input, |
66 Array<E>* output, | 66 Array<E>* output, |
67 SerializationContext* context) { | 67 SerializationContext* context) { |
68 std::vector<E> result(input->size()); | 68 std::vector<E> result(input->size()); |
69 if (input->size()) | 69 if (input->size()) |
70 memcpy(&result[0], input->storage(), input->size() * sizeof(E)); | 70 memcpy(&result[0], input->storage(), input->size() * sizeof(E)); |
71 output->Swap(&result); | 71 output->Swap(&result); |
| 72 return true; |
72 } | 73 } |
73 }; | 74 }; |
74 | 75 |
75 // Serializes and deserializes arrays of bools. | 76 // Serializes and deserializes arrays of bools. |
76 template <> | 77 template <> |
77 struct ArraySerializer<bool, bool, false> { | 78 struct ArraySerializer<bool, bool, false> { |
78 static size_t GetSerializedSize(const Array<bool>& input) { | 79 static size_t GetSerializedSize(const Array<bool>& input) { |
79 return sizeof(Array_Data<bool>) + Align((input.size() + 7) / 8); | 80 return sizeof(Array_Data<bool>) + Align((input.size() + 7) / 8); |
80 } | 81 } |
81 | 82 |
82 static void SerializeElements(Array<bool> input, | 83 static void SerializeElements(Array<bool> input, |
83 Buffer* buf, | 84 Buffer* buf, |
84 Array_Data<bool>* output, | 85 Array_Data<bool>* output, |
85 const ArrayValidateParams* validate_params) { | 86 const ArrayValidateParams* validate_params) { |
86 MOJO_DCHECK(!validate_params->element_is_nullable) | 87 MOJO_DCHECK(!validate_params->element_is_nullable) |
87 << "Primitive type should be non-nullable"; | 88 << "Primitive type should be non-nullable"; |
88 MOJO_DCHECK(!validate_params->element_validate_params) | 89 MOJO_DCHECK(!validate_params->element_validate_params) |
89 << "Primitive type should not have array validate params"; | 90 << "Primitive type should not have array validate params"; |
90 | 91 |
91 // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy? | 92 // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy? |
92 for (size_t i = 0; i < input.size(); ++i) | 93 for (size_t i = 0; i < input.size(); ++i) |
93 output->at(i) = input[i]; | 94 output->at(i) = input[i]; |
94 } | 95 } |
95 static void DeserializeElements(Array_Data<bool>* input, | 96 static bool DeserializeElements(Array_Data<bool>* input, |
96 Array<bool>* output, | 97 Array<bool>* output, |
97 SerializationContext* context) { | 98 SerializationContext* context) { |
98 Array<bool> result(input->size()); | 99 Array<bool> result(input->size()); |
99 // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy? | 100 // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy? |
100 for (size_t i = 0; i < input->size(); ++i) | 101 for (size_t i = 0; i < input->size(); ++i) |
101 result.at(i) = input->at(i); | 102 result.at(i) = input->at(i); |
102 output->Swap(&result); | 103 output->Swap(&result); |
| 104 return true; |
103 } | 105 } |
104 }; | 106 }; |
105 | 107 |
106 // Serializes and deserializes arrays of handles. | 108 // Serializes and deserializes arrays of handles. |
107 template <typename H> | 109 template <typename H> |
108 struct ArraySerializer<ScopedHandleBase<H>, H, false> { | 110 struct ArraySerializer<ScopedHandleBase<H>, H, false> { |
109 static size_t GetSerializedSize(const Array<ScopedHandleBase<H>>& input) { | 111 static size_t GetSerializedSize(const Array<ScopedHandleBase<H>>& input) { |
110 return sizeof(Array_Data<H>) + Align(input.size() * sizeof(H)); | 112 return sizeof(Array_Data<H>) + Align(input.size() * sizeof(H)); |
111 } | 113 } |
112 | 114 |
113 static void SerializeElements(Array<ScopedHandleBase<H>> input, | 115 static void SerializeElements(Array<ScopedHandleBase<H>> input, |
114 Buffer* buf, | 116 Buffer* buf, |
115 Array_Data<H>* output, | 117 Array_Data<H>* output, |
116 const ArrayValidateParams* validate_params) { | 118 const ArrayValidateParams* validate_params) { |
117 MOJO_DCHECK(!validate_params->element_validate_params) | 119 MOJO_DCHECK(!validate_params->element_validate_params) |
118 << "Handle type should not have array validate params"; | 120 << "Handle type should not have array validate params"; |
119 | 121 |
120 for (size_t i = 0; i < input.size(); ++i) { | 122 for (size_t i = 0; i < input.size(); ++i) { |
121 output->at(i) = input[i].release(); // Transfer ownership of the handle. | 123 output->at(i) = input[i].release(); // Transfer ownership of the handle. |
122 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( | 124 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( |
123 !validate_params->element_is_nullable && !output->at(i).is_valid(), | 125 !validate_params->element_is_nullable && !output->at(i).is_valid(), |
124 VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE, | 126 VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE, |
125 MakeMessageWithArrayIndex( | 127 MakeMessageWithArrayIndex( |
126 "invalid handle in array expecting valid handles", input.size(), | 128 "invalid handle in array expecting valid handles", input.size(), |
127 i)); | 129 i)); |
128 } | 130 } |
129 } | 131 } |
130 static void DeserializeElements(Array_Data<H>* input, | 132 static bool DeserializeElements(Array_Data<H>* input, |
131 Array<ScopedHandleBase<H>>* output, | 133 Array<ScopedHandleBase<H>>* output, |
132 SerializationContext* context) { | 134 SerializationContext* context) { |
133 Array<ScopedHandleBase<H>> result(input->size()); | 135 Array<ScopedHandleBase<H>> result(input->size()); |
134 for (size_t i = 0; i < input->size(); ++i) | 136 for (size_t i = 0; i < input->size(); ++i) |
135 result.at(i) = MakeScopedHandle(FetchAndReset(&input->at(i))); | 137 result.at(i) = MakeScopedHandle(FetchAndReset(&input->at(i))); |
136 output->Swap(&result); | 138 output->Swap(&result); |
| 139 return true; |
137 } | 140 } |
138 }; | 141 }; |
139 | 142 |
140 // This template must only apply to pointer mojo entity (structs and arrays). | 143 // This template must only apply to pointer mojo entity (structs and arrays). |
141 // This is done by ensuring that WrapperTraits<S>::DataType is a pointer. | 144 // This is done by ensuring that WrapperTraits<S>::DataType is a pointer. |
142 template <typename S> | 145 template <typename S> |
143 struct ArraySerializer< | 146 struct ArraySerializer< |
144 S, | 147 S, |
145 typename EnableIf<IsPointer<typename WrapperTraits<S>::DataType>::value, | 148 typename EnableIf<IsPointer<typename WrapperTraits<S>::DataType>::value, |
146 typename WrapperTraits<S>::DataType>::type, | 149 typename WrapperTraits<S>::DataType>::type, |
(...skipping 17 matching lines...) Expand all Loading... |
164 SerializeCaller<S>::Run(input[i].Pass(), buf, &element, | 167 SerializeCaller<S>::Run(input[i].Pass(), buf, &element, |
165 validate_params->element_validate_params); | 168 validate_params->element_validate_params); |
166 output->at(i) = element; | 169 output->at(i) = element; |
167 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( | 170 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( |
168 !validate_params->element_is_nullable && !element, | 171 !validate_params->element_is_nullable && !element, |
169 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, | 172 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, |
170 MakeMessageWithArrayIndex("null in array expecting valid pointers", | 173 MakeMessageWithArrayIndex("null in array expecting valid pointers", |
171 input.size(), i)); | 174 input.size(), i)); |
172 } | 175 } |
173 } | 176 } |
174 static void DeserializeElements(Array_Data<S_Data*>* input, | 177 static bool DeserializeElements(Array_Data<S_Data*>* input, |
175 Array<S>* output, | 178 Array<S>* output, |
176 SerializationContext* context) { | 179 SerializationContext* context) { |
| 180 bool success = true; |
177 Array<S> result(input->size()); | 181 Array<S> result(input->size()); |
178 for (size_t i = 0; i < input->size(); ++i) { | 182 for (size_t i = 0; i < input->size(); ++i) { |
179 Deserialize_(input->at(i), &result[i], context); | 183 // Note that we rely on complete deserialization taking place in order to |
| 184 // transfer ownership of all encoded handles. Therefore we don't |
| 185 // short-circuit on failure here. |
| 186 if (!Deserialize_(input->at(i), &result[i], context)) |
| 187 success = false; |
180 } | 188 } |
181 output->Swap(&result); | 189 output->Swap(&result); |
| 190 return success; |
182 } | 191 } |
183 | 192 |
184 private: | 193 private: |
185 template <typename T> | 194 template <typename T> |
186 struct SerializeCaller { | 195 struct SerializeCaller { |
187 static void Run(T input, | 196 static void Run(T input, |
188 Buffer* buf, | 197 Buffer* buf, |
189 typename WrapperTraits<T>::DataType* output, | 198 typename WrapperTraits<T>::DataType* output, |
190 const ArrayValidateParams* validate_params) { | 199 const ArrayValidateParams* validate_params) { |
191 MOJO_DCHECK(!validate_params) | 200 MOJO_DCHECK(!validate_params) |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
237 U_Data* result = output->storage() + i; | 246 U_Data* result = output->storage() + i; |
238 SerializeUnion_(input[i].Pass(), buf, &result, true); | 247 SerializeUnion_(input[i].Pass(), buf, &result, true); |
239 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( | 248 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( |
240 !validate_params->element_is_nullable && output->at(i).is_null(), | 249 !validate_params->element_is_nullable && output->at(i).is_null(), |
241 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, | 250 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, |
242 MakeMessageWithArrayIndex("null in array expecting valid unions", | 251 MakeMessageWithArrayIndex("null in array expecting valid unions", |
243 input.size(), i)); | 252 input.size(), i)); |
244 } | 253 } |
245 } | 254 } |
246 | 255 |
247 static void DeserializeElements(Array_Data<U_Data>* input, | 256 static bool DeserializeElements(Array_Data<U_Data>* input, |
248 Array<U>* output, | 257 Array<U>* output, |
249 SerializationContext* context) { | 258 SerializationContext* context) { |
| 259 bool success = true; |
250 Array<U> result(input->size()); | 260 Array<U> result(input->size()); |
251 for (size_t i = 0; i < input->size(); ++i) { | 261 for (size_t i = 0; i < input->size(); ++i) { |
252 Deserialize_(&input->at(i), &result[i], context); | 262 // Note that we rely on complete deserialization taking place in order to |
| 263 // transfer ownership of all encoded handles. Therefore we don't |
| 264 // short-circuit on failure here. |
| 265 if (!Deserialize_(&input->at(i), &result[i], context)) |
| 266 success = false; |
253 } | 267 } |
254 output->Swap(&result); | 268 output->Swap(&result); |
| 269 return success; |
255 } | 270 } |
256 }; | 271 }; |
257 | 272 |
258 // Handles serialization and deserialization of arrays of strings. | 273 // Handles serialization and deserialization of arrays of strings. |
259 template <> | 274 template <> |
260 struct ArraySerializer<String, String_Data*> { | 275 struct ArraySerializer<String, String_Data*> { |
261 static size_t GetSerializedSize(const Array<String>& input) { | 276 static size_t GetSerializedSize(const Array<String>& input) { |
262 size_t size = | 277 size_t size = |
263 sizeof(Array_Data<String_Data*>) + input.size() * sizeof(StringPointer); | 278 sizeof(Array_Data<String_Data*>) + input.size() * sizeof(StringPointer); |
264 for (size_t i = 0; i < input.size(); ++i) | 279 for (size_t i = 0; i < input.size(); ++i) |
(...skipping 16 matching lines...) Expand all Loading... |
281 String_Data* element; | 296 String_Data* element; |
282 Serialize_(input[i], buf, &element); | 297 Serialize_(input[i], buf, &element); |
283 output->at(i) = element; | 298 output->at(i) = element; |
284 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( | 299 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( |
285 !validate_params->element_is_nullable && !element, | 300 !validate_params->element_is_nullable && !element, |
286 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, | 301 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, |
287 MakeMessageWithArrayIndex("null in array expecting valid strings", | 302 MakeMessageWithArrayIndex("null in array expecting valid strings", |
288 input.size(), i)); | 303 input.size(), i)); |
289 } | 304 } |
290 } | 305 } |
291 static void DeserializeElements(Array_Data<String_Data*>* input, | 306 static bool DeserializeElements(Array_Data<String_Data*>* input, |
292 Array<String>* output, | 307 Array<String>* output, |
293 SerializationContext* context) { | 308 SerializationContext* context) { |
294 Array<String> result(input->size()); | 309 Array<String> result(input->size()); |
295 for (size_t i = 0; i < input->size(); ++i) | 310 for (size_t i = 0; i < input->size(); ++i) { |
296 Deserialize_(input->at(i), &result[i], context); | 311 // It's OK to short-circuit here since string data cannot contain handles. |
| 312 if (!Deserialize_(input->at(i), &result[i], context)) |
| 313 return false; |
| 314 } |
297 output->Swap(&result); | 315 output->Swap(&result); |
| 316 return true; |
298 } | 317 } |
299 }; | 318 }; |
300 | 319 |
301 } // namespace internal | 320 } // namespace internal |
302 | 321 |
303 template <typename E> | 322 template <typename E> |
304 inline size_t GetSerializedSize_(const Array<E>& input) { | 323 inline size_t GetSerializedSize_(const Array<E>& input) { |
305 if (!input) | 324 if (!input) |
306 return 0; | 325 return 0; |
307 typedef typename internal::WrapperTraits<E>::DataType F; | 326 typedef typename internal::WrapperTraits<E>::DataType F; |
(...skipping 21 matching lines...) Expand all Loading... |
329 internal::ArraySerializer<E, F>::SerializeElements( | 348 internal::ArraySerializer<E, F>::SerializeElements( |
330 std::move(input), buf, result, validate_params); | 349 std::move(input), buf, result, validate_params); |
331 } | 350 } |
332 *output = result; | 351 *output = result; |
333 } else { | 352 } else { |
334 *output = nullptr; | 353 *output = nullptr; |
335 } | 354 } |
336 } | 355 } |
337 | 356 |
338 template <typename E, typename F> | 357 template <typename E, typename F> |
339 inline void Deserialize_(internal::Array_Data<F>* input, | 358 inline bool Deserialize_(internal::Array_Data<F>* input, |
340 Array<E>* output, | 359 Array<E>* output, |
341 internal::SerializationContext* context) { | 360 internal::SerializationContext* context) { |
342 if (input) { | 361 if (input) { |
343 internal::ArraySerializer<E, F>::DeserializeElements(input, output, | 362 if (!internal::ArraySerializer<E, F>::DeserializeElements(input, output, |
344 context); | 363 context)) { |
| 364 return false; |
| 365 } |
345 } else { | 366 } else { |
346 output->reset(); | 367 output->reset(); |
347 } | 368 } |
| 369 return true; |
348 } | 370 } |
349 | 371 |
350 } // namespace mojo | 372 } // namespace mojo |
351 | 373 |
352 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_ | 374 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_ |
OLD | NEW |