1 // Copyright 2013 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_SERIALIZATION_UTIL_H_ 6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_SERIALIZATION_UTIL_H_ 7 8 #include <stddef.h> 9 #include <stdint.h> 10 11 #include <queue> 12 13 #include "base/logging.h" 14 #include "base/macros.h" 15 #include "mojo/public/cpp/bindings/lib/bindings_internal.h" 16 #include "mojo/public/cpp/bindings/lib/serialization_context.h" 17 18 namespace mojo { 19 namespace internal { 20 21 template <typename T> 22 struct HasIsNullMethod { 23 template <typename U> 24 static char Test(decltype(U::IsNull) *); 25 template <typename U> 26 static int Test(...); 27 static const bool value = sizeof(Test<T>(0)) == sizeof(char); 28 29 private: 30 EnsureTypeIsComplete<T> check_t_; 31 }; 32 33 template < 34 typename Traits, 35 typename UserType, 36 typename std::enable_if<HasIsNullMethod<Traits>::value>::type* = nullptr> 37 bool CallIsNullIfExists(const UserType& input) { 38 return Traits::IsNull(input); 39 } 40 41 template < 42 typename Traits, 43 typename UserType, 44 typename std::enable_if<!HasIsNullMethod<Traits>::value>::type* = nullptr> 45 bool CallIsNullIfExists(const UserType& input) { 46 return false; 47 } 48 template <typename T> 49 struct HasSetToNullMethod { 50 template <typename U> 51 static char Test(decltype(U::SetToNull) *); 52 template <typename U> 53 static int Test(...); 54 static const bool value = sizeof(Test<T>(0)) == sizeof(char); 55 56 private: 57 EnsureTypeIsComplete<T> check_t_; 58 }; 59 60 template < 61 typename Traits, 62 typename UserType, 63 typename std::enable_if<HasSetToNullMethod<Traits>::value>::type* = nullptr> 64 bool CallSetToNullIfExists(UserType* output) { 65 Traits::SetToNull(output); 66 return true; 67 } 68 69 template <typename Traits, 70 typename UserType, 71 typename std::enable_if<!HasSetToNullMethod<Traits>::value>::type* = 72 nullptr> 73 bool CallSetToNullIfExists(UserType* output) { 74 LOG(ERROR) << "A null value is received. But the Struct/Array/StringTraits " 75 << "class doesn't define a SetToNull() function and therefore is " 76 << "unable to deserialize the value."; 77 return false; 78 } 79 80 template <typename T> 81 struct HasSetUpContextMethod { 82 template <typename U> 83 static char Test(decltype(U::SetUpContext) *); 84 template <typename U> 85 static int Test(...); 86 static const bool value = sizeof(Test<T>(0)) == sizeof(char); 87 88 private: 89 EnsureTypeIsComplete<T> check_t_; 90 }; 91 92 template <typename Traits, 93 bool has_context = HasSetUpContextMethod<Traits>::value> 94 struct CustomContextHelper; 95 96 template <typename Traits> 97 struct CustomContextHelper<Traits, true> { 98 template <typename MaybeConstUserType> 99 static void* SetUp(MaybeConstUserType& input, SerializationContext* context) { 100 return Traits::SetUpContext(input); 101 } 102 103 template <typename MaybeConstUserType> 104 static void TearDown(MaybeConstUserType& input, void* custom_context) { 105 Traits::TearDownContext(input, custom_context); 106 } 107 }; 108 109 template <typename Traits> 110 struct CustomContextHelper<Traits, false> { 111 template <typename MaybeConstUserType> 112 static void* SetUp(MaybeConstUserType& input, SerializationContext* context) { 113 return nullptr; 114 } 115 116 template <typename MaybeConstUserType> 117 static void TearDown(MaybeConstUserType& input, void* custom_context) { 118 DCHECK(!custom_context); 119 } 120 }; 121 122 template <typename ReturnType, typename ParamType, typename InputUserType> 123 ReturnType CallWithContext(ReturnType (*f)(ParamType, void*), 124 InputUserType&& input, 125 void* context) { 126 return f(std::forward<InputUserType>(input), context); 127 } 128 129 template <typename ReturnType, typename ParamType, typename InputUserType> 130 ReturnType CallWithContext(ReturnType (*f)(ParamType), 131 InputUserType&& input, 132 void* context) { 133 return f(std::forward<InputUserType>(input)); 134 } 135 136 template <typename T, typename MaybeConstUserType> 137 struct HasGetBeginMethod { 138 template <typename U> 139 static char Test( 140 decltype(U::GetBegin(std::declval<MaybeConstUserType&>())) *); 141 template <typename U> 142 static int Test(...); 143 static const bool value = sizeof(Test<T>(0)) == sizeof(char); 144 145 private: 146 EnsureTypeIsComplete<T> check_t_; 147 }; 148 149 template < 150 typename Traits, 151 typename MaybeConstUserType, 152 typename std::enable_if< 153 HasGetBeginMethod<Traits, MaybeConstUserType>::value>::type* = nullptr> 154 decltype(Traits::GetBegin(std::declval<MaybeConstUserType&>())) 155 CallGetBeginIfExists(MaybeConstUserType& input) { 156 return Traits::GetBegin(input); 157 } 158 159 template < 160 typename Traits, 161 typename MaybeConstUserType, 162 typename std::enable_if< 163 !HasGetBeginMethod<Traits, MaybeConstUserType>::value>::type* = nullptr> 164 size_t CallGetBeginIfExists(MaybeConstUserType& input) { 165 return 0; 166 } 167 168 template <typename T, typename MaybeConstUserType> 169 struct HasGetDataMethod { 170 template <typename U> 171 static char Test(decltype(U::GetData(std::declval<MaybeConstUserType&>())) *); 172 template <typename U> 173 static int Test(...); 174 static const bool value = sizeof(Test<T>(0)) == sizeof(char); 175 176 private: 177 EnsureTypeIsComplete<T> check_t_; 178 }; 179 180 template < 181 typename Traits, 182 typename MaybeConstUserType, 183 typename std::enable_if< 184 HasGetDataMethod<Traits, MaybeConstUserType>::value>::type* = nullptr> 185 decltype(Traits::GetData(std::declval<MaybeConstUserType&>())) 186 CallGetDataIfExists(MaybeConstUserType& input) { 187 return Traits::GetData(input); 188 } 189 190 template < 191 typename Traits, 192 typename MaybeConstUserType, 193 typename std::enable_if< 194 !HasGetDataMethod<Traits, MaybeConstUserType>::value>::type* = nullptr> 195 void* CallGetDataIfExists(MaybeConstUserType& input) { 196 return nullptr; 197 } 198 199 } // namespace internal 200 } // namespace mojo 201 202 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_SERIALIZATION_UTIL_H_ 203