| 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 |