| OLD | NEW | 
|---|
|  | (Empty) | 
| 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_BINDINGS_INTERNAL_H_ |  | 
| 6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDINGS_INTERNAL_H_ |  | 
| 7 |  | 
| 8 #include <type_traits> |  | 
| 9 |  | 
| 10 #include "mojo/public/cpp/bindings/lib/template_util.h" |  | 
| 11 #include "mojo/public/cpp/bindings/struct_ptr.h" |  | 
| 12 #include "mojo/public/cpp/system/handle.h" |  | 
| 13 #include "mojo/public/cpp/system/message_pipe.h" |  | 
| 14 |  | 
| 15 namespace mojo { |  | 
| 16 class String; |  | 
| 17 |  | 
| 18 template <typename T> |  | 
| 19 class Array; |  | 
| 20 |  | 
| 21 template <typename Interface> |  | 
| 22 class InterfaceHandle; |  | 
| 23 |  | 
| 24 template <typename Interface> |  | 
| 25 class InterfaceRequest; |  | 
| 26 |  | 
| 27 template <typename K, typename V> |  | 
| 28 class Map; |  | 
| 29 |  | 
| 30 namespace internal { |  | 
| 31 template <typename T> |  | 
| 32 class Array_Data; |  | 
| 33 |  | 
| 34 #pragma pack(push, 1) |  | 
| 35 |  | 
| 36 struct StructHeader { |  | 
| 37   uint32_t num_bytes; |  | 
| 38   uint32_t version; |  | 
| 39 }; |  | 
| 40 static_assert(sizeof(StructHeader) == 8, "Bad sizeof(StructHeader)"); |  | 
| 41 |  | 
| 42 struct ArrayHeader { |  | 
| 43   uint32_t num_bytes; |  | 
| 44   uint32_t num_elements; |  | 
| 45 }; |  | 
| 46 static_assert(sizeof(ArrayHeader) == 8, "Bad_sizeof(ArrayHeader)"); |  | 
| 47 |  | 
| 48 template <typename T> |  | 
| 49 union StructPointer { |  | 
| 50   uint64_t offset; |  | 
| 51   T* ptr; |  | 
| 52 }; |  | 
| 53 static_assert(sizeof(StructPointer<char>) == 8, "Bad_sizeof(StructPointer)"); |  | 
| 54 |  | 
| 55 template <typename T> |  | 
| 56 union ArrayPointer { |  | 
| 57   uint64_t offset; |  | 
| 58   Array_Data<T>* ptr; |  | 
| 59 }; |  | 
| 60 static_assert(sizeof(ArrayPointer<char>) == 8, "Bad_sizeof(ArrayPointer)"); |  | 
| 61 |  | 
| 62 union StringPointer { |  | 
| 63   uint64_t offset; |  | 
| 64   Array_Data<char>* ptr; |  | 
| 65 }; |  | 
| 66 static_assert(sizeof(StringPointer) == 8, "Bad_sizeof(StringPointer)"); |  | 
| 67 |  | 
| 68 struct Interface_Data { |  | 
| 69   MessagePipeHandle handle; |  | 
| 70   uint32_t version; |  | 
| 71 }; |  | 
| 72 static_assert(sizeof(Interface_Data) == 8, "Bad_sizeof(Interface_Data)"); |  | 
| 73 |  | 
| 74 template <typename T> |  | 
| 75 union UnionPointer { |  | 
| 76   uint64_t offset; |  | 
| 77   T* ptr; |  | 
| 78 }; |  | 
| 79 static_assert(sizeof(UnionPointer<char>) == 8, "Bad_sizeof(UnionPointer)"); |  | 
| 80 |  | 
| 81 #pragma pack(pop) |  | 
| 82 |  | 
| 83 template <typename T> |  | 
| 84 void ResetIfNonNull(T* ptr) { |  | 
| 85   if (ptr) |  | 
| 86     *ptr = T(); |  | 
| 87 } |  | 
| 88 |  | 
| 89 template <typename T> |  | 
| 90 T FetchAndReset(T* ptr) { |  | 
| 91   T temp = *ptr; |  | 
| 92   *ptr = T(); |  | 
| 93   return temp; |  | 
| 94 } |  | 
| 95 |  | 
| 96 template <typename H> |  | 
| 97 struct IsHandle { |  | 
| 98   enum { value = std::is_base_of<Handle, H>::value }; |  | 
| 99 }; |  | 
| 100 |  | 
| 101 // TODO(vardhan): Replace RemoveStructPtr<> and UnwrapStructPtr<> with |  | 
| 102 // specializations of std::pointer_traits<> on [Inlined]StructPtr<>. |  | 
| 103 template <typename T> |  | 
| 104 struct RemoveStructPtr { |  | 
| 105   typedef T type; |  | 
| 106 }; |  | 
| 107 |  | 
| 108 template <typename T> |  | 
| 109 struct RemoveStructPtr<StructPtr<T>> { |  | 
| 110   typedef T type; |  | 
| 111 }; |  | 
| 112 |  | 
| 113 template <typename T> |  | 
| 114 struct RemoveStructPtr<InlinedStructPtr<T>> { |  | 
| 115   typedef T type; |  | 
| 116 }; |  | 
| 117 |  | 
| 118 template <typename T> |  | 
| 119 struct UnwrapStructPtr { |  | 
| 120   static T* value(T& x) { return &x; } |  | 
| 121 }; |  | 
| 122 |  | 
| 123 template <typename T> |  | 
| 124 struct UnwrapStructPtr<StructPtr<T>> { |  | 
| 125   static T* value(StructPtr<T>& x) { return x.get(); } |  | 
| 126 }; |  | 
| 127 |  | 
| 128 template <typename T> |  | 
| 129 struct UnwrapStructPtr<InlinedStructPtr<T>> { |  | 
| 130   static T* value(InlinedStructPtr<T>& x) { return x.get(); } |  | 
| 131 }; |  | 
| 132 |  | 
| 133 template <typename T> |  | 
| 134 struct UnwrapConstStructPtr { |  | 
| 135   static const T* value(const T& x) { return &x; } |  | 
| 136 }; |  | 
| 137 |  | 
| 138 template <typename T> |  | 
| 139 struct UnwrapConstStructPtr<StructPtr<T>> { |  | 
| 140   static const T* value(const StructPtr<T>& x) { return x.get(); } |  | 
| 141 }; |  | 
| 142 |  | 
| 143 template <typename T> |  | 
| 144 struct UnwrapConstStructPtr<InlinedStructPtr<T>> { |  | 
| 145   static const T* value(const InlinedStructPtr<T>& x) { return x.get(); } |  | 
| 146 }; |  | 
| 147 |  | 
| 148 template <typename T> |  | 
| 149 struct IsStructPtr { |  | 
| 150   static bool const value = IsSpecializationOf<StructPtr, T>::value || |  | 
| 151                             IsSpecializationOf<InlinedStructPtr, T>::value; |  | 
| 152 }; |  | 
| 153 |  | 
| 154 template <typename T> |  | 
| 155 struct IsUnionWrapperType { |  | 
| 156   template <typename U> |  | 
| 157   static YesType Test(const typename U::Data_::MojomUnionDataType*); |  | 
| 158 |  | 
| 159   template <typename U> |  | 
| 160   static NoType Test(...); |  | 
| 161 |  | 
| 162   static const bool value = |  | 
| 163       sizeof(Test<T>(0)) == sizeof(YesType) && !std::is_const<T>::value; |  | 
| 164 }; |  | 
| 165 |  | 
| 166 template <typename T> |  | 
| 167 struct IsUnionDataType { |  | 
| 168   template <typename U> |  | 
| 169   static YesType Test(const typename U::MojomUnionDataType*); |  | 
| 170 |  | 
| 171   template <typename U> |  | 
| 172   static NoType Test(...); |  | 
| 173 |  | 
| 174   static const bool value = |  | 
| 175       sizeof(Test<T>(0)) == sizeof(YesType) && !std::is_const<T>::value; |  | 
| 176 }; |  | 
| 177 |  | 
| 178 // To introduce a new mojom type, you must define (partial or full) template |  | 
| 179 // specializations for the following traits templates, which operate on the C++ |  | 
| 180 // wrapper types representing a mojom type: |  | 
| 181 //   - WrapperTraits: provides a |DataType| typedef which points to the |  | 
| 182 //                    serialized data type. |  | 
| 183 //   - ValueTraits: provides an |Equals()| method for comparing the two wrapper |  | 
| 184 //                  values of the same type. |  | 
| 185 // |  | 
| 186 // Currently, full specializations of WrapperTraits are generated for mojo |  | 
| 187 // structs in their generated `.mojom.h`. In contrast, WrapperTraits for Unions |  | 
| 188 // don't need to be auto-generated because their underlying DataType can be |  | 
| 189 // accessed without dependency issues -- a catch-all WrapperTraits for unions is |  | 
| 190 // instead defined here. |  | 
| 191 // TODO(vardhan): Merge ValueTraits and WrapperTraits into one? |  | 
| 192 // TODO(vardhan): Write a doc about all the Traits templates you need to touch |  | 
| 193 // when introducing a new mojom type. |  | 
| 194 // TODO(vardhan): Instead of providing |move_only| & |is_union| template |  | 
| 195 // parameters, provide a default "typename Enable = void" template parameter, |  | 
| 196 // and have specializations define their own Enable expressions (similar to how |  | 
| 197 // ValueTraits is). |  | 
| 198 template <typename T, |  | 
| 199           bool move_only = IsMoveOnlyType<T>::value, |  | 
| 200           bool is_union = |  | 
| 201               IsUnionWrapperType<typename RemoveStructPtr<T>::type>::value> |  | 
| 202 struct WrapperTraits; |  | 
| 203 |  | 
| 204 // Catch-all for all mojom types not specialized below. |  | 
| 205 template <typename T> |  | 
| 206 struct WrapperTraits<T, false, false> { |  | 
| 207   using DataType = T; |  | 
| 208 }; |  | 
| 209 template <typename H> |  | 
| 210 struct WrapperTraits<ScopedHandleBase<H>, true, false> { |  | 
| 211   using DataType = H; |  | 
| 212 }; |  | 
| 213 template <typename I> |  | 
| 214 struct WrapperTraits<InterfaceRequest<I>, true, false> { |  | 
| 215   using DataType = MessagePipeHandle; |  | 
| 216 }; |  | 
| 217 template <typename Interface> |  | 
| 218 struct WrapperTraits<InterfaceHandle<Interface>, true, false> { |  | 
| 219   using DataType = Interface_Data; |  | 
| 220 }; |  | 
| 221 // Unions. |  | 
| 222 template <typename U> |  | 
| 223 struct WrapperTraits<StructPtr<U>, true, true> { |  | 
| 224   using DataType = typename U::Data_; |  | 
| 225 }; |  | 
| 226 template <typename U> |  | 
| 227 struct WrapperTraits<InlinedStructPtr<U>, true, true> { |  | 
| 228   using DataType = typename U::Data_; |  | 
| 229 }; |  | 
| 230 // Catch-all for other pointer types: arrays, maps. |  | 
| 231 template <typename S> |  | 
| 232 struct WrapperTraits<S, true, false> { |  | 
| 233   using DataType = typename S::Data_*; |  | 
| 234 }; |  | 
| 235 |  | 
| 236 template <typename T, typename Enable = void> |  | 
| 237 struct ValueTraits { |  | 
| 238   static bool Equals(const T& a, const T& b) { return a == b; } |  | 
| 239 }; |  | 
| 240 |  | 
| 241 template <typename T> |  | 
| 242 struct ValueTraits<T, |  | 
| 243                    typename std::enable_if< |  | 
| 244                        IsSpecializationOf<Array, T>::value || |  | 
| 245                        IsSpecializationOf<Map, T>::value || |  | 
| 246                        IsSpecializationOf<StructPtr, T>::value || |  | 
| 247                        IsSpecializationOf<InlinedStructPtr, T>::value>::type> { |  | 
| 248   static bool Equals(const T& a, const T& b) { return a.Equals(b); } |  | 
| 249 }; |  | 
| 250 |  | 
| 251 template <typename T> |  | 
| 252 struct ValueTraits<ScopedHandleBase<T>> { |  | 
| 253   static bool Equals(const ScopedHandleBase<T>& a, |  | 
| 254                      const ScopedHandleBase<T>& b) { |  | 
| 255     return (&a == &b) || (!a.is_valid() && !b.is_valid()); |  | 
| 256   } |  | 
| 257 }; |  | 
| 258 |  | 
| 259 // |InterfaceHandle|s hold message pipes uniquely, so they can only be equal if |  | 
| 260 // they're the same object or are both "invalid". |  | 
| 261 template <typename I> |  | 
| 262 struct ValueTraits<InterfaceHandle<I>> { |  | 
| 263   static bool Equals(const InterfaceHandle<I>& a, const InterfaceHandle<I>& b) { |  | 
| 264     return (&a == &b) || (!a.is_valid() && !b.is_valid()); |  | 
| 265   } |  | 
| 266 }; |  | 
| 267 |  | 
| 268 // |InterfaceRequest|s hold message pipes uniquely, so they can only be equal if |  | 
| 269 // they're the same object or are both "invalid". |  | 
| 270 template <typename I> |  | 
| 271 struct ValueTraits<InterfaceRequest<I>> { |  | 
| 272   static bool Equals(const InterfaceRequest<I>& a, |  | 
| 273                      const InterfaceRequest<I>& b) { |  | 
| 274     return (&a == &b) || (!a.is_pending() && !b.is_pending()); |  | 
| 275   } |  | 
| 276 }; |  | 
| 277 |  | 
| 278 }  // namespace internal |  | 
| 279 }  // namespace mojo |  | 
| 280 |  | 
| 281 #endif  // MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDINGS_INTERNAL_H_ |  | 
| OLD | NEW | 
|---|