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 <stddef.h> | 8 #include <stddef.h> |
| 9 #include <string.h> // For |memcpy()|. | 9 #include <string.h> // For |memcpy()|. |
| 10 | 10 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 49 ? ArraySerializerType::POINTER | 49 ? ArraySerializerType::POINTER |
| 50 : (IsHandle<DataElement>::value | 50 : (IsHandle<DataElement>::value |
| 51 ? ArraySerializerType::HANDLE | 51 ? ArraySerializerType::HANDLE |
| 52 : (std::is_same<Element, bool>::value | 52 : (std::is_same<Element, bool>::value |
| 53 ? ArraySerializerType::BOOLEAN | 53 ? ArraySerializerType::BOOLEAN |
| 54 : (std::is_enum<Element>::value | 54 : (std::is_enum<Element>::value |
| 55 ? ArraySerializerType::ENUM | 55 ? ArraySerializerType::ENUM |
| 56 : ArraySerializerType::POD)))); | 56 : ArraySerializerType::POD)))); |
| 57 }; | 57 }; |
| 58 | 58 |
| 59 // Used as the UserTypeReader template parameter of ArraySerializer. | 59 template <typename Traits, |
| 60 template <typename MaybeConstUserType> | 60 typename MaybeConstUserType, |
| 61 class ArrayReader { | 61 bool HasGetBegin = |
| 62 HasGetBeginMethod<Traits, MaybeConstUserType>::value> | |
| 63 class ArrayIterator {}; | |
| 64 | |
| 65 // Used as the UserTypeIterator template parameter of ArraySerializer. | |
| 66 template <typename Traits, typename MaybeConstUserType> | |
| 67 class ArrayIterator<Traits, MaybeConstUserType, true> { | |
| 62 public: | 68 public: |
| 63 using UserType = typename std::remove_const<MaybeConstUserType>::type; | 69 using IteratorType = decltype( |
| 64 using Traits = ArrayTraits<UserType>; | 70 CallGetBeginIfExists<Traits>(std::declval<MaybeConstUserType&>())); |
| 65 | 71 |
| 66 explicit ArrayReader(MaybeConstUserType& input) : input_(input) {} | 72 explicit ArrayIterator(MaybeConstUserType& input) |
| 67 ~ArrayReader() {} | 73 : input_(input), iter_(CallGetBeginIfExists<Traits>(input)) {} |
| 74 ~ArrayIterator() {} | |
| 75 | |
| 76 size_t GetSize() const { return Traits::GetSize(input_); } | |
| 77 | |
| 78 using GetNextResult = | |
| 79 decltype(Traits::GetValue(std::declval<IteratorType&>())); | |
| 80 GetNextResult GetNext() { | |
| 81 auto& value = Traits::GetValue(iter_); | |
| 82 Traits::AdvanceIterator(iter_); | |
| 83 return value; | |
| 84 } | |
| 85 | |
| 86 using GetDataIfExistsResult = decltype( | |
| 87 CallGetDataIfExists<Traits>(std::declval<MaybeConstUserType&>())); | |
| 88 GetDataIfExistsResult GetDataIfExists() { | |
| 89 return CallGetDataIfExists<Traits>(input_); | |
| 90 } | |
| 91 | |
| 92 private: | |
| 93 MaybeConstUserType& input_; | |
| 94 IteratorType iter_; | |
| 95 }; | |
| 96 | |
| 97 // Used as the UserTypeIterator template parameter of ArraySerializer. | |
| 98 template <typename Traits, typename MaybeConstUserType> | |
| 99 class ArrayIterator<Traits, MaybeConstUserType, false> { | |
| 100 public: | |
| 101 explicit ArrayIterator(MaybeConstUserType& input) : input_(input), iter_(0) {} | |
| 102 ~ArrayIterator() {} | |
| 68 | 103 |
| 69 size_t GetSize() const { return Traits::GetSize(input_); } | 104 size_t GetSize() const { return Traits::GetSize(input_); } |
| 70 | 105 |
| 71 using GetNextResult = | 106 using GetNextResult = |
| 72 decltype(Traits::GetAt(std::declval<MaybeConstUserType&>(), 0)); | 107 decltype(Traits::GetAt(std::declval<MaybeConstUserType&>(), 0)); |
| 73 GetNextResult GetNext() { | 108 GetNextResult GetNext() { |
| 74 DCHECK_LT(index_, Traits::GetSize(input_)); | 109 DCHECK_LT(iter_, Traits::GetSize(input_)); |
| 75 return Traits::GetAt(input_, index_++); | 110 return Traits::GetAt(input_, iter_++); |
| 76 } | 111 } |
| 77 | 112 |
| 78 using GetDataIfExistsResult = decltype( | 113 using GetDataIfExistsResult = decltype( |
| 79 CallGetDataIfExists<Traits>(std::declval<MaybeConstUserType&>())); | 114 CallGetDataIfExists<Traits>(std::declval<MaybeConstUserType&>())); |
| 80 GetDataIfExistsResult GetDataIfExists() { | 115 GetDataIfExistsResult GetDataIfExists() { |
| 81 return CallGetDataIfExists<Traits>(input_); | 116 return CallGetDataIfExists<Traits>(input_); |
| 82 } | 117 } |
| 83 | 118 |
| 84 private: | 119 private: |
| 85 MaybeConstUserType& input_; | 120 MaybeConstUserType& input_; |
| 86 size_t index_ = 0; | 121 size_t iter_; |
| 87 }; | 122 }; |
| 88 | 123 |
| 89 // ArraySerializer is also used to serialize map keys and values. Therefore, it | 124 // ArraySerializer is also used to serialize map keys and values. Therefore, it |
| 90 // has a UserTypeReader parameter which is an adaptor for reading to hide the | 125 // has a UserTypeIterator parameter which is an adaptor for reading to hide the |
| 91 // difference between ArrayTraits and MapTraits. | 126 // difference between ArrayTraits and MapTraits. |
| 92 template <typename MojomType, | 127 template <typename MojomType, |
| 93 typename MaybeConstUserType, | 128 typename MaybeConstUserType, |
| 94 typename UserTypeReader, | 129 typename UserTypeIterator, |
| 95 ArraySerializerType type = GetArraySerializerType<MojomType>::value> | 130 ArraySerializerType type = GetArraySerializerType<MojomType>::value> |
| 96 struct ArraySerializer; | 131 struct ArraySerializer; |
| 97 | 132 |
| 98 // Handles serialization and deserialization of arrays of pod types. | 133 // Handles serialization and deserialization of arrays of pod types. |
| 99 template <typename MojomType, | 134 template <typename MojomType, |
| 100 typename MaybeConstUserType, | 135 typename MaybeConstUserType, |
| 101 typename UserTypeReader> | 136 typename UserTypeIterator> |
| 102 struct ArraySerializer<MojomType, | 137 struct ArraySerializer<MojomType, |
| 103 MaybeConstUserType, | 138 MaybeConstUserType, |
| 104 UserTypeReader, | 139 UserTypeIterator, |
| 105 ArraySerializerType::POD> { | 140 ArraySerializerType::POD> { |
| 106 using UserType = typename std::remove_const<MaybeConstUserType>::type; | 141 using UserType = typename std::remove_const<MaybeConstUserType>::type; |
| 107 using Data = typename MojomType::Data_; | 142 using Data = typename MojomType::Data_; |
| 108 using DataElement = typename Data::Element; | 143 using DataElement = typename Data::Element; |
| 109 using Element = typename MojomType::Element; | 144 using Element = typename MojomType::Element; |
| 110 using Traits = ArrayTraits<UserType>; | 145 using Traits = ArrayTraits<UserType>; |
| 146 using IteratorType = | |
|
yzshen1
2016/06/13 15:18:05
please remove this line.
Fady Samuel
2016/06/13 15:38:11
Done.
| |
| 147 decltype(CallGetBeginIfExists<Traits>(std::declval<UserType&>())); | |
| 111 | 148 |
| 112 static_assert(std::is_same<Element, DataElement>::value, | 149 static_assert(std::is_same<Element, DataElement>::value, |
| 113 "Incorrect array serializer"); | 150 "Incorrect array serializer"); |
| 114 static_assert(std::is_same<Element, typename Traits::Element>::value, | 151 static_assert(std::is_same<Element, typename Traits::Element>::value, |
| 115 "Incorrect array serializer"); | 152 "Incorrect array serializer"); |
| 116 | 153 |
| 117 static size_t GetSerializedSize(UserTypeReader* input, | 154 static size_t GetSerializedSize(UserTypeIterator* input, |
| 118 SerializationContext* context) { | 155 SerializationContext* context) { |
| 119 return sizeof(Data) + Align(input->GetSize() * sizeof(DataElement)); | 156 return sizeof(Data) + Align(input->GetSize() * sizeof(DataElement)); |
| 120 } | 157 } |
| 121 | 158 |
| 122 static void SerializeElements(UserTypeReader* input, | 159 static void SerializeElements(UserTypeIterator* input, |
| 123 Buffer* buf, | 160 Buffer* buf, |
| 124 Data* output, | 161 Data* output, |
| 125 const ContainerValidateParams* validate_params, | 162 const ContainerValidateParams* validate_params, |
| 126 SerializationContext* context) { | 163 SerializationContext* context) { |
| 127 DCHECK(!validate_params->element_is_nullable) | 164 DCHECK(!validate_params->element_is_nullable) |
| 128 << "Primitive type should be non-nullable"; | 165 << "Primitive type should be non-nullable"; |
| 129 DCHECK(!validate_params->element_validate_params) | 166 DCHECK(!validate_params->element_validate_params) |
| 130 << "Primitive type should not have array validate params"; | 167 << "Primitive type should not have array validate params"; |
| 131 | 168 |
| 132 size_t size = input->GetSize(); | 169 size_t size = input->GetSize(); |
| 133 if (size == 0) | 170 if (size == 0) |
| 134 return; | 171 return; |
| 135 | 172 |
| 136 auto data = input->GetDataIfExists(); | 173 auto data = input->GetDataIfExists(); |
| 137 if (data) { | 174 if (data) { |
| 138 memcpy(output->storage(), data, size * sizeof(DataElement)); | 175 memcpy(output->storage(), data, size * sizeof(DataElement)); |
| 139 } else { | 176 } else { |
| 140 for (size_t i = 0; i < size; ++i) | 177 for (size_t i = 0; i < size; ++i) |
| 141 output->at(i) = input->GetNext(); | 178 output->at(i) = input->GetNext(); |
| 142 } | 179 } |
| 143 } | 180 } |
| 144 | 181 |
| 145 static bool DeserializeElements(Data* input, | 182 static bool DeserializeElements(Data* input, |
| 146 UserType* output, | 183 UserType* output, |
| 147 SerializationContext* context) { | 184 SerializationContext* context) { |
| 148 if (!Traits::Resize(*output, input->size())) | 185 if (!Traits::Resize(*output, input->size())) |
| 149 return false; | 186 return false; |
| 187 ArrayIterator<Traits, UserType> iterator(*output); | |
| 150 if (input->size()) { | 188 if (input->size()) { |
| 151 auto data = CallGetDataIfExists<Traits>(*output); | 189 auto data = iterator.GetDataIfExists(); |
| 152 if (data) { | 190 if (data) { |
| 153 memcpy(data, input->storage(), input->size() * sizeof(DataElement)); | 191 memcpy(data, input->storage(), input->size() * sizeof(DataElement)); |
| 154 } else { | 192 } else { |
| 155 for (size_t i = 0; i < input->size(); ++i) | 193 for (size_t i = 0; i < input->size(); ++i) |
| 156 Traits::GetAt(*output, i) = input->at(i); | 194 iterator.GetNext() = input->at(i); |
| 157 } | 195 } |
| 158 } | 196 } |
| 159 return true; | 197 return true; |
| 160 } | 198 } |
| 161 }; | 199 }; |
| 162 | 200 |
| 163 // Handles serialization and deserialization of arrays of enum types. | 201 // Handles serialization and deserialization of arrays of enum types. |
| 164 template <typename MojomType, | 202 template <typename MojomType, |
| 165 typename MaybeConstUserType, | 203 typename MaybeConstUserType, |
| 166 typename UserTypeReader> | 204 typename UserTypeIterator> |
| 167 struct ArraySerializer<MojomType, | 205 struct ArraySerializer<MojomType, |
| 168 MaybeConstUserType, | 206 MaybeConstUserType, |
| 169 UserTypeReader, | 207 UserTypeIterator, |
| 170 ArraySerializerType::ENUM> { | 208 ArraySerializerType::ENUM> { |
| 171 using UserType = typename std::remove_const<MaybeConstUserType>::type; | 209 using UserType = typename std::remove_const<MaybeConstUserType>::type; |
| 172 using Data = typename MojomType::Data_; | 210 using Data = typename MojomType::Data_; |
| 173 using DataElement = typename Data::Element; | 211 using DataElement = typename Data::Element; |
| 174 using Element = typename MojomType::Element; | 212 using Element = typename MojomType::Element; |
| 175 using Traits = ArrayTraits<UserType>; | 213 using Traits = ArrayTraits<UserType>; |
| 176 | 214 |
| 177 static_assert(sizeof(Element) == sizeof(DataElement), | 215 static_assert(sizeof(Element) == sizeof(DataElement), |
| 178 "Incorrect array serializer"); | 216 "Incorrect array serializer"); |
| 179 | 217 |
| 180 static size_t GetSerializedSize(UserTypeReader* input, | 218 static size_t GetSerializedSize(UserTypeIterator* input, |
| 181 SerializationContext* context) { | 219 SerializationContext* context) { |
| 182 return sizeof(Data) + Align(input->GetSize() * sizeof(DataElement)); | 220 return sizeof(Data) + Align(input->GetSize() * sizeof(DataElement)); |
| 183 } | 221 } |
| 184 | 222 |
| 185 static void SerializeElements(UserTypeReader* input, | 223 static void SerializeElements(UserTypeIterator* input, |
| 186 Buffer* buf, | 224 Buffer* buf, |
| 187 Data* output, | 225 Data* output, |
| 188 const ContainerValidateParams* validate_params, | 226 const ContainerValidateParams* validate_params, |
| 189 SerializationContext* context) { | 227 SerializationContext* context) { |
| 190 DCHECK(!validate_params->element_is_nullable) | 228 DCHECK(!validate_params->element_is_nullable) |
| 191 << "Primitive type should be non-nullable"; | 229 << "Primitive type should be non-nullable"; |
| 192 DCHECK(!validate_params->element_validate_params) | 230 DCHECK(!validate_params->element_validate_params) |
| 193 << "Primitive type should not have array validate params"; | 231 << "Primitive type should not have array validate params"; |
| 194 | 232 |
| 195 size_t size = input->GetSize(); | 233 size_t size = input->GetSize(); |
| 196 for (size_t i = 0; i < size; ++i) | 234 for (size_t i = 0; i < size; ++i) |
| 197 Serialize<Element>(input->GetNext(), output->storage() + i); | 235 Serialize<Element>(input->GetNext(), output->storage() + i); |
| 198 } | 236 } |
| 199 | 237 |
| 200 static bool DeserializeElements(Data* input, | 238 static bool DeserializeElements(Data* input, |
| 201 UserType* output, | 239 UserType* output, |
| 202 SerializationContext* context) { | 240 SerializationContext* context) { |
| 203 if (!Traits::Resize(*output, input->size())) | 241 if (!Traits::Resize(*output, input->size())) |
| 204 return false; | 242 return false; |
| 243 ArrayIterator<Traits, UserType> iterator(*output); | |
| 205 for (size_t i = 0; i < input->size(); ++i) { | 244 for (size_t i = 0; i < input->size(); ++i) { |
| 206 if (!Deserialize<Element>(input->at(i), &Traits::GetAt(*output, i))) | 245 if (!Deserialize<Element>(input->at(i), &iterator.GetNext())) |
| 207 return false; | 246 return false; |
| 208 } | 247 } |
| 209 return true; | 248 return true; |
| 210 } | 249 } |
| 211 }; | 250 }; |
| 212 | 251 |
| 213 // Serializes and deserializes arrays of bools. | 252 // Serializes and deserializes arrays of bools. |
| 214 template <typename MojomType, | 253 template <typename MojomType, |
| 215 typename MaybeConstUserType, | 254 typename MaybeConstUserType, |
| 216 typename UserTypeReader> | 255 typename UserTypeIterator> |
| 217 struct ArraySerializer<MojomType, | 256 struct ArraySerializer<MojomType, |
| 218 MaybeConstUserType, | 257 MaybeConstUserType, |
| 219 UserTypeReader, | 258 UserTypeIterator, |
| 220 ArraySerializerType::BOOLEAN> { | 259 ArraySerializerType::BOOLEAN> { |
| 221 using UserType = typename std::remove_const<MaybeConstUserType>::type; | 260 using UserType = typename std::remove_const<MaybeConstUserType>::type; |
| 222 using Traits = ArrayTraits<UserType>; | 261 using Traits = ArrayTraits<UserType>; |
| 223 using Data = typename MojomType::Data_; | 262 using Data = typename MojomType::Data_; |
| 224 | 263 |
| 225 static_assert(std::is_same<bool, typename UserType::Element>::value, | 264 static_assert(std::is_same<bool, typename UserType::Element>::value, |
| 226 "Incorrect array serializer"); | 265 "Incorrect array serializer"); |
| 227 | 266 |
| 228 static size_t GetSerializedSize(UserTypeReader* input, | 267 static size_t GetSerializedSize(UserTypeIterator* input, |
| 229 SerializationContext* context) { | 268 SerializationContext* context) { |
| 230 return sizeof(Data) + Align((input->GetSize() + 7) / 8); | 269 return sizeof(Data) + Align((input->GetSize() + 7) / 8); |
| 231 } | 270 } |
| 232 | 271 |
| 233 static void SerializeElements(UserTypeReader* input, | 272 static void SerializeElements(UserTypeIterator* input, |
| 234 Buffer* buf, | 273 Buffer* buf, |
| 235 Data* output, | 274 Data* output, |
| 236 const ContainerValidateParams* validate_params, | 275 const ContainerValidateParams* validate_params, |
| 237 SerializationContext* context) { | 276 SerializationContext* context) { |
| 238 DCHECK(!validate_params->element_is_nullable) | 277 DCHECK(!validate_params->element_is_nullable) |
| 239 << "Primitive type should be non-nullable"; | 278 << "Primitive type should be non-nullable"; |
| 240 DCHECK(!validate_params->element_validate_params) | 279 DCHECK(!validate_params->element_validate_params) |
| 241 << "Primitive type should not have array validate params"; | 280 << "Primitive type should not have array validate params"; |
| 242 | 281 |
| 243 size_t size = input->GetSize(); | 282 size_t size = input->GetSize(); |
| 244 for (size_t i = 0; i < size; ++i) | 283 for (size_t i = 0; i < size; ++i) |
| 245 output->at(i) = input->GetNext(); | 284 output->at(i) = input->GetNext(); |
| 246 } | 285 } |
| 247 static bool DeserializeElements(Data* input, | 286 static bool DeserializeElements(Data* input, |
| 248 UserType* output, | 287 UserType* output, |
| 249 SerializationContext* context) { | 288 SerializationContext* context) { |
| 250 if (!Traits::Resize(*output, input->size())) | 289 if (!Traits::Resize(*output, input->size())) |
| 251 return false; | 290 return false; |
| 291 ArrayIterator<Traits, UserType> iterator(*output); | |
| 252 for (size_t i = 0; i < input->size(); ++i) | 292 for (size_t i = 0; i < input->size(); ++i) |
| 253 Traits::GetAt(*output, i) = input->at(i); | 293 iterator.GetNext() = input->at(i); |
| 254 return true; | 294 return true; |
| 255 } | 295 } |
| 256 }; | 296 }; |
| 257 | 297 |
| 258 // Serializes and deserializes arrays of handles. | 298 // Serializes and deserializes arrays of handles. |
| 259 template <typename MojomType, | 299 template <typename MojomType, |
| 260 typename MaybeConstUserType, | 300 typename MaybeConstUserType, |
| 261 typename UserTypeReader> | 301 typename UserTypeIterator> |
| 262 struct ArraySerializer<MojomType, | 302 struct ArraySerializer<MojomType, |
| 263 MaybeConstUserType, | 303 MaybeConstUserType, |
| 264 UserTypeReader, | 304 UserTypeIterator, |
| 265 ArraySerializerType::HANDLE> { | 305 ArraySerializerType::HANDLE> { |
| 266 using UserType = typename std::remove_const<MaybeConstUserType>::type; | 306 using UserType = typename std::remove_const<MaybeConstUserType>::type; |
| 267 using Data = typename MojomType::Data_; | 307 using Data = typename MojomType::Data_; |
| 268 using Element = typename MojomType::Element; | 308 using Element = typename MojomType::Element; |
| 269 using Traits = ArrayTraits<UserType>; | 309 using Traits = ArrayTraits<UserType>; |
| 270 | 310 |
| 271 static_assert(std::is_same<Element, typename Traits::Element>::value, | 311 static_assert(std::is_same<Element, typename Traits::Element>::value, |
| 272 "Incorrect array serializer"); | 312 "Incorrect array serializer"); |
| 273 | 313 |
| 274 static size_t GetSerializedSize(UserTypeReader* input, | 314 static size_t GetSerializedSize(UserTypeIterator* input, |
| 275 SerializationContext* context) { | 315 SerializationContext* context) { |
| 276 return sizeof(Data) + | 316 return sizeof(Data) + |
| 277 Align(input->GetSize() * sizeof(typename Data::Element)); | 317 Align(input->GetSize() * sizeof(typename Data::Element)); |
| 278 } | 318 } |
| 279 | 319 |
| 280 static void SerializeElements(UserTypeReader* input, | 320 static void SerializeElements(UserTypeIterator* input, |
| 281 Buffer* buf, | 321 Buffer* buf, |
| 282 Data* output, | 322 Data* output, |
| 283 const ContainerValidateParams* validate_params, | 323 const ContainerValidateParams* validate_params, |
| 284 SerializationContext* context) { | 324 SerializationContext* context) { |
| 285 DCHECK(!validate_params->element_validate_params) | 325 DCHECK(!validate_params->element_validate_params) |
| 286 << "Handle type should not have array validate params"; | 326 << "Handle type should not have array validate params"; |
| 287 | 327 |
| 288 size_t size = input->GetSize(); | 328 size_t size = input->GetSize(); |
| 289 for (size_t i = 0; i < size; ++i) { | 329 for (size_t i = 0; i < size; ++i) { |
| 290 // Transfer ownership of the handle. | 330 // Transfer ownership of the handle. |
| 291 output->at(i) = context->handles.AddHandle(input->GetNext().release()); | 331 output->at(i) = context->handles.AddHandle(input->GetNext().release()); |
| 292 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( | 332 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( |
| 293 !validate_params->element_is_nullable && !output->at(i).is_valid(), | 333 !validate_params->element_is_nullable && !output->at(i).is_valid(), |
| 294 VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE, | 334 VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE, |
| 295 MakeMessageWithArrayIndex( | 335 MakeMessageWithArrayIndex( |
| 296 "invalid handle in array expecting valid handles", size, i)); | 336 "invalid handle in array expecting valid handles", size, i)); |
| 297 } | 337 } |
| 298 } | 338 } |
| 299 static bool DeserializeElements(Data* input, | 339 static bool DeserializeElements(Data* input, |
| 300 UserType* output, | 340 UserType* output, |
| 301 SerializationContext* context) { | 341 SerializationContext* context) { |
| 302 using HandleType = typename Element::RawHandleType; | 342 using HandleType = typename Element::RawHandleType; |
| 303 if (!Traits::Resize(*output, input->size())) | 343 if (!Traits::Resize(*output, input->size())) |
| 304 return false; | 344 return false; |
| 345 ArrayIterator<Traits, UserType> iterator(*output); | |
| 305 for (size_t i = 0; i < input->size(); ++i) { | 346 for (size_t i = 0; i < input->size(); ++i) { |
| 306 Traits::GetAt(*output, i) = MakeScopedHandle( | 347 iterator.GetNext() = MakeScopedHandle( |
| 307 HandleType(context->handles.TakeHandle(input->at(i)).value())); | 348 HandleType(context->handles.TakeHandle(input->at(i)).value())); |
| 308 } | 349 } |
| 309 return true; | 350 return true; |
| 310 } | 351 } |
| 311 }; | 352 }; |
| 312 | 353 |
| 313 // This template must only apply to pointer mojo entity (strings, structs, | 354 // This template must only apply to pointer mojo entity (strings, structs, |
| 314 // arrays and maps). | 355 // arrays and maps). |
| 315 template <typename MojomType, | 356 template <typename MojomType, |
| 316 typename MaybeConstUserType, | 357 typename MaybeConstUserType, |
| 317 typename UserTypeReader> | 358 typename UserTypeIterator> |
| 318 struct ArraySerializer<MojomType, | 359 struct ArraySerializer<MojomType, |
| 319 MaybeConstUserType, | 360 MaybeConstUserType, |
| 320 UserTypeReader, | 361 UserTypeIterator, |
| 321 ArraySerializerType::POINTER> { | 362 ArraySerializerType::POINTER> { |
| 322 using UserType = typename std::remove_const<MaybeConstUserType>::type; | 363 using UserType = typename std::remove_const<MaybeConstUserType>::type; |
| 323 using Data = typename MojomType::Data_; | 364 using Data = typename MojomType::Data_; |
| 324 using DataElement = typename Data::Element; | 365 using DataElement = typename Data::Element; |
| 325 using Element = typename MojomType::Element; | 366 using Element = typename MojomType::Element; |
| 326 using Traits = ArrayTraits<UserType>; | 367 using Traits = ArrayTraits<UserType>; |
| 327 | 368 |
| 328 static size_t GetSerializedSize(UserTypeReader* input, | 369 static size_t GetSerializedSize(UserTypeIterator* input, |
| 329 SerializationContext* context) { | 370 SerializationContext* context) { |
| 330 size_t element_count = input->GetSize(); | 371 size_t element_count = input->GetSize(); |
| 331 size_t size = | 372 size_t size = |
| 332 sizeof(Data) + | 373 sizeof(Data) + |
| 333 element_count * | 374 element_count * |
| 334 sizeof(Pointer<typename std::remove_pointer<DataElement>::type>); | 375 sizeof(Pointer<typename std::remove_pointer<DataElement>::type>); |
| 335 for (size_t i = 0; i < element_count; ++i) | 376 for (size_t i = 0; i < element_count; ++i) |
| 336 size += PrepareToSerialize<Element>(input->GetNext(), context); | 377 size += PrepareToSerialize<Element>(input->GetNext(), context); |
| 337 return size; | 378 return size; |
| 338 } | 379 } |
| 339 | 380 |
| 340 static void SerializeElements(UserTypeReader* input, | 381 static void SerializeElements(UserTypeIterator* input, |
| 341 Buffer* buf, | 382 Buffer* buf, |
| 342 Data* output, | 383 Data* output, |
| 343 const ContainerValidateParams* validate_params, | 384 const ContainerValidateParams* validate_params, |
| 344 SerializationContext* context) { | 385 SerializationContext* context) { |
| 345 size_t size = input->GetSize(); | 386 size_t size = input->GetSize(); |
| 346 for (size_t i = 0; i < size; ++i) { | 387 for (size_t i = 0; i < size; ++i) { |
| 347 DataElement element; | 388 DataElement element; |
| 348 SerializeCaller<Element>::Run(input->GetNext(), buf, &element, | 389 SerializeCaller<Element>::Run(input->GetNext(), buf, &element, |
| 349 validate_params->element_validate_params, | 390 validate_params->element_validate_params, |
| 350 context); | 391 context); |
| 351 output->at(i) = element; | 392 output->at(i) = element; |
| 352 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( | 393 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( |
| 353 !validate_params->element_is_nullable && !element, | 394 !validate_params->element_is_nullable && !element, |
| 354 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, | 395 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, |
| 355 MakeMessageWithArrayIndex("null in array expecting valid pointers", | 396 MakeMessageWithArrayIndex("null in array expecting valid pointers", |
| 356 size, i)); | 397 size, i)); |
| 357 } | 398 } |
| 358 } | 399 } |
| 359 static bool DeserializeElements(Data* input, | 400 static bool DeserializeElements(Data* input, |
| 360 UserType* output, | 401 UserType* output, |
| 361 SerializationContext* context) { | 402 SerializationContext* context) { |
| 362 bool success = true; | 403 bool success = true; |
| 363 if (!Traits::Resize(*output, input->size())) | 404 if (!Traits::Resize(*output, input->size())) |
| 364 return false; | 405 return false; |
| 406 ArrayIterator<Traits, UserType> iterator(*output); | |
| 365 for (size_t i = 0; i < input->size(); ++i) { | 407 for (size_t i = 0; i < input->size(); ++i) { |
| 366 // Note that we rely on complete deserialization taking place in order to | 408 // Note that we rely on complete deserialization taking place in order to |
| 367 // transfer ownership of all encoded handles. Therefore we don't | 409 // transfer ownership of all encoded handles. Therefore we don't |
| 368 // short-circuit on failure here. | 410 // short-circuit on failure here. |
| 369 if (!Deserialize<Element>(input->at(i), &Traits::GetAt(*output, i), | 411 if (!Deserialize<Element>(input->at(i), &iterator.GetNext(), context)) { |
| 370 context)) { | |
| 371 success = false; | 412 success = false; |
| 372 } | 413 } |
| 373 } | 414 } |
| 374 return success; | 415 return success; |
| 375 } | 416 } |
| 376 | 417 |
| 377 private: | 418 private: |
| 378 template <typename T, | 419 template <typename T, |
| 379 bool is_array_or_map = IsSpecializationOf<Array, T>::value || | 420 bool is_array_or_map = IsSpecializationOf<Array, T>::value || |
| 380 IsSpecializationOf<Map, T>::value> | 421 IsSpecializationOf<Map, T>::value> |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 399 SerializationContext* context) { | 440 SerializationContext* context) { |
| 400 Serialize<T>(std::forward<InputElementType>(input), buf, output, | 441 Serialize<T>(std::forward<InputElementType>(input), buf, output, |
| 401 validate_params, context); | 442 validate_params, context); |
| 402 } | 443 } |
| 403 }; | 444 }; |
| 404 }; | 445 }; |
| 405 | 446 |
| 406 // Handles serialization and deserialization of arrays of unions. | 447 // Handles serialization and deserialization of arrays of unions. |
| 407 template <typename MojomType, | 448 template <typename MojomType, |
| 408 typename MaybeConstUserType, | 449 typename MaybeConstUserType, |
| 409 typename UserTypeReader> | 450 typename UserTypeIterator> |
| 410 struct ArraySerializer<MojomType, | 451 struct ArraySerializer<MojomType, |
| 411 MaybeConstUserType, | 452 MaybeConstUserType, |
| 412 UserTypeReader, | 453 UserTypeIterator, |
| 413 ArraySerializerType::UNION> { | 454 ArraySerializerType::UNION> { |
| 414 using UserType = typename std::remove_const<MaybeConstUserType>::type; | 455 using UserType = typename std::remove_const<MaybeConstUserType>::type; |
| 415 using Data = typename MojomType::Data_; | 456 using Data = typename MojomType::Data_; |
| 416 using Element = typename MojomType::Element; | 457 using Element = typename MojomType::Element; |
| 417 using Traits = ArrayTraits<UserType>; | 458 using Traits = ArrayTraits<UserType>; |
| 418 | 459 |
| 419 static_assert(std::is_same<typename MojomType::Element, | 460 static_assert(std::is_same<typename MojomType::Element, |
| 420 typename Traits::Element>::value, | 461 typename Traits::Element>::value, |
| 421 "Incorrect array serializer"); | 462 "Incorrect array serializer"); |
| 422 | 463 |
| 423 static size_t GetSerializedSize(UserTypeReader* input, | 464 static size_t GetSerializedSize(UserTypeIterator* input, |
| 424 SerializationContext* context) { | 465 SerializationContext* context) { |
| 425 size_t element_count = input->GetSize(); | 466 size_t element_count = input->GetSize(); |
| 426 size_t size = sizeof(Data); | 467 size_t size = sizeof(Data); |
| 427 for (size_t i = 0; i < element_count; ++i) { | 468 for (size_t i = 0; i < element_count; ++i) { |
| 428 // Call with |inlined| set to false, so that it will account for both the | 469 // Call with |inlined| set to false, so that it will account for both the |
| 429 // data in the union and the space in the array used to hold the union. | 470 // data in the union and the space in the array used to hold the union. |
| 430 size += PrepareToSerialize<Element>(input->GetNext(), false, context); | 471 size += PrepareToSerialize<Element>(input->GetNext(), false, context); |
| 431 } | 472 } |
| 432 return size; | 473 return size; |
| 433 } | 474 } |
| 434 | 475 |
| 435 static void SerializeElements(UserTypeReader* input, | 476 static void SerializeElements(UserTypeIterator* input, |
| 436 Buffer* buf, | 477 Buffer* buf, |
| 437 Data* output, | 478 Data* output, |
| 438 const ContainerValidateParams* validate_params, | 479 const ContainerValidateParams* validate_params, |
| 439 SerializationContext* context) { | 480 SerializationContext* context) { |
| 440 size_t size = input->GetSize(); | 481 size_t size = input->GetSize(); |
| 441 for (size_t i = 0; i < size; ++i) { | 482 for (size_t i = 0; i < size; ++i) { |
| 442 typename Data::Element* result = output->storage() + i; | 483 typename Data::Element* result = output->storage() + i; |
| 443 Serialize<Element>(input->GetNext(), buf, &result, true, context); | 484 Serialize<Element>(input->GetNext(), buf, &result, true, context); |
| 444 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( | 485 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( |
| 445 !validate_params->element_is_nullable && output->at(i).is_null(), | 486 !validate_params->element_is_nullable && output->at(i).is_null(), |
| 446 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, | 487 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, |
| 447 MakeMessageWithArrayIndex("null in array expecting valid unions", | 488 MakeMessageWithArrayIndex("null in array expecting valid unions", |
| 448 size, i)); | 489 size, i)); |
| 449 } | 490 } |
| 450 } | 491 } |
| 451 | 492 |
| 452 static bool DeserializeElements(Data* input, | 493 static bool DeserializeElements(Data* input, |
| 453 UserType* output, | 494 UserType* output, |
| 454 SerializationContext* context) { | 495 SerializationContext* context) { |
| 455 bool success = true; | 496 bool success = true; |
| 456 if (!Traits::Resize(*output, input->size())) | 497 if (!Traits::Resize(*output, input->size())) |
| 457 return false; | 498 return false; |
| 499 ArrayIterator<Traits, UserType> iterator(*output); | |
| 458 for (size_t i = 0; i < input->size(); ++i) { | 500 for (size_t i = 0; i < input->size(); ++i) { |
| 459 // Note that we rely on complete deserialization taking place in order to | 501 // Note that we rely on complete deserialization taking place in order to |
| 460 // transfer ownership of all encoded handles. Therefore we don't | 502 // transfer ownership of all encoded handles. Therefore we don't |
| 461 // short-circuit on failure here. | 503 // short-circuit on failure here. |
| 462 if (!Deserialize<Element>(&input->at(i), &Traits::GetAt(*output, i), | 504 if (!Deserialize<Element>(&input->at(i), &iterator.GetNext(), context)) { |
| 463 context)) { | |
| 464 success = false; | 505 success = false; |
| 465 } | 506 } |
| 466 } | 507 } |
| 467 return success; | 508 return success; |
| 468 } | 509 } |
| 469 }; | 510 }; |
| 470 | 511 |
| 471 template <typename Element, typename MaybeConstUserType> | 512 template <typename Element, typename MaybeConstUserType> |
| 472 struct Serializer<Array<Element>, MaybeConstUserType> { | 513 struct Serializer<Array<Element>, MaybeConstUserType> { |
| 473 using UserType = typename std::remove_const<MaybeConstUserType>::type; | 514 using UserType = typename std::remove_const<MaybeConstUserType>::type; |
| 515 using Traits = ArrayTraits<UserType>; | |
| 474 using Impl = ArraySerializer<Array<Element>, | 516 using Impl = ArraySerializer<Array<Element>, |
| 475 MaybeConstUserType, | 517 MaybeConstUserType, |
| 476 ArrayReader<MaybeConstUserType>>; | 518 ArrayIterator<Traits, MaybeConstUserType>>; |
| 477 using Traits = ArrayTraits<UserType>; | |
| 478 using Data = typename Array<Element>::Data_; | 519 using Data = typename Array<Element>::Data_; |
| 479 | 520 |
| 480 static size_t PrepareToSerialize(MaybeConstUserType& input, | 521 static size_t PrepareToSerialize(MaybeConstUserType& input, |
| 481 SerializationContext* context) { | 522 SerializationContext* context) { |
| 482 if (CallIsNullIfExists<Traits>(input)) | 523 if (CallIsNullIfExists<Traits>(input)) |
| 483 return 0; | 524 return 0; |
| 484 ArrayReader<MaybeConstUserType> reader(input); | 525 ArrayIterator<Traits, MaybeConstUserType> iterator(input); |
| 485 return Impl::GetSerializedSize(&reader, context); | 526 return Impl::GetSerializedSize(&iterator, context); |
| 486 } | 527 } |
| 487 | 528 |
| 488 static void Serialize(MaybeConstUserType& input, | 529 static void Serialize(MaybeConstUserType& input, |
| 489 Buffer* buf, | 530 Buffer* buf, |
| 490 Data** output, | 531 Data** output, |
| 491 const ContainerValidateParams* validate_params, | 532 const ContainerValidateParams* validate_params, |
| 492 SerializationContext* context) { | 533 SerializationContext* context) { |
| 493 if (!CallIsNullIfExists<Traits>(input)) { | 534 if (!CallIsNullIfExists<Traits>(input)) { |
| 494 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( | 535 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( |
| 495 validate_params->expected_num_elements != 0 && | 536 validate_params->expected_num_elements != 0 && |
| 496 Traits::GetSize(input) != validate_params->expected_num_elements, | 537 Traits::GetSize(input) != validate_params->expected_num_elements, |
| 497 internal::VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER, | 538 internal::VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER, |
| 498 internal::MakeMessageWithExpectedArraySize( | 539 internal::MakeMessageWithExpectedArraySize( |
| 499 "fixed-size array has wrong number of elements", | 540 "fixed-size array has wrong number of elements", |
| 500 Traits::GetSize(input), validate_params->expected_num_elements)); | 541 Traits::GetSize(input), validate_params->expected_num_elements)); |
| 501 Data* result = Data::New(Traits::GetSize(input), buf); | 542 Data* result = Data::New(Traits::GetSize(input), buf); |
| 502 if (result) { | 543 if (result) { |
| 503 ArrayReader<MaybeConstUserType> reader(input); | 544 ArrayIterator<Traits, MaybeConstUserType> iterator(input); |
| 504 Impl::SerializeElements(&reader, buf, result, validate_params, context); | 545 Impl::SerializeElements(&iterator, buf, result, validate_params, |
| 546 context); | |
| 505 } | 547 } |
| 506 *output = result; | 548 *output = result; |
| 507 } else { | 549 } else { |
| 508 *output = nullptr; | 550 *output = nullptr; |
| 509 } | 551 } |
| 510 } | 552 } |
| 511 | 553 |
| 512 static bool Deserialize(Data* input, | 554 static bool Deserialize(Data* input, |
| 513 UserType* output, | 555 UserType* output, |
| 514 SerializationContext* context) { | 556 SerializationContext* context) { |
| 515 if (!input) | 557 if (!input) |
| 516 return CallSetToNullIfExists<Traits>(output); | 558 return CallSetToNullIfExists<Traits>(output); |
| 517 return Impl::DeserializeElements(input, output, context); | 559 return Impl::DeserializeElements(input, output, context); |
| 518 } | 560 } |
| 519 }; | 561 }; |
| 520 | 562 |
| 521 } // namespace internal | 563 } // namespace internal |
| 522 } // namespace mojo | 564 } // namespace mojo |
| 523 | 565 |
| 524 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_ | 566 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_ |
| OLD | NEW |