Home | History | Annotate | Download | only in lib
      1 // Copyright 2016 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_NATIVE_ENUM_SERIALIZATION_H_
      6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_NATIVE_ENUM_SERIALIZATION_H_
      7 
      8 #include <stddef.h>
      9 #include <stdint.h>
     10 
     11 #include <type_traits>
     12 
     13 #include "base/logging.h"
     14 #include "base/pickle.h"
     15 #include "ipc/ipc_param_traits.h"
     16 #include "mojo/public/cpp/bindings/lib/serialization_forward.h"
     17 #include "mojo/public/cpp/bindings/native_enum.h"
     18 
     19 namespace mojo {
     20 namespace internal {
     21 
     22 template <typename MaybeConstUserType>
     23 struct NativeEnumSerializerImpl {
     24   using UserType = typename std::remove_const<MaybeConstUserType>::type;
     25   using Traits = IPC::ParamTraits<UserType>;
     26 
     27   // IPC_ENUM_TRAITS* macros serialize enum as int, make sure that fits into
     28   // mojo native-only enum.
     29   static_assert(sizeof(NativeEnum) >= sizeof(int),
     30                 "Cannot store the serialization result in NativeEnum.");
     31 
     32   static void Serialize(UserType input, int32_t* output) {
     33     base::Pickle pickle;
     34     Traits::Write(&pickle, input);
     35 
     36     CHECK_GE(sizeof(int32_t), pickle.payload_size());
     37     *output = 0;
     38     memcpy(reinterpret_cast<char*>(output), pickle.payload(),
     39            pickle.payload_size());
     40   }
     41 
     42   struct PickleData {
     43     uint32_t payload_size;
     44     int32_t value;
     45   };
     46   static_assert(sizeof(PickleData) == 8, "PickleData size mismatch.");
     47 
     48   static bool Deserialize(int32_t input, UserType* output) {
     49     PickleData data = {sizeof(int32_t), input};
     50     base::Pickle pickle_view(reinterpret_cast<const char*>(&data),
     51                              sizeof(PickleData));
     52     base::PickleIterator iter(pickle_view);
     53     return Traits::Read(&pickle_view, &iter, output);
     54   }
     55 };
     56 
     57 struct UnmappedNativeEnumSerializerImpl {
     58   static void Serialize(NativeEnum input, int32_t* output) {
     59     *output = static_cast<int32_t>(input);
     60   }
     61   static bool Deserialize(int32_t input, NativeEnum* output) {
     62     *output = static_cast<NativeEnum>(input);
     63     return true;
     64   }
     65 };
     66 
     67 template <>
     68 struct NativeEnumSerializerImpl<NativeEnum>
     69     : public UnmappedNativeEnumSerializerImpl {};
     70 
     71 template <>
     72 struct NativeEnumSerializerImpl<const NativeEnum>
     73     : public UnmappedNativeEnumSerializerImpl {};
     74 
     75 template <typename MaybeConstUserType>
     76 struct Serializer<NativeEnum, MaybeConstUserType>
     77     : public NativeEnumSerializerImpl<MaybeConstUserType> {};
     78 
     79 }  // namespace internal
     80 }  // namespace mojo
     81 
     82 #endif  // MOJO_PUBLIC_CPP_BINDINGS_LIB_NATIVE_ENUM_SERIALIZATION_H_
     83