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 SerializeNativeEnumSerializerImpl32 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 DeserializeNativeEnumSerializerImpl48 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 { SerializeUnmappedNativeEnumSerializerImpl58 static void Serialize(NativeEnum input, int32_t* output) { 59 *output = static_cast<int32_t>(input); 60 } DeserializeUnmappedNativeEnumSerializerImpl61 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