| 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_MAP_SERIALIZATION_H_ |    5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_MAP_SERIALIZATION_H_ | 
|    6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_MAP_SERIALIZATION_H_ |    6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_MAP_SERIALIZATION_H_ | 
|    7  |    7  | 
 |    8 #include <type_traits> | 
 |    9  | 
|    8 #include "mojo/public/cpp/bindings/array.h" |   10 #include "mojo/public/cpp/bindings/array.h" | 
 |   11 #include "mojo/public/cpp/bindings/lib/array_serialization.h" | 
|    9 #include "mojo/public/cpp/bindings/lib/map_data_internal.h" |   12 #include "mojo/public/cpp/bindings/lib/map_data_internal.h" | 
|   10 #include "mojo/public/cpp/bindings/lib/serialization_forward.h" |   13 #include "mojo/public/cpp/bindings/lib/serialization_forward.h" | 
|   11 #include "mojo/public/cpp/bindings/map.h" |   14 #include "mojo/public/cpp/bindings/map.h" | 
|   12  |   15  | 
|   13 namespace mojo { |   16 namespace mojo { | 
|   14 namespace internal { |   17 namespace internal { | 
|   15  |   18  | 
|   16 template <typename Key, typename Value> |   19 template <typename MaybeConstUserType> | 
|   17 struct MapContext { |   20 class MapReaderBase { | 
|   18   explicit MapContext(bool in_is_null) : is_null(in_is_null) {} |   21  public: | 
 |   22   using UserType = typename std::remove_const<MaybeConstUserType>::type; | 
 |   23   using Traits = MapTraits<UserType>; | 
 |   24   using MaybeConstIterator = | 
 |   25       decltype(Traits::GetBegin(std::declval<MaybeConstUserType&>())); | 
|   19  |   26  | 
|   20   bool is_null; |   27   explicit MapReaderBase(MaybeConstUserType& input) | 
|   21   Array<Key> keys; |   28       : input_(input), iter_(Traits::GetBegin(input_)) {} | 
|   22   Array<Value> values; |   29   ~MapReaderBase() {} | 
 |   30  | 
 |   31   size_t GetSize() const { return Traits::GetSize(input_); } | 
 |   32  | 
 |   33   // Return null because key or value elements are not stored continuously in | 
 |   34   // memory. | 
 |   35   void* GetDataIfExists() { return nullptr; } | 
 |   36  | 
 |   37  protected: | 
 |   38   MaybeConstUserType& input_; | 
 |   39   MaybeConstIterator iter_; | 
 |   40 }; | 
 |   41  | 
 |   42 // Used as the UserTypeReader template parameter of ArraySerializer. | 
 |   43 template <typename MaybeConstUserType> | 
 |   44 class MapKeyReader : public MapReaderBase<MaybeConstUserType> { | 
 |   45  public: | 
 |   46   using Base = MapReaderBase<MaybeConstUserType>; | 
 |   47   using Traits = typename Base::Traits; | 
 |   48  | 
 |   49   explicit MapKeyReader(MaybeConstUserType& input) : Base(input) {} | 
 |   50   ~MapKeyReader() {} | 
 |   51  | 
 |   52   const typename Traits::Key& GetNext() { | 
 |   53     const typename Traits::Key& key = Traits::GetKey(this->iter_); | 
 |   54     Traits::AdvanceIterator(this->iter_); | 
 |   55     return key; | 
 |   56   } | 
 |   57 }; | 
 |   58  | 
 |   59 // Used as the UserTypeReader template parameter of ArraySerializer. | 
 |   60 template <typename MaybeConstUserType> | 
 |   61 class MapValueReader : public MapReaderBase<MaybeConstUserType> { | 
 |   62  public: | 
 |   63   using Base = MapReaderBase<MaybeConstUserType>; | 
 |   64   using Traits = typename Base::Traits; | 
 |   65   using MaybeConstIterator = typename Base::MaybeConstIterator; | 
 |   66  | 
 |   67   explicit MapValueReader(MaybeConstUserType& input) : Base(input) {} | 
 |   68   ~MapValueReader() {} | 
 |   69  | 
 |   70   using GetNextResult = | 
 |   71       decltype(Traits::GetValue(std::declval<MaybeConstIterator&>())); | 
 |   72   GetNextResult GetNext() { | 
 |   73     GetNextResult value = Traits::GetValue(this->iter_); | 
 |   74     Traits::AdvanceIterator(this->iter_); | 
 |   75     return value; | 
 |   76   } | 
|   23 }; |   77 }; | 
|   24  |   78  | 
|   25 template <typename Key, typename Value, typename MaybeConstUserType> |   79 template <typename Key, typename Value, typename MaybeConstUserType> | 
|   26 struct Serializer<Map<Key, Value>, MaybeConstUserType> { |   80 struct Serializer<Map<Key, Value>, MaybeConstUserType> { | 
|   27   using UserType = typename std::remove_const<MaybeConstUserType>::type; |   81   using UserType = typename std::remove_const<MaybeConstUserType>::type; | 
|   28   using UserKey = typename UserType::Key; |   82   using Traits = MapTraits<UserType>; | 
|   29   using UserValue = typename UserType::Value; |   83   using UserKey = typename Traits::Key; | 
 |   84   using UserValue = typename Traits::Value; | 
|   30   using Data = typename Map<Key, Value>::Data_; |   85   using Data = typename Map<Key, Value>::Data_; | 
 |   86   using KeyArraySerializer = ArraySerializer<Array<Key>, | 
 |   87                                              Array<UserKey>, | 
 |   88                                              MapKeyReader<MaybeConstUserType>>; | 
 |   89   using ValueArraySerializer = | 
 |   90       ArraySerializer<Array<Value>, | 
 |   91                       Array<UserValue>, | 
 |   92                       MapValueReader<MaybeConstUserType>>; | 
|   31  |   93  | 
|   32   static_assert(std::is_same<MaybeConstUserType, UserType>::value, |   94   static size_t PrepareToSerialize(MaybeConstUserType& input, | 
|   33                 "Only support serialization of non-const Maps."); |  | 
|   34   static_assert(IsSpecializationOf<Map, UserType>::value, |  | 
|   35                 "Custom mapping of mojom map is not supported yet."); |  | 
|   36  |  | 
|   37   static size_t PrepareToSerialize(UserType& input, |  | 
|   38                                    SerializationContext* context) { |   95                                    SerializationContext* context) { | 
|   39     auto map_context = new MapContext<UserKey, UserValue>(input.is_null()); |   96     if (CallIsNullIfExists<Traits>(input)) | 
|   40     if (!context->custom_contexts) |  | 
|   41       context->custom_contexts.reset(new std::queue<void*>()); |  | 
|   42     context->custom_contexts->push(map_context); |  | 
|   43  |  | 
|   44     if (!input) |  | 
|   45       return 0; |   97       return 0; | 
|   46  |   98  | 
|   47     input.DecomposeMapTo(&map_context->keys, &map_context->values); |  | 
|   48  |  | 
|   49     size_t struct_overhead = sizeof(Data); |   99     size_t struct_overhead = sizeof(Data); | 
 |  100     MapKeyReader<MaybeConstUserType> key_reader(input); | 
|   50     size_t keys_size = |  101     size_t keys_size = | 
|   51         internal::PrepareToSerialize<Array<Key>>(map_context->keys, context); |  102         KeyArraySerializer::GetSerializedSize(&key_reader, context); | 
|   52     size_t values_size = internal::PrepareToSerialize<Array<Value>>( |  103     MapValueReader<MaybeConstUserType> value_reader(input); | 
|   53         map_context->values, context); |  104     size_t values_size = | 
 |  105         ValueArraySerializer::GetSerializedSize(&value_reader, context); | 
|   54  |  106  | 
|   55     return struct_overhead + keys_size + values_size; |  107     return struct_overhead + keys_size + values_size; | 
|   56   } |  108   } | 
|   57  |  109  | 
|   58   // We don't need an ArrayValidateParams instance for key validation since |  110   // We don't need an ArrayValidateParams instance for key validation since | 
|   59   // we can deduce it from the Key type. (which can only be primitive types or |  111   // we can deduce it from the Key type. (which can only be primitive types or | 
|   60   // non-nullable strings.) |  112   // non-nullable strings.) | 
|   61   static void Serialize(UserType& input, |  113   static void Serialize(MaybeConstUserType& input, | 
|   62                         Buffer* buf, |  114                         Buffer* buf, | 
|   63                         Data** output, |  115                         Data** output, | 
|   64                         const ArrayValidateParams* value_validate_params, |  116                         const ArrayValidateParams* value_validate_params, | 
|   65                         SerializationContext* context) { |  117                         SerializationContext* context) { | 
|   66     std::unique_ptr<MapContext<UserKey, UserValue>> map_context( |  118     if (CallIsNullIfExists<Traits>(input)) { | 
|   67         static_cast<MapContext<UserKey, UserValue>*>( |  | 
|   68             context->custom_contexts->front())); |  | 
|   69     context->custom_contexts->pop(); |  | 
|   70  |  | 
|   71     if (map_context->is_null) { |  | 
|   72       *output = nullptr; |  119       *output = nullptr; | 
|   73       return; |  120       return; | 
|   74     } |  121     } | 
|   75  |  122  | 
|   76     auto result = Data::New(buf); |  123     auto result = Data::New(buf); | 
|   77     if (result) { |  124     if (result) { | 
|   78       const ArrayValidateParams* key_validate_params = |  125       result->keys.ptr = Array<Key>::Data_::New(Traits::GetSize(input), buf); | 
|   79           MapKeyValidateParamsFactory< |  126       if (result->keys.ptr) { | 
|   80               typename GetDataTypeAsArrayElement<Key>::Data>::Get(); |  127         const ArrayValidateParams* key_validate_params = | 
|   81       internal::Serialize<Array<Key>>(map_context->keys, buf, &result->keys.ptr, |  128             MapKeyValidateParamsFactory< | 
|   82                                       key_validate_params, context); |  129                 typename GetDataTypeAsArrayElement<Key>::Data>::Get(); | 
|   83       internal::Serialize<Array<Value>>(map_context->values, buf, |  130         MapKeyReader<MaybeConstUserType> key_reader(input); | 
|   84                                         &result->values.ptr, |  131         KeyArraySerializer::SerializeElements( | 
|   85                                         value_validate_params, context); |  132             &key_reader, buf, result->keys.ptr, key_validate_params, context); | 
 |  133       } | 
 |  134  | 
 |  135       result->values.ptr = | 
 |  136           Array<Value>::Data_::New(Traits::GetSize(input), buf); | 
 |  137       if (result->values.ptr) { | 
 |  138         MapValueReader<MaybeConstUserType> value_reader(input); | 
 |  139         ValueArraySerializer::SerializeElements(&value_reader, buf, | 
 |  140                                                 result->values.ptr, | 
 |  141                                                 value_validate_params, context); | 
 |  142       } | 
|   86     } |  143     } | 
|   87     *output = result; |  144     *output = result; | 
|   88   } |  145   } | 
|   89  |  146  | 
|   90   static bool Deserialize(Data* input, |  147   static bool Deserialize(Data* input, | 
|   91                           UserType* output, |  148                           UserType* output, | 
|   92                           SerializationContext* context) { |  149                           SerializationContext* context) { | 
|   93     bool success = true; |  150     if (!input) | 
|   94     if (input) { |  151       return CallSetToNullIfExists<Traits>(output); | 
|   95       Array<UserKey> keys; |  | 
|   96       Array<UserValue> values; |  | 
|   97  |  152  | 
|   98       // Note that we rely on complete deserialization taking place in order to |  153     Array<UserKey> keys; | 
|   99       // transfer ownership of all encoded handles. Therefore we don't |  154     Array<UserValue> values; | 
|  100       // short-circuit on failure here. |  | 
|  101       if (!internal::Deserialize<Array<Key>>(input->keys.ptr, &keys, context)) |  | 
|  102         success = false; |  | 
|  103       if (!internal::Deserialize<Array<Value>>(input->values.ptr, &values, |  | 
|  104                                                context)) { |  | 
|  105         success = false; |  | 
|  106       } |  | 
|  107  |  155  | 
|  108       *output = UserType(std::move(keys), std::move(values)); |  156     if (!KeyArraySerializer::DeserializeElements(input->keys.ptr, &keys, | 
|  109     } else { |  157                                                  context) || | 
|  110       *output = nullptr; |  158         !ValueArraySerializer::DeserializeElements(input->values.ptr, &values, | 
 |  159                                                    context)) { | 
 |  160       return false; | 
|  111     } |  161     } | 
|  112     return success; |  162  | 
 |  163     DCHECK_EQ(keys.size(), values.size()); | 
 |  164     size_t size = keys.size(); | 
 |  165     Traits::SetToEmpty(output); | 
 |  166  | 
 |  167     for (size_t i = 0; i < size; ++i) | 
 |  168       Traits::Insert(*output, std::move(keys[i]), std::move(values[i])); | 
 |  169     return true; | 
|  113   } |  170   } | 
|  114 }; |  171 }; | 
|  115  |  172  | 
|  116 }  // namespace internal |  173 }  // namespace internal | 
|  117 }  // namespace mojo |  174 }  // namespace mojo | 
|  118  |  175  | 
|  119 #endif  // MOJO_PUBLIC_CPP_BINDINGS_LIB_MAP_SERIALIZATION_H_ |  176 #endif  // MOJO_PUBLIC_CPP_BINDINGS_LIB_MAP_SERIALIZATION_H_ | 
| OLD | NEW |