| 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 | 9 |
| 10 #include "mojo/public/cpp/bindings/buffer.h" | 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/lib/bounds_checker.h" |
| 13 #include "mojo/public/cpp/bindings/passable.h" | 14 #include "mojo/public/cpp/bindings/passable.h" |
| 14 | 15 |
| 15 namespace mojo { | 16 namespace mojo { |
| 16 template <typename T> class Array; | 17 template <typename T> class Array; |
| 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; |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 static void EncodePointersAndHandles(const ArrayHeader* header, | 123 static void EncodePointersAndHandles(const ArrayHeader* header, |
| 123 ElementType* elements, | 124 ElementType* elements, |
| 124 std::vector<Handle>* handles) { | 125 std::vector<Handle>* handles) { |
| 125 } | 126 } |
| 126 | 127 |
| 127 static bool DecodePointersAndHandles(const ArrayHeader* header, | 128 static bool DecodePointersAndHandles(const ArrayHeader* header, |
| 128 ElementType* elements, | 129 ElementType* elements, |
| 129 Message* message) { | 130 Message* message) { |
| 130 return true; | 131 return true; |
| 131 } | 132 } |
| 133 |
| 134 static bool ValidateElements(const ArrayHeader* header, |
| 135 const ElementType* elements, |
| 136 BoundsChecker* bounds_checker) { |
| 137 return true; |
| 138 } |
| 132 }; | 139 }; |
| 133 | 140 |
| 134 template <> | 141 template <> |
| 135 struct ArraySerializationHelper<Handle, true> { | 142 struct ArraySerializationHelper<Handle, true> { |
| 136 typedef ArrayDataTraits<Handle>::StorageType ElementType; | 143 typedef ArrayDataTraits<Handle>::StorageType ElementType; |
| 137 | 144 |
| 138 static size_t ComputeSizeOfElements(const ArrayHeader* header, | 145 static size_t ComputeSizeOfElements(const ArrayHeader* header, |
| 139 const ElementType* elements) { | 146 const ElementType* elements) { |
| 140 return 0; | 147 return 0; |
| 141 } | 148 } |
| 142 | 149 |
| 143 static void CloneElements(const ArrayHeader* header, | 150 static void CloneElements(const ArrayHeader* header, |
| 144 ElementType* elements, | 151 ElementType* elements, |
| 145 Buffer* buf) { | 152 Buffer* buf) { |
| 146 } | 153 } |
| 147 | 154 |
| 148 static void ClearHandles(const ArrayHeader* header, ElementType* elements); | 155 static void ClearHandles(const ArrayHeader* header, ElementType* elements); |
| 149 | 156 |
| 150 static void CloseHandles(const ArrayHeader* header, ElementType* elements); | 157 static void CloseHandles(const ArrayHeader* header, ElementType* elements); |
| 151 | 158 |
| 152 static void EncodePointersAndHandles(const ArrayHeader* header, | 159 static void EncodePointersAndHandles(const ArrayHeader* header, |
| 153 ElementType* elements, | 160 ElementType* elements, |
| 154 std::vector<Handle>* handles); | 161 std::vector<Handle>* handles); |
| 155 | 162 |
| 156 static bool DecodePointersAndHandles(const ArrayHeader* header, | 163 static bool DecodePointersAndHandles(const ArrayHeader* header, |
| 157 ElementType* elements, | 164 ElementType* elements, |
| 158 Message* message); | 165 Message* message); |
| 166 |
| 167 static bool ValidateElements(const ArrayHeader* header, |
| 168 const ElementType* elements, |
| 169 BoundsChecker* bounds_checker); |
| 159 }; | 170 }; |
| 160 | 171 |
| 161 template <typename H> | 172 template <typename H> |
| 162 struct ArraySerializationHelper<H, true> { | 173 struct ArraySerializationHelper<H, true> { |
| 163 typedef typename ArrayDataTraits<H>::StorageType ElementType; | 174 typedef typename ArrayDataTraits<H>::StorageType ElementType; |
| 164 | 175 |
| 165 static size_t ComputeSizeOfElements(const ArrayHeader* header, | 176 static size_t ComputeSizeOfElements(const ArrayHeader* header, |
| 166 const ElementType* elements) { | 177 const ElementType* elements) { |
| 167 return 0; | 178 return 0; |
| 168 } | 179 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 186 ArraySerializationHelper<Handle, true>::EncodePointersAndHandles( | 197 ArraySerializationHelper<Handle, true>::EncodePointersAndHandles( |
| 187 header, elements, handles); | 198 header, elements, handles); |
| 188 } | 199 } |
| 189 | 200 |
| 190 static bool DecodePointersAndHandles(const ArrayHeader* header, | 201 static bool DecodePointersAndHandles(const ArrayHeader* header, |
| 191 ElementType* elements, | 202 ElementType* elements, |
| 192 Message* message) { | 203 Message* message) { |
| 193 return ArraySerializationHelper<Handle, true>::DecodePointersAndHandles( | 204 return ArraySerializationHelper<Handle, true>::DecodePointersAndHandles( |
| 194 header, elements, message); | 205 header, elements, message); |
| 195 } | 206 } |
| 207 |
| 208 static bool ValidateElements(const ArrayHeader* header, |
| 209 const ElementType* elements, |
| 210 BoundsChecker* bounds_checker) { |
| 211 return ArraySerializationHelper<Handle, true>::ValidateElements( |
| 212 header, elements, bounds_checker); |
| 213 } |
| 196 }; | 214 }; |
| 197 | 215 |
| 198 template <typename P> | 216 template <typename P> |
| 199 struct ArraySerializationHelper<P*, false> { | 217 struct ArraySerializationHelper<P*, false> { |
| 200 typedef typename ArrayDataTraits<P*>::StorageType ElementType; | 218 typedef typename ArrayDataTraits<P*>::StorageType ElementType; |
| 201 | 219 |
| 202 static size_t ComputeSizeOfElements(const ArrayHeader* header, | 220 static size_t ComputeSizeOfElements(const ArrayHeader* header, |
| 203 const ElementType* elements) { | 221 const ElementType* elements) { |
| 204 size_t result = 0; | 222 size_t result = 0; |
| 205 for (uint32_t i = 0; i < header->num_elements; ++i) { | 223 for (uint32_t i = 0; i < header->num_elements; ++i) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 | 256 |
| 239 static bool DecodePointersAndHandles(const ArrayHeader* header, | 257 static bool DecodePointersAndHandles(const ArrayHeader* header, |
| 240 ElementType* elements, | 258 ElementType* elements, |
| 241 Message* message) { | 259 Message* message) { |
| 242 for (uint32_t i = 0; i < header->num_elements; ++i) { | 260 for (uint32_t i = 0; i < header->num_elements; ++i) { |
| 243 if (!Decode(&elements[i], message)) | 261 if (!Decode(&elements[i], message)) |
| 244 return false; | 262 return false; |
| 245 } | 263 } |
| 246 return true; | 264 return true; |
| 247 } | 265 } |
| 266 |
| 267 static bool ValidateElements(const ArrayHeader* header, |
| 268 const ElementType* elements, |
| 269 BoundsChecker* bounds_checker) { |
| 270 for (uint32_t i = 0; i < header->num_elements; ++i) { |
| 271 if (!ValidateEncodedPointer(&elements[i].offset) || |
| 272 !P::Validate(DecodePointerRaw(&elements[i].offset), bounds_checker)) { |
| 273 return false; |
| 274 } |
| 275 } |
| 276 return true; |
| 277 } |
| 248 }; | 278 }; |
| 249 | 279 |
| 250 template <typename T> | 280 template <typename T> |
| 251 class Array_Data { | 281 class Array_Data { |
| 252 public: | 282 public: |
| 253 typedef ArrayDataTraits<T> Traits; | 283 typedef ArrayDataTraits<T> Traits; |
| 254 typedef typename Traits::StorageType StorageType; | 284 typedef typename Traits::StorageType StorageType; |
| 255 typedef typename Traits::Wrapper Wrapper; | 285 typedef typename Traits::Wrapper Wrapper; |
| 256 typedef typename Traits::Ref Ref; | 286 typedef typename Traits::Ref Ref; |
| 257 typedef typename Traits::ConstRef ConstRef; | 287 typedef typename Traits::ConstRef ConstRef; |
| 258 typedef ArraySerializationHelper<T, TypeTraits<T>::kIsHandle> Helper; | 288 typedef ArraySerializationHelper<T, TypeTraits<T>::kIsHandle> Helper; |
| 259 | 289 |
| 260 static Array_Data<T>* New(size_t num_elements, Buffer* buf, | 290 static Array_Data<T>* New(size_t num_elements, Buffer* buf, |
| 261 Buffer::Destructor dtor = NULL) { | 291 Buffer::Destructor dtor = NULL) { |
| 262 size_t num_bytes = sizeof(Array_Data<T>) + | 292 size_t num_bytes = sizeof(Array_Data<T>) + |
| 263 Traits::GetStorageSize(num_elements); | 293 Traits::GetStorageSize(num_elements); |
| 264 return new (buf->Allocate(num_bytes, dtor)) Array_Data<T>(num_bytes, | 294 return new (buf->Allocate(num_bytes, dtor)) Array_Data<T>(num_bytes, |
| 265 num_elements); | 295 num_elements); |
| 266 } | 296 } |
| 267 | 297 |
| 268 static void Destructor(void* address) { | 298 static void Destructor(void* address) { |
| 269 static_cast<Array_Data*>(address)->CloseHandles(); | 299 static_cast<Array_Data*>(address)->CloseHandles(); |
| 270 } | 300 } |
| 271 | 301 |
| 302 static bool Validate(const void* data, BoundsChecker* bounds_checker) { |
| 303 if (!data) |
| 304 return true; |
| 305 if (!IsAligned(data)) |
| 306 return false; |
| 307 if (!bounds_checker->IsWithinUnclaimedRange(data, sizeof(ArrayHeader))) |
| 308 return false; |
| 309 const ArrayHeader* header = static_cast<const ArrayHeader*>(data); |
| 310 if (header->num_bytes < (sizeof(Array_Data<T>) + |
| 311 Traits::GetStorageSize(header->num_elements))) { |
| 312 return false; |
| 313 } |
| 314 if (!bounds_checker->ClaimMemory(data, header->num_bytes)) |
| 315 return false; |
| 316 |
| 317 const Array_Data<T>* object = static_cast<const Array_Data<T>*>(data); |
| 318 return Helper::ValidateElements(&object->header_, object->storage(), |
| 319 bounds_checker); |
| 320 } |
| 321 |
| 272 size_t size() const { return header_.num_elements; } | 322 size_t size() const { return header_.num_elements; } |
| 273 | 323 |
| 274 Ref at(size_t offset) { | 324 Ref at(size_t offset) { |
| 275 assert(offset < static_cast<size_t>(header_.num_elements)); | 325 assert(offset < static_cast<size_t>(header_.num_elements)); |
| 276 return Traits::ToRef(storage(), offset); | 326 return Traits::ToRef(storage(), offset); |
| 277 } | 327 } |
| 278 | 328 |
| 279 ConstRef at(size_t offset) const { | 329 ConstRef at(size_t offset) const { |
| 280 assert(offset < static_cast<size_t>(header_.num_elements)); | 330 assert(offset < static_cast<size_t>(header_.num_elements)); |
| 281 return Traits::ToConstRef(storage(), offset); | 331 return Traits::ToConstRef(storage(), offset); |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 static Ref ToRef(H& data) { return Ref(&data); } | 453 static Ref ToRef(H& data) { return Ref(&data); } |
| 404 static ConstRef ToConstRef(const H& data) { | 454 static ConstRef ToConstRef(const H& data) { |
| 405 return ConstRef(const_cast<H*>(&data)); | 455 return ConstRef(const_cast<H*>(&data)); |
| 406 } | 456 } |
| 407 }; | 457 }; |
| 408 | 458 |
| 409 } // namespace internal | 459 } // namespace internal |
| 410 } // namespace mojo | 460 } // namespace mojo |
| 411 | 461 |
| 412 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_ | 462 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_ |
| OLD | NEW |