| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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_ARRAY_INTERNAL_H_ | 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_ |
| 6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_ | 6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_ |
| 7 | 7 |
| 8 #include <new> | 8 #include <new> |
| 9 #include <vector> |
| 9 | 10 |
| 10 #include "mojo/public/cpp/bindings/buffer.h" | |
| 11 #include "mojo/public/cpp/bindings/lib/bindings_internal.h" | 11 #include "mojo/public/cpp/bindings/lib/bindings_internal.h" |
| 12 #include "mojo/public/cpp/bindings/lib/bindings_serialization.h" | 12 #include "mojo/public/cpp/bindings/lib/bindings_serialization.h" |
| 13 #include "mojo/public/cpp/bindings/passable.h" | 13 #include "mojo/public/cpp/bindings/lib/buffer.h" |
| 14 | 14 |
| 15 namespace mojo { | 15 namespace mojo { |
| 16 template <typename T> class Array; | 16 template <typename T> class Array; |
| 17 class String; |
| 17 | 18 |
| 18 namespace internal { | 19 namespace internal { |
| 19 | 20 |
| 20 template <typename T> | 21 template <typename T> |
| 21 struct ArrayDataTraits { | 22 struct ArrayDataTraits { |
| 22 typedef T StorageType; | 23 typedef T StorageType; |
| 23 typedef Array<T> Wrapper; | |
| 24 typedef T& Ref; | 24 typedef T& Ref; |
| 25 typedef T const& ConstRef; | 25 typedef T const& ConstRef; |
| 26 | 26 |
| 27 static size_t GetStorageSize(size_t num_elements) { | 27 static size_t GetStorageSize(size_t num_elements) { |
| 28 return sizeof(StorageType) * num_elements; | 28 return sizeof(StorageType) * num_elements; |
| 29 } | 29 } |
| 30 static Ref ToRef(StorageType* storage, size_t offset) { | 30 static Ref ToRef(StorageType* storage, size_t offset) { |
| 31 return storage[offset]; | 31 return storage[offset]; |
| 32 } | 32 } |
| 33 static ConstRef ToConstRef(const StorageType* storage, size_t offset) { | 33 static ConstRef ToConstRef(const StorageType* storage, size_t offset) { |
| 34 return storage[offset]; | 34 return storage[offset]; |
| 35 } | 35 } |
| 36 }; | 36 }; |
| 37 | 37 |
| 38 template <typename P> | 38 template <typename P> |
| 39 struct ArrayDataTraits<P*> { | 39 struct ArrayDataTraits<P*> { |
| 40 typedef StructPointer<P> StorageType; | 40 typedef StructPointer<P> StorageType; |
| 41 typedef Array<typename P::Wrapper> Wrapper; | |
| 42 typedef P*& Ref; | 41 typedef P*& Ref; |
| 43 typedef P* const& ConstRef; | 42 typedef P* const& ConstRef; |
| 44 | 43 |
| 45 static size_t GetStorageSize(size_t num_elements) { | 44 static size_t GetStorageSize(size_t num_elements) { |
| 46 return sizeof(StorageType) * num_elements; | 45 return sizeof(StorageType) * num_elements; |
| 47 } | 46 } |
| 48 static Ref ToRef(StorageType* storage, size_t offset) { | 47 static Ref ToRef(StorageType* storage, size_t offset) { |
| 49 return storage[offset].ptr; | 48 return storage[offset].ptr; |
| 50 } | 49 } |
| 51 static ConstRef ToConstRef(const StorageType* storage, size_t offset) { | 50 static ConstRef ToConstRef(const StorageType* storage, size_t offset) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 70 operator bool() const; | 69 operator bool() const; |
| 71 private: | 70 private: |
| 72 friend struct ArrayDataTraits<bool>; | 71 friend struct ArrayDataTraits<bool>; |
| 73 BitRef(uint8_t* storage, uint8_t mask); | 72 BitRef(uint8_t* storage, uint8_t mask); |
| 74 BitRef(); | 73 BitRef(); |
| 75 uint8_t* storage_; | 74 uint8_t* storage_; |
| 76 uint8_t mask_; | 75 uint8_t mask_; |
| 77 }; | 76 }; |
| 78 | 77 |
| 79 typedef uint8_t StorageType; | 78 typedef uint8_t StorageType; |
| 80 typedef Array<bool> Wrapper; | |
| 81 typedef BitRef Ref; | 79 typedef BitRef Ref; |
| 82 typedef bool ConstRef; | 80 typedef bool ConstRef; |
| 83 | 81 |
| 84 static size_t GetStorageSize(size_t num_elements) { | 82 static size_t GetStorageSize(size_t num_elements) { |
| 85 return ((num_elements + 7) / 8); | 83 return ((num_elements + 7) / 8); |
| 86 } | 84 } |
| 87 static BitRef ToRef(StorageType* storage, size_t offset) { | 85 static BitRef ToRef(StorageType* storage, size_t offset) { |
| 88 return BitRef(&storage[offset / 8], 1 << (offset % 8)); | 86 return BitRef(&storage[offset / 8], 1 << (offset % 8)); |
| 89 } | 87 } |
| 90 static bool ToConstRef(const StorageType* storage, size_t offset) { | 88 static bool ToConstRef(const StorageType* storage, size_t offset) { |
| 91 return (storage[offset / 8] & (1 << (offset % 8))) != 0; | 89 return (storage[offset / 8] & (1 << (offset % 8))) != 0; |
| 92 } | 90 } |
| 93 }; | 91 }; |
| 94 | 92 |
| 95 // What follows is code to support the serialization of Array_Data<T>. There | 93 // What follows is code to support the serialization of Array_Data<T>. There |
| 96 // are two interesting cases: arrays of primitives and arrays of objects. | 94 // are two interesting cases: arrays of primitives and arrays of objects. |
| 97 // Arrays of objects are represented as arrays of pointers to objects. | 95 // Arrays of objects are represented as arrays of pointers to objects. |
| 98 | 96 |
| 99 template <typename T, bool kIsHandle> struct ArraySerializationHelper; | 97 template <typename T, bool kIsHandle> struct ArraySerializationHelper; |
| 100 | 98 |
| 101 template <typename T> | 99 template <typename T> |
| 102 struct ArraySerializationHelper<T, false> { | 100 struct ArraySerializationHelper<T, false> { |
| 103 typedef typename ArrayDataTraits<T>::StorageType ElementType; | 101 typedef typename ArrayDataTraits<T>::StorageType ElementType; |
| 104 | 102 |
| 105 static size_t ComputeSizeOfElements(const ArrayHeader* header, | |
| 106 const ElementType* elements) { | |
| 107 return 0; | |
| 108 } | |
| 109 | |
| 110 static void CloneElements(const ArrayHeader* header, | |
| 111 ElementType* elements, | |
| 112 Buffer* buf) { | |
| 113 } | |
| 114 | |
| 115 static void ClearHandles(const ArrayHeader* header, ElementType* elements) { | |
| 116 } | |
| 117 | |
| 118 static void CloseHandles(const ArrayHeader* header, | |
| 119 ElementType* elements) { | |
| 120 } | |
| 121 | |
| 122 static void EncodePointersAndHandles(const ArrayHeader* header, | 103 static void EncodePointersAndHandles(const ArrayHeader* header, |
| 123 ElementType* elements, | 104 ElementType* elements, |
| 124 std::vector<Handle>* handles) { | 105 std::vector<Handle>* handles) { |
| 125 } | 106 } |
| 126 | 107 |
| 127 static bool DecodePointersAndHandles(const ArrayHeader* header, | 108 static bool DecodePointersAndHandles(const ArrayHeader* header, |
| 128 ElementType* elements, | 109 ElementType* elements, |
| 129 Message* message) { | 110 Message* message) { |
| 130 return true; | 111 return true; |
| 131 } | 112 } |
| 132 }; | 113 }; |
| 133 | 114 |
| 134 template <> | 115 template <> |
| 135 struct ArraySerializationHelper<Handle, true> { | 116 struct ArraySerializationHelper<Handle, true> { |
| 136 typedef ArrayDataTraits<Handle>::StorageType ElementType; | 117 typedef ArrayDataTraits<Handle>::StorageType ElementType; |
| 137 | 118 |
| 138 static size_t ComputeSizeOfElements(const ArrayHeader* header, | |
| 139 const ElementType* elements) { | |
| 140 return 0; | |
| 141 } | |
| 142 | |
| 143 static void CloneElements(const ArrayHeader* header, | |
| 144 ElementType* elements, | |
| 145 Buffer* buf) { | |
| 146 } | |
| 147 | |
| 148 static void ClearHandles(const ArrayHeader* header, ElementType* elements); | |
| 149 | |
| 150 static void CloseHandles(const ArrayHeader* header, ElementType* elements); | |
| 151 | |
| 152 static void EncodePointersAndHandles(const ArrayHeader* header, | 119 static void EncodePointersAndHandles(const ArrayHeader* header, |
| 153 ElementType* elements, | 120 ElementType* elements, |
| 154 std::vector<Handle>* handles); | 121 std::vector<Handle>* handles); |
| 155 | 122 |
| 156 static bool DecodePointersAndHandles(const ArrayHeader* header, | 123 static bool DecodePointersAndHandles(const ArrayHeader* header, |
| 157 ElementType* elements, | 124 ElementType* elements, |
| 158 Message* message); | 125 Message* message); |
| 159 }; | 126 }; |
| 160 | 127 |
| 161 template <typename H> | 128 template <typename H> |
| 162 struct ArraySerializationHelper<H, true> { | 129 struct ArraySerializationHelper<H, true> { |
| 163 typedef typename ArrayDataTraits<H>::StorageType ElementType; | 130 typedef typename ArrayDataTraits<H>::StorageType ElementType; |
| 164 | 131 |
| 165 static size_t ComputeSizeOfElements(const ArrayHeader* header, | |
| 166 const ElementType* elements) { | |
| 167 return 0; | |
| 168 } | |
| 169 | |
| 170 static void CloneElements(const ArrayHeader* header, | |
| 171 ElementType* elements, | |
| 172 Buffer* buf) { | |
| 173 } | |
| 174 | |
| 175 static void ClearHandles(const ArrayHeader* header, ElementType* elements) { | |
| 176 ArraySerializationHelper<Handle, true>::ClearHandles(header, elements); | |
| 177 } | |
| 178 | |
| 179 static void CloseHandles(const ArrayHeader* header, ElementType* elements) { | |
| 180 ArraySerializationHelper<Handle, true>::CloseHandles(header, elements); | |
| 181 } | |
| 182 | |
| 183 static void EncodePointersAndHandles(const ArrayHeader* header, | 132 static void EncodePointersAndHandles(const ArrayHeader* header, |
| 184 ElementType* elements, | 133 ElementType* elements, |
| 185 std::vector<Handle>* handles) { | 134 std::vector<Handle>* handles) { |
| 186 ArraySerializationHelper<Handle, true>::EncodePointersAndHandles( | 135 ArraySerializationHelper<Handle, true>::EncodePointersAndHandles( |
| 187 header, elements, handles); | 136 header, elements, handles); |
| 188 } | 137 } |
| 189 | 138 |
| 190 static bool DecodePointersAndHandles(const ArrayHeader* header, | 139 static bool DecodePointersAndHandles(const ArrayHeader* header, |
| 191 ElementType* elements, | 140 ElementType* elements, |
| 192 Message* message) { | 141 Message* message) { |
| 193 return ArraySerializationHelper<Handle, true>::DecodePointersAndHandles( | 142 return ArraySerializationHelper<Handle, true>::DecodePointersAndHandles( |
| 194 header, elements, message); | 143 header, elements, message); |
| 195 } | 144 } |
| 196 }; | 145 }; |
| 197 | 146 |
| 198 template <typename P> | 147 template <typename P> |
| 199 struct ArraySerializationHelper<P*, false> { | 148 struct ArraySerializationHelper<P*, false> { |
| 200 typedef typename ArrayDataTraits<P*>::StorageType ElementType; | 149 typedef typename ArrayDataTraits<P*>::StorageType ElementType; |
| 201 | 150 |
| 202 static size_t ComputeSizeOfElements(const ArrayHeader* header, | |
| 203 const ElementType* elements) { | |
| 204 size_t result = 0; | |
| 205 for (uint32_t i = 0; i < header->num_elements; ++i) { | |
| 206 if (elements[i].ptr) | |
| 207 result += elements[i].ptr->ComputeSize(); | |
| 208 } | |
| 209 return result; | |
| 210 } | |
| 211 | |
| 212 static void CloneElements(const ArrayHeader* header, | |
| 213 ElementType* elements, | |
| 214 Buffer* buf) { | |
| 215 for (uint32_t i = 0; i < header->num_elements; ++i) { | |
| 216 if (elements[i].ptr) | |
| 217 elements[i].ptr = elements[i].ptr->Clone(buf); | |
| 218 } | |
| 219 } | |
| 220 | |
| 221 static void ClearHandles(const ArrayHeader* header, ElementType* elements) { | |
| 222 } | |
| 223 | |
| 224 static void CloseHandles(const ArrayHeader* header, | |
| 225 ElementType* elements) { | |
| 226 for (uint32_t i = 0; i < header->num_elements; ++i) { | |
| 227 if (elements[i].ptr) | |
| 228 elements[i].ptr->CloseHandles(); | |
| 229 } | |
| 230 } | |
| 231 | |
| 232 static void EncodePointersAndHandles(const ArrayHeader* header, | 151 static void EncodePointersAndHandles(const ArrayHeader* header, |
| 233 ElementType* elements, | 152 ElementType* elements, |
| 234 std::vector<Handle>* handles) { | 153 std::vector<Handle>* handles) { |
| 235 for (uint32_t i = 0; i < header->num_elements; ++i) | 154 for (uint32_t i = 0; i < header->num_elements; ++i) |
| 236 Encode(&elements[i], handles); | 155 Encode(&elements[i], handles); |
| 237 } | 156 } |
| 238 | 157 |
| 239 static bool DecodePointersAndHandles(const ArrayHeader* header, | 158 static bool DecodePointersAndHandles(const ArrayHeader* header, |
| 240 ElementType* elements, | 159 ElementType* elements, |
| 241 Message* message) { | 160 Message* message) { |
| 242 for (uint32_t i = 0; i < header->num_elements; ++i) { | 161 for (uint32_t i = 0; i < header->num_elements; ++i) { |
| 243 if (!Decode(&elements[i], message)) | 162 if (!Decode(&elements[i], message)) |
| 244 return false; | 163 return false; |
| 245 } | 164 } |
| 246 return true; | 165 return true; |
| 247 } | 166 } |
| 248 }; | 167 }; |
| 249 | 168 |
| 250 template <typename T> | 169 template <typename T> |
| 251 class Array_Data { | 170 class Array_Data { |
| 252 public: | 171 public: |
| 253 typedef ArrayDataTraits<T> Traits; | 172 typedef ArrayDataTraits<T> Traits; |
| 254 typedef typename Traits::StorageType StorageType; | 173 typedef typename Traits::StorageType StorageType; |
| 255 typedef typename Traits::Wrapper Wrapper; | |
| 256 typedef typename Traits::Ref Ref; | 174 typedef typename Traits::Ref Ref; |
| 257 typedef typename Traits::ConstRef ConstRef; | 175 typedef typename Traits::ConstRef ConstRef; |
| 258 typedef ArraySerializationHelper<T, TypeTraits<T>::kIsHandle> Helper; | 176 typedef ArraySerializationHelper<T, IsHandle<T>::value> Helper; |
| 259 | 177 |
| 260 static Array_Data<T>* New(size_t num_elements, Buffer* buf, | 178 static Array_Data<T>* New(size_t num_elements, Buffer* buf) { |
| 261 Buffer::Destructor dtor = NULL) { | |
| 262 size_t num_bytes = sizeof(Array_Data<T>) + | 179 size_t num_bytes = sizeof(Array_Data<T>) + |
| 263 Traits::GetStorageSize(num_elements); | 180 Traits::GetStorageSize(num_elements); |
| 264 return new (buf->Allocate(num_bytes, dtor)) Array_Data<T>(num_bytes, | 181 return new (buf->Allocate(num_bytes)) Array_Data<T>(num_bytes, |
| 265 num_elements); | 182 num_elements); |
| 266 } | |
| 267 | |
| 268 static void Destructor(void* address) { | |
| 269 static_cast<Array_Data*>(address)->CloseHandles(); | |
| 270 } | 183 } |
| 271 | 184 |
| 272 size_t size() const { return header_.num_elements; } | 185 size_t size() const { return header_.num_elements; } |
| 273 | 186 |
| 274 Ref at(size_t offset) { | 187 Ref at(size_t offset) { |
| 275 assert(offset < static_cast<size_t>(header_.num_elements)); | 188 assert(offset < static_cast<size_t>(header_.num_elements)); |
| 276 return Traits::ToRef(storage(), offset); | 189 return Traits::ToRef(storage(), offset); |
| 277 } | 190 } |
| 278 | 191 |
| 279 ConstRef at(size_t offset) const { | 192 ConstRef at(size_t offset) const { |
| 280 assert(offset < static_cast<size_t>(header_.num_elements)); | 193 assert(offset < static_cast<size_t>(header_.num_elements)); |
| 281 return Traits::ToConstRef(storage(), offset); | 194 return Traits::ToConstRef(storage(), offset); |
| 282 } | 195 } |
| 283 | 196 |
| 284 StorageType* storage() { | 197 StorageType* storage() { |
| 285 return reinterpret_cast<StorageType*>( | 198 return reinterpret_cast<StorageType*>( |
| 286 reinterpret_cast<char*>(this) + sizeof(*this)); | 199 reinterpret_cast<char*>(this) + sizeof(*this)); |
| 287 } | 200 } |
| 288 | 201 |
| 289 const StorageType* storage() const { | 202 const StorageType* storage() const { |
| 290 return reinterpret_cast<const StorageType*>( | 203 return reinterpret_cast<const StorageType*>( |
| 291 reinterpret_cast<const char*>(this) + sizeof(*this)); | 204 reinterpret_cast<const char*>(this) + sizeof(*this)); |
| 292 } | 205 } |
| 293 | 206 |
| 294 size_t ComputeSize() const { | |
| 295 return Align(header_.num_bytes) + | |
| 296 Helper::ComputeSizeOfElements(&header_, storage()); | |
| 297 } | |
| 298 | |
| 299 Array_Data<T>* Clone(Buffer* buf) { | |
| 300 Array_Data<T>* clone = New(header_.num_elements, buf); | |
| 301 memcpy(clone->storage(), | |
| 302 storage(), | |
| 303 header_.num_bytes - sizeof(Array_Data<T>)); | |
| 304 Helper::CloneElements(&clone->header_, clone->storage(), buf); | |
| 305 | |
| 306 // Zero-out handles in the original storage as they have been transferred | |
| 307 // to the clone. | |
| 308 Helper::ClearHandles(&header_, storage()); | |
| 309 return clone; | |
| 310 } | |
| 311 | |
| 312 void CloseHandles() { | |
| 313 Helper::CloseHandles(&header_, storage()); | |
| 314 } | |
| 315 | |
| 316 void EncodePointersAndHandles(std::vector<Handle>* handles) { | 207 void EncodePointersAndHandles(std::vector<Handle>* handles) { |
| 317 Helper::EncodePointersAndHandles(&header_, storage(), handles); | 208 Helper::EncodePointersAndHandles(&header_, storage(), handles); |
| 318 } | 209 } |
| 319 | 210 |
| 320 bool DecodePointersAndHandles(Message* message) { | 211 bool DecodePointersAndHandles(Message* message) { |
| 321 return Helper::DecodePointersAndHandles(&header_, storage(), message); | 212 return Helper::DecodePointersAndHandles(&header_, storage(), message); |
| 322 } | 213 } |
| 323 | 214 |
| 324 private: | 215 private: |
| 325 Array_Data(size_t num_bytes, size_t num_elements) { | 216 Array_Data(size_t num_bytes, size_t num_elements) { |
| 326 header_.num_bytes = static_cast<uint32_t>(num_bytes); | 217 header_.num_bytes = static_cast<uint32_t>(num_bytes); |
| 327 header_.num_elements = static_cast<uint32_t>(num_elements); | 218 header_.num_elements = static_cast<uint32_t>(num_elements); |
| 328 } | 219 } |
| 329 ~Array_Data() {} | 220 ~Array_Data() {} |
| 330 | 221 |
| 331 internal::ArrayHeader header_; | 222 internal::ArrayHeader header_; |
| 332 | 223 |
| 333 // Elements of type internal::ArrayDataTraits<T>::StorageType follow. | 224 // Elements of type internal::ArrayDataTraits<T>::StorageType follow. |
| 334 }; | 225 }; |
| 335 MOJO_COMPILE_ASSERT(sizeof(Array_Data<char>) == 8, bad_sizeof_Array_Data); | 226 MOJO_COMPILE_ASSERT(sizeof(Array_Data<char>) == 8, bad_sizeof_Array_Data); |
| 336 | 227 |
| 337 // UTF-8 encoded | 228 // UTF-8 encoded |
| 338 typedef Array_Data<char> String_Data; | 229 typedef Array_Data<char> String_Data; |
| 339 | 230 |
| 340 template <typename T, bool kIsObject, bool kIsHandle> struct ArrayTraits {}; | 231 template <typename T, bool kIsMoveOnlyType> struct ArrayTraits {}; |
| 341 | 232 |
| 342 // When T is an object type: | 233 template <typename T> struct ArrayTraits<T, false> { |
| 343 template <typename T> struct ArrayTraits<T, true, false> { | 234 typedef T StorageType; |
| 344 typedef Array_Data<typename T::Data*> DataType; | 235 typedef typename std::vector<T>::reference RefType; |
| 345 typedef const T& ConstRef; | 236 typedef typename std::vector<T>::const_reference ConstRefType; |
| 346 typedef T& Ref; | 237 static inline void Initialize(std::vector<T>* vec) { |
| 347 static Buffer::Destructor GetDestructor() { | |
| 348 return NULL; | |
| 349 } | 238 } |
| 350 static typename T::Data* ToArrayElement(const T& value) { | 239 static inline void Finalize(std::vector<T>* vec) { |
| 351 return Unwrap(value); | |
| 352 } | 240 } |
| 353 // Something sketchy is indeed happening here... | 241 static inline ConstRefType at(const std::vector<T>* vec, size_t offset) { |
| 354 static Ref ToRef(typename T::Data*& data) { | 242 return vec->at(offset); |
| 355 return *reinterpret_cast<T*>(&data); | |
| 356 } | 243 } |
| 357 static ConstRef ToConstRef(typename T::Data* const& data) { | 244 static inline RefType at(std::vector<T>* vec, size_t offset) { |
| 358 return *reinterpret_cast<const T*>(&data); | 245 return vec->at(offset); |
| 359 } | 246 } |
| 360 }; | 247 }; |
| 361 | 248 |
| 362 // When T is a primitive (non-bool) type: | 249 template <typename T> struct ArrayTraits<T, true> { |
| 363 template <typename T> struct ArrayTraits<T, false, false> { | 250 struct StorageType { |
| 364 typedef Array_Data<T> DataType; | 251 char buf[sizeof(T) + (8 - (sizeof(T) % 8)) % 8]; // Make 8-byte aligned. |
| 365 typedef const T& ConstRef; | 252 }; |
| 366 typedef T& Ref; | 253 typedef T& RefType; |
| 367 static Buffer::Destructor GetDestructor() { | 254 typedef const T& ConstRefType; |
| 368 return NULL; | 255 static inline void Initialize(std::vector<StorageType>* vec) { |
| 256 for (size_t i = 0; i < vec->size(); ++i) |
| 257 new (vec->at(i).buf) T(); |
| 369 } | 258 } |
| 370 static T ToArrayElement(const T& value) { | 259 static inline void Finalize(std::vector<StorageType>* vec) { |
| 371 return value; | 260 for (size_t i = 0; i < vec->size(); ++i) |
| 261 reinterpret_cast<T*>(vec->at(i).buf)->~T(); |
| 372 } | 262 } |
| 373 static Ref ToRef(T& data) { return data; } | 263 static inline ConstRefType at(const std::vector<StorageType>* vec, |
| 374 static ConstRef ToConstRef(const T& data) { return data; } | 264 size_t offset) { |
| 375 }; | 265 return *reinterpret_cast<const T*>(vec->at(offset).buf); |
| 376 | |
| 377 // When T is a bool type: | |
| 378 template <> struct ArrayTraits<bool, false, false> { | |
| 379 typedef Array_Data<bool> DataType; | |
| 380 typedef bool ConstRef; | |
| 381 typedef ArrayDataTraits<bool>::Ref Ref; | |
| 382 static Buffer::Destructor GetDestructor() { | |
| 383 return NULL; | |
| 384 } | 266 } |
| 385 static bool ToArrayElement(const bool& value) { | 267 static inline RefType at(std::vector<StorageType>* vec, size_t offset) { |
| 386 return value; | 268 return *reinterpret_cast<T*>(vec->at(offset).buf); |
| 387 } | |
| 388 static Ref ToRef(const Ref& data) { return data; } | |
| 389 static ConstRef ToConstRef(ConstRef data) { return data; } | |
| 390 }; | |
| 391 | |
| 392 // When T is a handle type: | |
| 393 template <typename H> struct ArrayTraits<H, false, true> { | |
| 394 typedef Array_Data<H> DataType; | |
| 395 typedef Passable<H> ConstRef; | |
| 396 typedef AssignableAndPassable<H> Ref; | |
| 397 static Buffer::Destructor GetDestructor() { | |
| 398 return &DataType::Destructor; | |
| 399 } | |
| 400 static H ToArrayElement(const H& value) { | |
| 401 return value; | |
| 402 } | |
| 403 static Ref ToRef(H& data) { return Ref(&data); } | |
| 404 static ConstRef ToConstRef(const H& data) { | |
| 405 return ConstRef(const_cast<H*>(&data)); | |
| 406 } | 269 } |
| 407 }; | 270 }; |
| 408 | 271 |
| 272 template <> struct WrapperTraits<String, false> { |
| 273 typedef String_Data* DataType; |
| 274 }; |
| 275 |
| 409 } // namespace internal | 276 } // namespace internal |
| 410 } // namespace mojo | 277 } // namespace mojo |
| 411 | 278 |
| 412 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_ | 279 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_ |
| OLD | NEW |