Chromium Code Reviews| 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 | |
| 10 #include <vector> | 9 #include <vector> |
| 11 | 10 |
| 12 #include "mojo/public/c/system/macros.h" | 11 #include "mojo/public/c/system/macros.h" |
| 13 #include "mojo/public/cpp/bindings/lib/array_internal.h" | 12 #include "mojo/public/cpp/bindings/lib/array_internal.h" |
| 14 #include "mojo/public/cpp/bindings/lib/map_serialization.h" | 13 #include "mojo/public/cpp/bindings/lib/bindings_internal.h" |
| 14 #include "mojo/public/cpp/bindings/lib/iterator_util.h" | |
| 15 #include "mojo/public/cpp/bindings/lib/map_data_internal.h" | |
| 16 #include "mojo/public/cpp/bindings/lib/map_serialization_forward.h" | |
| 15 #include "mojo/public/cpp/bindings/lib/string_serialization.h" | 17 #include "mojo/public/cpp/bindings/lib/string_serialization.h" |
| 16 #include "mojo/public/cpp/bindings/lib/template_util.h" | 18 #include "mojo/public/cpp/bindings/lib/template_util.h" |
| 17 #include "mojo/public/cpp/bindings/lib/validation_errors.h" | 19 #include "mojo/public/cpp/bindings/lib/validation_errors.h" |
| 18 | 20 |
| 19 namespace mojo { | 21 namespace mojo { |
| 20 | |
| 21 template <typename E> | |
| 22 inline size_t GetSerializedSize_(const Array<E>& input); | |
| 23 | |
| 24 template <typename E, typename F> | |
| 25 inline void SerializeArray_( | |
| 26 Array<E> input, | |
| 27 internal::Buffer* buf, | |
| 28 internal::Array_Data<F>** output, | |
| 29 const internal::ArrayValidateParams* validate_params); | |
| 30 | |
| 31 template <typename E, typename F> | |
| 32 inline void Deserialize_(internal::Array_Data<F>* data, Array<E>* output); | |
| 33 | |
| 34 namespace internal { | 22 namespace internal { |
| 35 | 23 |
| 24 // The ArraySerializer template contains static methods for serializing |Array|s | |
| 25 // of various types. These methods include: | |
| 26 // * size_t GetSerializedSize(..) | |
| 27 // Computes the size of the serialized version of the |Array|. | |
| 28 // * void SerializeElementsWithIterator(..) | |
| 29 // Takes an iterator and |num_elements| representing an |Array| (or | |
| 30 // possibly a |Map|), and serializes it. | |
| 31 // * void SerializeElements(..) | |
| 32 // Takes an |Array| directly and serializes it. This usually calls into | |
| 33 // SerializeElementsWithIterator(), except for an |Array| of PODs which | |
| 34 // will directly memcpy the PODs as an optimization. | |
| 36 template <typename E, | 35 template <typename E, |
| 37 typename F, | 36 typename F, |
| 38 bool is_union = | 37 bool is_union = |
| 39 IsUnionDataType<typename RemovePointer<F>::type>::value> | 38 IsUnionDataType<typename RemovePointer<F>::type>::value> |
| 40 struct ArraySerializer; | 39 struct ArraySerializer; |
| 41 | 40 |
| 42 // Handles serialization and deserialization of arrays of pod types. | 41 // Handles serialization and deserialization of arrays of pod types. |
| 43 template <typename E, typename F> | 42 template <typename E, typename F> |
| 44 struct ArraySerializer<E, F, false> { | 43 struct ArraySerializer<E, F, false> { |
| 45 static_assert(sizeof(E) == sizeof(F), "Incorrect array serializer"); | 44 static_assert(sizeof(E) == sizeof(F), "Incorrect array serializer"); |
| 46 static size_t GetSerializedSize(const Array<E>& input) { | 45 static size_t GetSerializedSize(const Array<E>& input) { |
| 47 return sizeof(Array_Data<F>) + Align(input.size() * sizeof(E)); | 46 return sizeof(Array_Data<F>) + Align(input.size() * sizeof(E)); |
| 48 } | 47 } |
| 49 | 48 |
| 50 static void SerializeElements(Array<E> input, | 49 template <typename Iterator> |
| 50 static void SerializeElementsWithIterator( | |
| 51 Iterator it, | |
| 52 size_t num_elements, | |
| 53 Buffer* buf, | |
| 54 Array_Data<F>* output, | |
| 55 const ArrayValidateParams* validate_params) { | |
| 56 MOJO_DCHECK(!validate_params->element_is_nullable) | |
| 57 << "Primitive type should be non-nullable"; | |
| 58 MOJO_DCHECK(!validate_params->element_validate_params) | |
| 59 << "Primitive type should not have array validate params"; | |
| 60 if (num_elements) { | |
|
viettrungluu
2015/09/23 23:20:24
This seems redundant.
vardhan
2015/09/25 19:33:05
oops
| |
| 61 for (size_t i = 0; i < num_elements; ++i, ++it) { | |
|
viettrungluu
2015/09/23 23:20:24
nit: For consistency with other stuff in this file
vardhan
2015/09/25 19:33:05
Done.
| |
| 62 output->at(i) = *it; | |
| 63 } | |
| 64 } | |
| 65 } | |
| 66 | |
| 67 // We can optimize serializing PODs by |memcpy|ing directly. | |
| 68 static void SerializeElements(Array<E>* input, | |
| 51 Buffer* buf, | 69 Buffer* buf, |
| 52 Array_Data<F>* output, | 70 Array_Data<F>* output, |
| 53 const ArrayValidateParams* validate_params) { | 71 const ArrayValidateParams* validate_params) { |
| 54 MOJO_DCHECK(!validate_params->element_is_nullable) | 72 MOJO_DCHECK(!validate_params->element_is_nullable) |
| 55 << "Primitive type should be non-nullable"; | 73 << "Primitive type should be non-nullable"; |
| 56 MOJO_DCHECK(!validate_params->element_validate_params) | 74 MOJO_DCHECK(!validate_params->element_validate_params) |
| 57 << "Primitive type should not have array validate params"; | 75 << "Primitive type should not have array validate params"; |
| 76 if (input->size()) { | |
|
viettrungluu
2015/09/23 23:20:24
Assuming that output->storage() and &input->storag
vardhan
2015/09/25 19:33:05
output->storage() could point to memory we shouldn
| |
| 77 memcpy(output->storage(), &input->storage()[0], | |
| 78 input->size() * sizeof(E)); | |
| 79 } | |
| 80 } | |
| 58 | 81 |
| 59 if (input.size()) | |
| 60 memcpy(output->storage(), &input.storage()[0], input.size() * sizeof(E)); | |
| 61 } | |
| 62 static void DeserializeElements(Array_Data<F>* input, Array<E>* output) { | 82 static void DeserializeElements(Array_Data<F>* input, Array<E>* output) { |
| 63 std::vector<E> result(input->size()); | 83 std::vector<E> result(input->size()); |
| 64 if (input->size()) | 84 if (input->size()) |
| 65 memcpy(&result[0], input->storage(), input->size() * sizeof(E)); | 85 memcpy(&result[0], input->storage(), input->size() * sizeof(E)); |
| 66 output->Swap(&result); | 86 output->Swap(&result); |
| 67 } | 87 } |
| 68 }; | 88 }; |
| 69 | 89 |
| 70 // Serializes and deserializes arrays of bools. | 90 // Serializes and deserializes arrays of bools. |
| 71 template <> | 91 template <> |
| 72 struct ArraySerializer<bool, bool, false> { | 92 struct ArraySerializer<bool, bool, false> { |
| 73 static size_t GetSerializedSize(const Array<bool>& input) { | 93 static size_t GetSerializedSize(const Array<bool>& input) { |
| 74 return sizeof(Array_Data<bool>) + Align((input.size() + 7) / 8); | 94 return sizeof(Array_Data<bool>) + Align((input.size() + 7) / 8); |
| 75 } | 95 } |
| 76 | 96 |
| 77 static void SerializeElements(Array<bool> input, | 97 template <typename Iterator> |
| 78 Buffer* buf, | 98 static void SerializeElementsWithIterator( |
| 79 Array_Data<bool>* output, | 99 Iterator it, |
| 80 const ArrayValidateParams* validate_params) { | 100 size_t num_elements, |
| 101 Buffer* buf, | |
| 102 Array_Data<bool>* output, | |
| 103 const ArrayValidateParams* validate_params) { | |
| 81 MOJO_DCHECK(!validate_params->element_is_nullable) | 104 MOJO_DCHECK(!validate_params->element_is_nullable) |
| 82 << "Primitive type should be non-nullable"; | 105 << "Primitive type should be non-nullable"; |
| 83 MOJO_DCHECK(!validate_params->element_validate_params) | 106 MOJO_DCHECK(!validate_params->element_validate_params) |
| 84 << "Primitive type should not have array validate params"; | 107 << "Primitive type should not have array validate params"; |
| 85 | 108 |
| 86 // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy? | 109 // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy? |
| 87 for (size_t i = 0; i < input.size(); ++i) | 110 for (size_t i = 0; i < num_elements; ++i, ++it) { |
|
viettrungluu
2015/09/23 23:20:24
Omit {}.
(Probably do so elsewhere too.)
vardhan
2015/09/25 19:33:05
Done.
| |
| 88 output->at(i) = input[i]; | 111 output->at(i) = *it; |
| 112 } | |
| 89 } | 113 } |
| 114 | |
| 115 static void SerializeElements(Array<bool>* input, | |
| 116 Buffer* buf, | |
| 117 Array_Data<bool>* output, | |
| 118 const ArrayValidateParams* validate_params) { | |
| 119 SerializeElementsWithIterator(input->begin(), input->size(), buf, output, | |
| 120 validate_params); | |
| 121 } | |
| 122 | |
| 90 static void DeserializeElements(Array_Data<bool>* input, | 123 static void DeserializeElements(Array_Data<bool>* input, |
| 91 Array<bool>* output) { | 124 Array<bool>* output) { |
| 92 Array<bool> result(input->size()); | 125 Array<bool> result(input->size()); |
| 93 // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy? | 126 // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy? |
| 94 for (size_t i = 0; i < input->size(); ++i) | 127 for (size_t i = 0; i < input->size(); ++i) |
| 95 result.at(i) = input->at(i); | 128 result.at(i) = input->at(i); |
| 96 output->Swap(&result); | 129 output->Swap(&result); |
| 97 } | 130 } |
| 98 }; | 131 }; |
| 99 | 132 |
| 100 // Serializes and deserializes arrays of handles. | 133 // Serializes and deserializes arrays of handles. |
| 101 template <typename H> | 134 template <typename H> |
| 102 struct ArraySerializer<ScopedHandleBase<H>, H, false> { | 135 struct ArraySerializer<ScopedHandleBase<H>, H, false> { |
| 103 static size_t GetSerializedSize(const Array<ScopedHandleBase<H>>& input) { | 136 static size_t GetSerializedSize(const Array<ScopedHandleBase<H>>& input) { |
| 104 return sizeof(Array_Data<H>) + Align(input.size() * sizeof(H)); | 137 return sizeof(Array_Data<H>) + Align(input.size() * sizeof(H)); |
| 105 } | 138 } |
| 106 | 139 |
| 107 static void SerializeElements(Array<ScopedHandleBase<H>> input, | 140 template <typename Iterator> |
| 108 Buffer* buf, | 141 static void SerializeElementsWithIterator( |
| 109 Array_Data<H>* output, | 142 Iterator it, |
| 110 const ArrayValidateParams* validate_params) { | 143 size_t num_elements, |
| 144 Buffer* buf, | |
| 145 Array_Data<H>* output, | |
| 146 const ArrayValidateParams* validate_params) { | |
| 111 MOJO_DCHECK(!validate_params->element_validate_params) | 147 MOJO_DCHECK(!validate_params->element_validate_params) |
| 112 << "Handle type should not have array validate params"; | 148 << "Handle type should not have array validate params"; |
| 113 | 149 |
| 114 for (size_t i = 0; i < input.size(); ++i) { | 150 for (size_t i = 0; i < num_elements; ++i, ++it) { |
| 115 output->at(i) = input[i].release(); // Transfer ownership of the handle. | 151 // Transfer ownership of the handle. |
| 152 output->at(i) = (*it).release(); | |
| 116 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( | 153 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( |
| 117 !validate_params->element_is_nullable && !output->at(i).is_valid(), | 154 !validate_params->element_is_nullable && !output->at(i).is_valid(), |
| 118 VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE, | 155 VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE, |
| 119 MakeMessageWithArrayIndex( | 156 MakeMessageWithArrayIndex( |
| 120 "invalid handle in array expecting valid handles", input.size(), | 157 "invalid handle in array expecting valid handles", num_elements, |
| 121 i)); | 158 i)); |
| 122 } | 159 } |
| 123 } | 160 } |
| 161 | |
| 162 static void SerializeElements(Array<ScopedHandleBase<H>>* input, | |
| 163 Buffer* buf, | |
| 164 Array_Data<H>* output, | |
| 165 const ArrayValidateParams* validate_params) { | |
| 166 SerializeElementsWithIterator(input->begin(), input->size(), buf, output, | |
| 167 validate_params); | |
| 168 } | |
| 169 | |
| 124 static void DeserializeElements(Array_Data<H>* input, | 170 static void DeserializeElements(Array_Data<H>* input, |
| 125 Array<ScopedHandleBase<H>>* output) { | 171 Array<ScopedHandleBase<H>>* output) { |
| 126 Array<ScopedHandleBase<H>> result(input->size()); | 172 Array<ScopedHandleBase<H>> result(input->size()); |
| 127 for (size_t i = 0; i < input->size(); ++i) | 173 for (size_t i = 0; i < input->size(); ++i) |
| 128 result.at(i) = MakeScopedHandle(FetchAndReset(&input->at(i))); | 174 result.at(i) = MakeScopedHandle(FetchAndReset(&input->at(i))); |
| 129 output->Swap(&result); | 175 output->Swap(&result); |
| 130 } | 176 } |
| 131 }; | 177 }; |
| 132 | 178 |
| 133 // This template must only apply to pointer mojo entity (structs and arrays). | 179 // SerializeCaller template is used by |ArraySerializer| to dispatch a serialize |
| 134 // This is done by ensuring that WrapperTraits<S>::DataType is a pointer. | 180 // call on a non-POD type. This template is defined outside |ArraySerializer| |
| 181 // since you cannot specialize a struct within a class definition. | |
| 182 template <typename T> | |
| 183 struct SerializeCaller { | |
| 184 static void Run(T* input, | |
| 185 Buffer* buf, | |
| 186 typename WrapperTraits<T>::DataType* output, | |
| 187 const ArrayValidateParams* validate_params) { | |
| 188 MOJO_DCHECK(!validate_params) | |
| 189 << "Struct type should not have array validate params"; | |
| 190 Serialize_(UnwrapStructPtr<T>::value(*input), buf, output); | |
| 191 } | |
| 192 }; | |
| 193 | |
| 194 template <> | |
| 195 struct SerializeCaller<String> { | |
| 196 static void Run(const String* input, | |
| 197 Buffer* buf, | |
| 198 String_Data** output, | |
| 199 const ArrayValidateParams* validate_params) { | |
| 200 MOJO_DCHECK(validate_params && !validate_params->element_validate_params && | |
| 201 !validate_params->element_is_nullable && | |
| 202 validate_params->expected_num_elements == 0) | |
| 203 << "String type has unexpected array validate params"; | |
| 204 SerializeString_(*input, buf, output); | |
| 205 } | |
| 206 }; | |
| 207 | |
| 208 template <typename T> | |
| 209 struct SerializeCaller<Array<T>> { | |
| 210 static void Run(Array<T>* input, | |
| 211 Buffer* buf, | |
| 212 typename Array<T>::Data_** output, | |
| 213 const ArrayValidateParams* validate_params) { | |
| 214 SerializeArray_(input, buf, output, validate_params); | |
| 215 } | |
| 216 }; | |
| 217 | |
| 218 template <typename Key, typename Value> | |
| 219 struct SerializeCaller<Map<Key, Value>> { | |
| 220 static void Run(Map<Key, Value>* input, | |
| 221 Buffer* buf, | |
| 222 typename Map<Key, Value>::Data_** output, | |
| 223 const ArrayValidateParams* validate_params) { | |
| 224 SerializeMap_(input, buf, output, validate_params); | |
| 225 } | |
| 226 }; | |
| 227 | |
| 228 template <typename T, | |
| 229 bool IsStructPtr = IsSpecializationOf<StructPtr, T>::value || | |
| 230 IsSpecializationOf<InlinedStructPtr, T>::value> | |
| 231 struct DeserializeCaller; | |
| 232 | |
| 233 template <typename T> | |
| 234 struct DeserializeCaller<T, false> { | |
| 235 static void Run(typename WrapperTraits<T>::DataType input, T* output) { | |
| 236 Deserialize_(input, output); | |
| 237 } | |
| 238 }; | |
| 239 | |
| 240 template <typename T> | |
| 241 struct DeserializeCaller<T, true> { | |
| 242 static void Run(typename WrapperTraits<T>::DataType input, T* output) { | |
| 243 // Since Deserialize_ takes in a |Struct*| (not |StructPtr|), we need to | |
| 244 // initialize the |StructPtr| here before deserializing into its underlying | |
| 245 // data. | |
| 246 // TODO(vardhan): Either all containers, or just Deserialize_(), should | |
| 247 // support taking in an allocator. | |
| 248 using UnwrapedStructType = typename RemoveStructPtr<T>::type; | |
| 249 *output = UnwrapedStructType::New(); | |
| 250 Deserialize_(input, output->get()); | |
| 251 } | |
| 252 }; | |
| 253 | |
| 254 // This template must only apply to pointer mojo entity (structs, arrays, | |
| 255 // strings). This is done by ensuring that WrapperTraits<S>::DataType is a | |
| 256 // pointer. | |
| 135 template <typename S> | 257 template <typename S> |
| 136 struct ArraySerializer< | 258 struct ArraySerializer< |
| 137 S, | 259 S, |
| 138 typename EnableIf<IsPointer<typename WrapperTraits<S>::DataType>::value, | 260 typename EnableIf<IsPointer<typename WrapperTraits<S>::DataType>::value, |
| 139 typename WrapperTraits<S>::DataType>::type, | 261 typename WrapperTraits<S>::DataType>::type, |
| 140 false> { | 262 false> { |
| 141 typedef | 263 typedef |
| 142 typename RemovePointer<typename WrapperTraits<S>::DataType>::type S_Data; | 264 typename RemovePointer<typename WrapperTraits<S>::DataType>::type S_Data; |
| 143 static size_t GetSerializedSize(const Array<S>& input) { | 265 static size_t GetSerializedSize(const Array<S>& input) { |
| 144 size_t size = sizeof(Array_Data<S_Data*>) + | 266 size_t size = sizeof(Array_Data<S_Data*>) + |
| 145 input.size() * sizeof(StructPointer<S_Data>); | 267 input.size() * sizeof(StructPointer<S_Data>); |
| 146 for (size_t i = 0; i < input.size(); ++i) | 268 for (size_t i = 0; i < input.size(); ++i) |
| 147 size += GetSerializedSize_(input[i]); | 269 size += GetSerializedSize_(*(UnwrapConstStructPtr<S>::value(input[i]))); |
| 148 return size; | 270 return size; |
| 149 } | 271 } |
| 150 | 272 |
| 151 static void SerializeElements(Array<S> input, | 273 template <typename Iterator> |
| 152 Buffer* buf, | 274 static void SerializeElementsWithIterator( |
| 153 Array_Data<S_Data*>* output, | 275 Iterator it, |
| 154 const ArrayValidateParams* validate_params) { | 276 size_t num_elements, |
| 155 for (size_t i = 0; i < input.size(); ++i) { | 277 Buffer* buf, |
| 278 Array_Data<S_Data*>* output, | |
| 279 const ArrayValidateParams* validate_params) { | |
| 280 for (size_t i = 0; i < num_elements; ++i, ++it) { | |
| 156 S_Data* element; | 281 S_Data* element; |
| 157 SerializeCaller<S>::Run(input[i].Pass(), buf, &element, | 282 SerializeCaller<S>::Run(&(*it), buf, &element, |
| 158 validate_params->element_validate_params); | 283 validate_params->element_validate_params); |
| 159 output->at(i) = element; | 284 output->at(i) = element; |
| 160 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( | 285 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( |
| 161 !validate_params->element_is_nullable && !element, | 286 !validate_params->element_is_nullable && !element, |
| 162 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, | 287 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, |
| 163 MakeMessageWithArrayIndex("null in array expecting valid pointers", | 288 MakeMessageWithArrayIndex("null in array expecting valid pointers", |
| 164 input.size(), i)); | 289 num_elements, i)); |
| 165 } | 290 } |
| 166 } | 291 } |
| 292 | |
| 293 static void SerializeElements(Array<S>* input, | |
| 294 Buffer* buf, | |
| 295 Array_Data<S_Data*>* output, | |
| 296 const ArrayValidateParams* validate_params) { | |
| 297 SerializeElementsWithIterator(input->begin(), input->size(), buf, output, | |
| 298 validate_params); | |
| 299 } | |
| 300 | |
| 167 static void DeserializeElements(Array_Data<S_Data*>* input, | 301 static void DeserializeElements(Array_Data<S_Data*>* input, |
| 168 Array<S>* output) { | 302 Array<S>* output) { |
| 169 Array<S> result(input->size()); | 303 Array<S> result(input->size()); |
| 170 for (size_t i = 0; i < input->size(); ++i) { | 304 for (size_t i = 0; i < input->size(); ++i) { |
| 171 Deserialize_(input->at(i), &result[i]); | 305 DeserializeCaller<S>::Run(input->at(i), &result[i]); |
| 172 } | 306 } |
| 173 output->Swap(&result); | 307 output->Swap(&result); |
| 174 } | 308 } |
| 175 | |
| 176 private: | |
| 177 template <typename T> | |
| 178 struct SerializeCaller { | |
| 179 static void Run(T input, | |
| 180 Buffer* buf, | |
| 181 typename WrapperTraits<T>::DataType* output, | |
| 182 const ArrayValidateParams* validate_params) { | |
| 183 MOJO_DCHECK(!validate_params) | |
| 184 << "Struct type should not have array validate params"; | |
| 185 | |
| 186 Serialize_(input.Pass(), buf, output); | |
| 187 } | |
| 188 }; | |
| 189 | |
| 190 template <typename T> | |
| 191 struct SerializeCaller<Array<T>> { | |
| 192 static void Run(Array<T> input, | |
| 193 Buffer* buf, | |
| 194 typename Array<T>::Data_** output, | |
| 195 const ArrayValidateParams* validate_params) { | |
| 196 SerializeArray_(input.Pass(), buf, output, validate_params); | |
| 197 } | |
| 198 }; | |
| 199 | |
| 200 template <typename T, typename U> | |
| 201 struct SerializeCaller<Map<T, U>> { | |
| 202 static void Run(Map<T, U> input, | |
| 203 Buffer* buf, | |
| 204 typename Map<T, U>::Data_** output, | |
| 205 const ArrayValidateParams* validate_params) { | |
| 206 SerializeMap_(input.Pass(), buf, output, validate_params); | |
| 207 } | |
| 208 }; | |
| 209 }; | 309 }; |
| 210 | 310 |
| 211 // Handles serialization and deserialization of arrays of unions. | 311 // Handles serialization and deserialization of arrays of unions. |
| 212 template <typename U, typename U_Data> | 312 template <typename U, typename U_Data> |
| 213 struct ArraySerializer<U, U_Data, true> { | 313 struct ArraySerializer<U, U_Data, true> { |
| 214 static size_t GetSerializedSize(const Array<U>& input) { | 314 static size_t GetSerializedSize(const Array<U>& input) { |
| 215 size_t size = sizeof(Array_Data<U_Data>); | 315 size_t size = sizeof(Array_Data<U_Data>); |
| 216 for (size_t i = 0; i < input.size(); ++i) { | 316 for (size_t i = 0; i < input.size(); ++i) { |
| 217 // GetSerializedSize_ will account for both the data in the union and the | 317 // GetSerializedSize_ will account for both the data in the union and the |
| 218 // space in the array used to hold the union. | 318 // space in the array used to hold the union. |
| 219 size += GetSerializedSize_(input[i], false); | 319 size += GetSerializedSize_(input[i], false); |
| 220 } | 320 } |
| 221 return size; | 321 return size; |
| 222 } | 322 } |
| 223 | 323 |
| 224 static void SerializeElements(Array<U> input, | 324 template <typename Iterator> |
| 225 Buffer* buf, | 325 static void SerializeElementsWithIterator( |
| 226 Array_Data<U_Data>* output, | 326 Iterator it, |
| 227 const ArrayValidateParams* validate_params) { | 327 size_t num_elements, |
| 228 for (size_t i = 0; i < input.size(); ++i) { | 328 Buffer* buf, |
| 329 Array_Data<U_Data>* output, | |
| 330 const ArrayValidateParams* validate_params) { | |
| 331 for (size_t i = 0; i < num_elements; ++i, ++it) { | |
| 229 U_Data* result = output->storage() + i; | 332 U_Data* result = output->storage() + i; |
| 230 SerializeUnion_(input[i].Pass(), buf, &result, true); | 333 SerializeUnion_((*it).get(), buf, &result, true); |
| 231 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( | 334 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( |
| 232 !validate_params->element_is_nullable && output->at(i).is_null(), | 335 !validate_params->element_is_nullable && output->at(i).is_null(), |
| 233 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, | 336 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, |
| 234 MakeMessageWithArrayIndex("null in array expecting valid unions", | 337 MakeMessageWithArrayIndex("null in array expecting valid unions", |
| 235 input.size(), i)); | 338 num_elements, i)); |
| 236 } | 339 } |
| 237 } | 340 } |
| 238 | 341 |
| 342 static void SerializeElements(Array<U>* input, | |
| 343 Buffer* buf, | |
| 344 Array_Data<U_Data>* output, | |
| 345 const ArrayValidateParams* validate_params) { | |
| 346 SerializeElementsWithIterator(input->begin(), input->size(), buf, output, | |
| 347 validate_params); | |
| 348 } | |
| 349 | |
| 239 static void DeserializeElements(Array_Data<U_Data>* input, Array<U>* output) { | 350 static void DeserializeElements(Array_Data<U_Data>* input, Array<U>* output) { |
| 240 Array<U> result(input->size()); | 351 Array<U> result(input->size()); |
| 241 for (size_t i = 0; i < input->size(); ++i) { | 352 for (size_t i = 0; i < input->size(); ++i) { |
| 242 Deserialize_(&input->at(i), &result[i]); | 353 auto& elem = input->at(i); |
| 354 if (!elem.is_null()) { | |
| 355 using UnwrapedUnionType = typename RemoveStructPtr<U>::type; | |
| 356 result[i] = UnwrapedUnionType::New(); | |
| 357 Deserialize_(&elem, result[i].get()); | |
| 358 } | |
| 243 } | 359 } |
| 244 output->Swap(&result); | 360 output->Swap(&result); |
| 245 } | 361 } |
| 246 }; | 362 }; |
| 247 | |
| 248 // Handles serialization and deserialization of arrays of strings. | |
| 249 template <> | |
| 250 struct ArraySerializer<String, String_Data*> { | |
| 251 static size_t GetSerializedSize(const Array<String>& input) { | |
| 252 size_t size = | |
| 253 sizeof(Array_Data<String_Data*>) + input.size() * sizeof(StringPointer); | |
| 254 for (size_t i = 0; i < input.size(); ++i) | |
| 255 size += GetSerializedSize_(input[i]); | |
| 256 return size; | |
| 257 } | |
| 258 | |
| 259 static void SerializeElements(Array<String> input, | |
| 260 Buffer* buf, | |
| 261 Array_Data<String_Data*>* output, | |
| 262 const ArrayValidateParams* validate_params) { | |
| 263 MOJO_DCHECK( | |
| 264 validate_params->element_validate_params && | |
| 265 !validate_params->element_validate_params->element_validate_params && | |
| 266 !validate_params->element_validate_params->element_is_nullable && | |
| 267 validate_params->element_validate_params->expected_num_elements == 0) | |
| 268 << "String type has unexpected array validate params"; | |
| 269 | |
| 270 for (size_t i = 0; i < input.size(); ++i) { | |
| 271 String_Data* element; | |
| 272 Serialize_(input[i], buf, &element); | |
| 273 output->at(i) = element; | |
| 274 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( | |
| 275 !validate_params->element_is_nullable && !element, | |
| 276 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, | |
| 277 MakeMessageWithArrayIndex("null in array expecting valid strings", | |
| 278 input.size(), i)); | |
| 279 } | |
| 280 } | |
| 281 static void DeserializeElements(Array_Data<String_Data*>* input, | |
| 282 Array<String>* output) { | |
| 283 Array<String> result(input->size()); | |
| 284 for (size_t i = 0; i < input->size(); ++i) | |
| 285 Deserialize_(input->at(i), &result[i]); | |
| 286 output->Swap(&result); | |
| 287 } | |
| 288 }; | |
| 289 | 363 |
| 290 } // namespace internal | 364 } // namespace internal |
| 291 | 365 |
| 292 template <typename E> | 366 template <typename E> |
| 293 inline size_t GetSerializedSize_(const Array<E>& input) { | 367 inline size_t GetSerializedSize_(const Array<E>& input) { |
| 294 if (!input) | 368 if (!input) |
| 295 return 0; | 369 return 0; |
| 296 typedef typename internal::WrapperTraits<E>::DataType F; | 370 typedef typename internal::WrapperTraits<E>::DataType F; |
| 297 return internal::ArraySerializer<E, F>::GetSerializedSize(input); | 371 return internal::ArraySerializer<E, F>::GetSerializedSize(input); |
| 298 } | 372 } |
| 299 | 373 |
| 300 template <typename E, typename F> | 374 template <typename E, typename F> |
| 301 inline void SerializeArray_( | 375 inline void SerializeArray_( |
| 302 Array<E> input, | 376 Array<E>* input, |
| 303 internal::Buffer* buf, | 377 internal::Buffer* buf, |
| 304 internal::Array_Data<F>** output, | 378 internal::Array_Data<F>** output, |
| 305 const internal::ArrayValidateParams* validate_params) { | 379 const internal::ArrayValidateParams* validate_params) { |
| 306 if (input) { | 380 if (input && *input) { |
| 307 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( | 381 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( |
| 308 validate_params->expected_num_elements != 0 && | 382 validate_params->expected_num_elements != 0 && |
| 309 input.size() != validate_params->expected_num_elements, | 383 input->size() != validate_params->expected_num_elements, |
| 310 internal::VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER, | 384 internal::VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER, |
| 311 internal::MakeMessageWithExpectedArraySize( | 385 internal::MakeMessageWithExpectedArraySize( |
| 312 "fixed-size array has wrong number of elements", input.size(), | 386 "fixed-size array has wrong number of elements", input->size(), |
| 313 validate_params->expected_num_elements)); | 387 validate_params->expected_num_elements)); |
| 314 | 388 |
| 315 internal::Array_Data<F>* result = | 389 internal::Array_Data<F>* result = |
| 316 internal::Array_Data<F>::New(input.size(), buf); | 390 internal::Array_Data<F>::New(input->size(), buf); |
| 317 if (result) { | 391 if (result) { |
| 318 internal::ArraySerializer<E, F>::SerializeElements( | 392 internal::ArraySerializer<E, F>::SerializeElements(input, buf, result, |
| 319 internal::Forward(input), buf, result, validate_params); | 393 validate_params); |
| 320 } | 394 } |
| 321 *output = result; | 395 *output = result; |
| 322 } else { | 396 } else { |
| 323 *output = nullptr; | 397 *output = nullptr; |
| 324 } | 398 } |
| 325 } | 399 } |
| 326 | 400 |
| 327 template <typename E, typename F> | 401 template <typename E, typename F> |
| 328 inline void Deserialize_(internal::Array_Data<F>* input, Array<E>* output) { | 402 inline void Deserialize_(internal::Array_Data<F>* input, Array<E>* output) { |
| 329 if (input) { | 403 if (input) { |
| 330 internal::ArraySerializer<E, F>::DeserializeElements(input, output); | 404 internal::ArraySerializer<E, F>::DeserializeElements(input, output); |
| 331 } else { | 405 } else { |
| 332 output->reset(); | 406 output->reset(); |
| 333 } | 407 } |
| 334 } | 408 } |
| 335 | 409 |
| 336 } // namespace mojo | 410 } // namespace mojo |
| 337 | 411 |
| 338 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_ | 412 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_ |
| OLD | NEW |