| OLD | NEW | 
|---|
|  | (Empty) | 
| 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 |  | 
| 3 // found in the LICENSE file. |  | 
| 4 |  | 
| 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_ |  | 
| 6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_ |  | 
| 7 |  | 
| 8 #include <string.h>  // For |memcpy()|. |  | 
| 9 |  | 
| 10 #include <vector> |  | 
| 11 |  | 
| 12 #include "mojo/public/c/system/macros.h" |  | 
| 13 #include "mojo/public/cpp/bindings/lib/array_internal.h" |  | 
| 14 #include "mojo/public/cpp/bindings/lib/map_serialization.h" |  | 
| 15 #include "mojo/public/cpp/bindings/lib/string_serialization.h" |  | 
| 16 #include "mojo/public/cpp/bindings/lib/template_util.h" |  | 
| 17 #include "mojo/public/cpp/bindings/lib/validation_errors.h" |  | 
| 18 |  | 
| 19 namespace mojo { |  | 
| 20 |  | 
| 21 template <typename E> |  | 
| 22 inline size_t GetSerializedSize_(const Array<E>& input); |  | 
| 23 |  | 
| 24 // Because ValidateParams requires explicit argument specification, the |  | 
| 25 // argument-dependent loopup technique used to omit namespace when calling |  | 
| 26 // Serialize_() doesn't seem to work. Therefore, this function is named |  | 
| 27 // differently from those Serialize_() overloads. |  | 
| 28 template <typename ValidateParams, typename E, typename F> |  | 
| 29 inline void SerializeArray_(Array<E> input, |  | 
| 30                             internal::Buffer* buf, |  | 
| 31                             internal::Array_Data<F>** output); |  | 
| 32 |  | 
| 33 template <typename ValueValidateParams, |  | 
| 34           typename KeyWrapperType, |  | 
| 35           typename ValueWrapperType, |  | 
| 36           typename KeySerializationType, |  | 
| 37           typename ValueSerializationType> |  | 
| 38 inline void SerializeMap_( |  | 
| 39     Map<KeyWrapperType, ValueWrapperType> input, |  | 
| 40     internal::Buffer* buf, |  | 
| 41     internal::Map_Data<KeySerializationType, ValueSerializationType>** output); |  | 
| 42 |  | 
| 43 template <typename E, typename F> |  | 
| 44 inline void Deserialize_(internal::Array_Data<F>* data, Array<E>* output); |  | 
| 45 |  | 
| 46 namespace internal { |  | 
| 47 |  | 
| 48 template <typename E, typename F, bool move_only = IsMoveOnlyType<E>::value> |  | 
| 49 struct ArraySerializer; |  | 
| 50 |  | 
| 51 template <typename E, typename F> |  | 
| 52 struct ArraySerializer<E, F, false> { |  | 
| 53   static_assert(sizeof(E) == sizeof(F), "Incorrect array serializer"); |  | 
| 54   static size_t GetSerializedSize(const Array<E>& input) { |  | 
| 55     return sizeof(Array_Data<F>) + Align(input.size() * sizeof(E)); |  | 
| 56   } |  | 
| 57   template <bool element_is_nullable, typename ElementValidateParams> |  | 
| 58   static void SerializeElements(Array<E> input, |  | 
| 59                                 Buffer* buf, |  | 
| 60                                 Array_Data<F>* output) { |  | 
| 61     static_assert(!element_is_nullable, |  | 
| 62                   "Primitive type should be non-nullable"); |  | 
| 63     static_assert((IsSame<ElementValidateParams, NoValidateParams>::value), |  | 
| 64                   "Primitive type should not have array validate params"); |  | 
| 65 |  | 
| 66     if (input.size()) |  | 
| 67       memcpy(output->storage(), &input.storage()[0], input.size() * sizeof(E)); |  | 
| 68   } |  | 
| 69   static void DeserializeElements(Array_Data<F>* input, Array<E>* output) { |  | 
| 70     std::vector<E> result(input->size()); |  | 
| 71     if (input->size()) |  | 
| 72       memcpy(&result[0], input->storage(), input->size() * sizeof(E)); |  | 
| 73     output->Swap(&result); |  | 
| 74   } |  | 
| 75 }; |  | 
| 76 |  | 
| 77 template <> |  | 
| 78 struct ArraySerializer<bool, bool, false> { |  | 
| 79   static size_t GetSerializedSize(const Array<bool>& input) { |  | 
| 80     return sizeof(Array_Data<bool>) + Align((input.size() + 7) / 8); |  | 
| 81   } |  | 
| 82   template <bool element_is_nullable, typename ElementValidateParams> |  | 
| 83   static void SerializeElements(Array<bool> input, |  | 
| 84                                 Buffer* buf, |  | 
| 85                                 Array_Data<bool>* output) { |  | 
| 86     static_assert(!element_is_nullable, |  | 
| 87                   "Primitive type should be non-nullable"); |  | 
| 88     static_assert((IsSame<ElementValidateParams, NoValidateParams>::value), |  | 
| 89                   "Primitive type should not have array validate params"); |  | 
| 90 |  | 
| 91     // 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       output->at(i) = input[i]; |  | 
| 94   } |  | 
| 95   static void DeserializeElements(Array_Data<bool>* input, |  | 
| 96                                   Array<bool>* output) { |  | 
| 97     Array<bool> result(input->size()); |  | 
| 98     // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy? |  | 
| 99     for (size_t i = 0; i < input->size(); ++i) |  | 
| 100       result.at(i) = input->at(i); |  | 
| 101     output->Swap(&result); |  | 
| 102   } |  | 
| 103 }; |  | 
| 104 |  | 
| 105 template <typename H> |  | 
| 106 struct ArraySerializer<ScopedHandleBase<H>, H, true> { |  | 
| 107   static size_t GetSerializedSize(const Array<ScopedHandleBase<H>>& input) { |  | 
| 108     return sizeof(Array_Data<H>) + Align(input.size() * sizeof(H)); |  | 
| 109   } |  | 
| 110   template <bool element_is_nullable, typename ElementValidateParams> |  | 
| 111   static void SerializeElements(Array<ScopedHandleBase<H>> input, |  | 
| 112                                 Buffer* buf, |  | 
| 113                                 Array_Data<H>* output) { |  | 
| 114     static_assert((IsSame<ElementValidateParams, NoValidateParams>::value), |  | 
| 115                   "Handle type should not have array validate params"); |  | 
| 116 |  | 
| 117     for (size_t i = 0; i < input.size(); ++i) { |  | 
| 118       output->at(i) = input[i].release();  // Transfer ownership of the handle. |  | 
| 119       MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( |  | 
| 120           !element_is_nullable && !output->at(i).is_valid(), |  | 
| 121           VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE, |  | 
| 122           MakeMessageWithArrayIndex( |  | 
| 123               "invalid handle in array expecting valid handles", |  | 
| 124               input.size(), |  | 
| 125               i)); |  | 
| 126     } |  | 
| 127   } |  | 
| 128   static void DeserializeElements(Array_Data<H>* input, |  | 
| 129                                   Array<ScopedHandleBase<H>>* output) { |  | 
| 130     Array<ScopedHandleBase<H>> result(input->size()); |  | 
| 131     for (size_t i = 0; i < input->size(); ++i) |  | 
| 132       result.at(i) = MakeScopedHandle(FetchAndReset(&input->at(i))); |  | 
| 133     output->Swap(&result); |  | 
| 134   } |  | 
| 135 }; |  | 
| 136 |  | 
| 137 // This template must only apply to pointer mojo entity (structs and arrays). |  | 
| 138 // This is done by ensuring that WrapperTraits<S>::DataType is a pointer. |  | 
| 139 template <typename S> |  | 
| 140 struct ArraySerializer<S, |  | 
| 141                        typename internal::EnableIf< |  | 
| 142                            internal::IsPointer<typename internal::WrapperTraits< |  | 
| 143                                S>::DataType>::value, |  | 
| 144                            typename internal::WrapperTraits<S>::DataType>::type, |  | 
| 145                        true> { |  | 
| 146   typedef typename internal::RemovePointer< |  | 
| 147       typename internal::WrapperTraits<S>::DataType>::type S_Data; |  | 
| 148   static size_t GetSerializedSize(const Array<S>& input) { |  | 
| 149     size_t size = sizeof(Array_Data<S_Data*>) + |  | 
| 150                   input.size() * sizeof(internal::StructPointer<S_Data>); |  | 
| 151     for (size_t i = 0; i < input.size(); ++i) |  | 
| 152       size += GetSerializedSize_(input[i]); |  | 
| 153     return size; |  | 
| 154   } |  | 
| 155   template <bool element_is_nullable, typename ElementValidateParams> |  | 
| 156   static void SerializeElements(Array<S> input, |  | 
| 157                                 Buffer* buf, |  | 
| 158                                 Array_Data<S_Data*>* output) { |  | 
| 159     for (size_t i = 0; i < input.size(); ++i) { |  | 
| 160       S_Data* element; |  | 
| 161       SerializeCaller<S, ElementValidateParams>::Run( |  | 
| 162           input[i].Pass(), buf, &element); |  | 
| 163       output->at(i) = element; |  | 
| 164       MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( |  | 
| 165           !element_is_nullable && !element, |  | 
| 166           VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, |  | 
| 167           MakeMessageWithArrayIndex( |  | 
| 168               "null in array expecting valid pointers", input.size(), i)); |  | 
| 169     } |  | 
| 170   } |  | 
| 171   static void DeserializeElements(Array_Data<S_Data*>* input, |  | 
| 172                                   Array<S>* output) { |  | 
| 173     Array<S> result(input->size()); |  | 
| 174     for (size_t i = 0; i < input->size(); ++i) { |  | 
| 175       S element; |  | 
| 176       Deserialize_(input->at(i), &element); |  | 
| 177       result[i] = element.Pass(); |  | 
| 178     } |  | 
| 179     output->Swap(&result); |  | 
| 180   } |  | 
| 181 |  | 
| 182  private: |  | 
| 183   template <typename T, typename Params> |  | 
| 184   struct SerializeCaller { |  | 
| 185     static void Run(T input, |  | 
| 186                     Buffer* buf, |  | 
| 187                     typename internal::WrapperTraits<T>::DataType* output) { |  | 
| 188       static_assert((IsSame<Params, NoValidateParams>::value), |  | 
| 189                     "Struct type should not have array validate params"); |  | 
| 190 |  | 
| 191       Serialize_(input.Pass(), buf, output); |  | 
| 192     } |  | 
| 193   }; |  | 
| 194 |  | 
| 195   template <typename T, typename Params> |  | 
| 196   struct SerializeCaller<Array<T>, Params> { |  | 
| 197     static void Run(Array<T> input, |  | 
| 198                     Buffer* buf, |  | 
| 199                     typename Array<T>::Data_** output) { |  | 
| 200       SerializeArray_<Params>(input.Pass(), buf, output); |  | 
| 201     } |  | 
| 202   }; |  | 
| 203 |  | 
| 204   template <typename T, typename U, typename Params> |  | 
| 205   struct SerializeCaller<Map<T, U>, Params> { |  | 
| 206     static void Run(Map<T, U> input, |  | 
| 207                     Buffer* buf, |  | 
| 208                     typename Map<T, U>::Data_** output) { |  | 
| 209       SerializeMap_<Params>(input.Pass(), buf, output); |  | 
| 210     } |  | 
| 211   }; |  | 
| 212 }; |  | 
| 213 |  | 
| 214 template <> |  | 
| 215 struct ArraySerializer<String, String_Data*, false> { |  | 
| 216   static size_t GetSerializedSize(const Array<String>& input) { |  | 
| 217     size_t size = sizeof(Array_Data<String_Data*>) + |  | 
| 218                   input.size() * sizeof(internal::StringPointer); |  | 
| 219     for (size_t i = 0; i < input.size(); ++i) |  | 
| 220       size += GetSerializedSize_(input[i]); |  | 
| 221     return size; |  | 
| 222   } |  | 
| 223   template <bool element_is_nullable, typename ElementValidateParams> |  | 
| 224   static void SerializeElements(Array<String> input, |  | 
| 225                                 Buffer* buf, |  | 
| 226                                 Array_Data<String_Data*>* output) { |  | 
| 227     static_assert( |  | 
| 228         (IsSame<ElementValidateParams, |  | 
| 229                 ArrayValidateParams<0, false, NoValidateParams>>::value), |  | 
| 230         "String type has unexpected array validate params"); |  | 
| 231 |  | 
| 232     for (size_t i = 0; i < input.size(); ++i) { |  | 
| 233       String_Data* element; |  | 
| 234       Serialize_(input[i], buf, &element); |  | 
| 235       output->at(i) = element; |  | 
| 236       MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( |  | 
| 237           !element_is_nullable && !element, |  | 
| 238           VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, |  | 
| 239           MakeMessageWithArrayIndex( |  | 
| 240               "null in array expecting valid strings", input.size(), i)); |  | 
| 241     } |  | 
| 242   } |  | 
| 243   static void DeserializeElements(Array_Data<String_Data*>* input, |  | 
| 244                                   Array<String>* output) { |  | 
| 245     Array<String> result(input->size()); |  | 
| 246     for (size_t i = 0; i < input->size(); ++i) |  | 
| 247       Deserialize_(input->at(i), &result[i]); |  | 
| 248     output->Swap(&result); |  | 
| 249   } |  | 
| 250 }; |  | 
| 251 |  | 
| 252 }  // namespace internal |  | 
| 253 |  | 
| 254 template <typename E> |  | 
| 255 inline size_t GetSerializedSize_(const Array<E>& input) { |  | 
| 256   if (!input) |  | 
| 257     return 0; |  | 
| 258   typedef typename internal::WrapperTraits<E>::DataType F; |  | 
| 259   return internal::ArraySerializer<E, F>::GetSerializedSize(input); |  | 
| 260 } |  | 
| 261 |  | 
| 262 template <typename ValidateParams, typename E, typename F> |  | 
| 263 inline void SerializeArray_(Array<E> input, |  | 
| 264                             internal::Buffer* buf, |  | 
| 265                             internal::Array_Data<F>** output) { |  | 
| 266   if (input) { |  | 
| 267     MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( |  | 
| 268         ValidateParams::expected_num_elements != 0 && |  | 
| 269             input.size() != ValidateParams::expected_num_elements, |  | 
| 270         internal::VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER, |  | 
| 271         internal::MakeMessageWithExpectedArraySize( |  | 
| 272             "fixed-size array has wrong number of elements", |  | 
| 273             input.size(), |  | 
| 274             ValidateParams::expected_num_elements)); |  | 
| 275 |  | 
| 276     internal::Array_Data<F>* result = |  | 
| 277         internal::Array_Data<F>::New(input.size(), buf); |  | 
| 278     if (result) { |  | 
| 279       internal::ArraySerializer<E, F>::template SerializeElements< |  | 
| 280           ValidateParams::element_is_nullable, |  | 
| 281           typename ValidateParams::ElementValidateParams>( |  | 
| 282           internal::Forward(input), buf, result); |  | 
| 283     } |  | 
| 284     *output = result; |  | 
| 285   } else { |  | 
| 286     *output = nullptr; |  | 
| 287   } |  | 
| 288 } |  | 
| 289 |  | 
| 290 template <typename E, typename F> |  | 
| 291 inline void Deserialize_(internal::Array_Data<F>* input, Array<E>* output) { |  | 
| 292   if (input) { |  | 
| 293     internal::ArraySerializer<E, F>::DeserializeElements(input, output); |  | 
| 294   } else { |  | 
| 295     output->reset(); |  | 
| 296   } |  | 
| 297 } |  | 
| 298 |  | 
| 299 }  // namespace mojo |  | 
| 300 |  | 
| 301 #endif  // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_ |  | 
| OLD | NEW | 
|---|