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_BINDINGS_LIB_ARRAY_INTERNAL_H_ | 5 #ifndef MOJO_PUBLIC_BINDINGS_LIB_ARRAY_INTERNAL_H_ |
6 #define MOJO_PUBLIC_BINDINGS_LIB_ARRAY_INTERNAL_H_ | 6 #define MOJO_PUBLIC_BINDINGS_LIB_ARRAY_INTERNAL_H_ |
7 | 7 |
8 #include <new> | 8 #include <new> |
9 | 9 |
10 #include "mojo/public/bindings/lib/bindings_internal.h" | 10 #include "mojo/public/bindings/lib/bindings_internal.h" |
| 11 #include "mojo/public/bindings/lib/bindings_serialization.h" |
11 #include "mojo/public/bindings/lib/buffer.h" | 12 #include "mojo/public/bindings/lib/buffer.h" |
12 #include "mojo/public/bindings/lib/passable.h" | 13 #include "mojo/public/bindings/lib/passable.h" |
13 #include "mojo/public/system/core_cpp.h" | 14 #include "mojo/public/system/core_cpp.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> |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 return ((num_elements + 7) / 8); | 86 return ((num_elements + 7) / 8); |
86 } | 87 } |
87 static BitRef ToRef(StorageType* storage, size_t offset) { | 88 static BitRef ToRef(StorageType* storage, size_t offset) { |
88 return BitRef(&storage[offset / 8], 1 << (offset % 8)); | 89 return BitRef(&storage[offset / 8], 1 << (offset % 8)); |
89 } | 90 } |
90 static bool ToConstRef(const StorageType* storage, size_t offset) { | 91 static bool ToConstRef(const StorageType* storage, size_t offset) { |
91 return (storage[offset / 8] & (1 << (offset % 8))) != 0; | 92 return (storage[offset / 8] & (1 << (offset % 8))) != 0; |
92 } | 93 } |
93 }; | 94 }; |
94 | 95 |
| 96 // What follows is code to support the serialization of Array_Data<T>. There |
| 97 // are two interesting cases: arrays of primitives and arrays of objects. |
| 98 // Arrays of objects are represented as arrays of pointers to objects. |
| 99 |
| 100 template <typename T> |
| 101 struct ArraySerializationHelper { |
| 102 typedef T ElementType; |
| 103 |
| 104 static size_t ComputeSizeOfElements(const ArrayHeader* header, |
| 105 const ElementType* elements) { |
| 106 return 0; |
| 107 } |
| 108 |
| 109 static void CloneElements(const ArrayHeader* header, |
| 110 ElementType* elements, |
| 111 Buffer* buf) { |
| 112 } |
| 113 |
| 114 static void EncodePointersAndHandles(const ArrayHeader* header, |
| 115 ElementType* elements, |
| 116 std::vector<Handle>* handles) { |
| 117 } |
| 118 |
| 119 static bool DecodePointersAndHandles(const ArrayHeader* header, |
| 120 ElementType* elements, |
| 121 Message* message) { |
| 122 return true; |
| 123 } |
| 124 }; |
| 125 |
| 126 template <> |
| 127 struct ArraySerializationHelper<Handle> { |
| 128 typedef Handle ElementType; |
| 129 |
| 130 static size_t ComputeSizeOfElements(const ArrayHeader* header, |
| 131 const ElementType* elements) { |
| 132 return 0; |
| 133 } |
| 134 |
| 135 static void CloneElements(const ArrayHeader* header, |
| 136 ElementType* elements, |
| 137 Buffer* buf) { |
| 138 } |
| 139 |
| 140 static void EncodePointersAndHandles(const ArrayHeader* header, |
| 141 ElementType* elements, |
| 142 std::vector<Handle>* handles); |
| 143 |
| 144 static bool DecodePointersAndHandles(const ArrayHeader* header, |
| 145 ElementType* elements, |
| 146 Message* message); |
| 147 }; |
| 148 |
| 149 template <typename P> |
| 150 struct ArraySerializationHelper<P*> { |
| 151 typedef StructPointer<P> ElementType; |
| 152 |
| 153 static size_t ComputeSizeOfElements(const ArrayHeader* header, |
| 154 const ElementType* elements) { |
| 155 size_t result = 0; |
| 156 for (uint32_t i = 0; i < header->num_elements; ++i) { |
| 157 if (elements[i].ptr) |
| 158 result += elements[i].ptr->ComputeSize(); |
| 159 } |
| 160 return result; |
| 161 } |
| 162 |
| 163 static void CloneElements(const ArrayHeader* header, |
| 164 ElementType* elements, |
| 165 Buffer* buf) { |
| 166 for (uint32_t i = 0; i < header->num_elements; ++i) { |
| 167 if (elements[i].ptr) |
| 168 elements[i].ptr = elements[i].ptr->Clone(buf); |
| 169 } |
| 170 } |
| 171 |
| 172 static void EncodePointersAndHandles(const ArrayHeader* header, |
| 173 ElementType* elements, |
| 174 std::vector<Handle>* handles) { |
| 175 for (uint32_t i = 0; i < header->num_elements; ++i) |
| 176 Encode(&elements[i], handles); |
| 177 } |
| 178 |
| 179 static bool DecodePointersAndHandles(const ArrayHeader* header, |
| 180 ElementType* elements, |
| 181 Message* message) { |
| 182 for (uint32_t i = 0; i < header->num_elements; ++i) { |
| 183 if (!Decode(&elements[i], message)) |
| 184 return false; |
| 185 } |
| 186 return true; |
| 187 } |
| 188 }; |
| 189 |
95 template <typename T> | 190 template <typename T> |
96 class Array_Data { | 191 class Array_Data { |
97 public: | 192 public: |
98 typedef ArrayDataTraits<T> Traits; | 193 typedef ArrayDataTraits<T> Traits; |
99 typedef typename Traits::StorageType StorageType; | 194 typedef typename Traits::StorageType StorageType; |
100 typedef typename Traits::Wrapper Wrapper; | 195 typedef typename Traits::Wrapper Wrapper; |
101 typedef typename Traits::Ref Ref; | 196 typedef typename Traits::Ref Ref; |
102 typedef typename Traits::ConstRef ConstRef; | 197 typedef typename Traits::ConstRef ConstRef; |
103 | 198 |
104 static Array_Data<T>* New(size_t num_elements, Buffer* buf) { | 199 static Array_Data<T>* New(size_t num_elements, Buffer* buf) { |
(...skipping 18 matching lines...) Expand all Loading... |
123 StorageType* storage() { | 218 StorageType* storage() { |
124 return reinterpret_cast<StorageType*>( | 219 return reinterpret_cast<StorageType*>( |
125 reinterpret_cast<char*>(this) + sizeof(*this)); | 220 reinterpret_cast<char*>(this) + sizeof(*this)); |
126 } | 221 } |
127 | 222 |
128 const StorageType* storage() const { | 223 const StorageType* storage() const { |
129 return reinterpret_cast<const StorageType*>( | 224 return reinterpret_cast<const StorageType*>( |
130 reinterpret_cast<const char*>(this) + sizeof(*this)); | 225 reinterpret_cast<const char*>(this) + sizeof(*this)); |
131 } | 226 } |
132 | 227 |
| 228 size_t ComputeSize() const { |
| 229 return Align(header_.num_bytes) + |
| 230 ArraySerializationHelper<T>::ComputeSizeOfElements(&header_, storage()); |
| 231 } |
| 232 |
| 233 Array_Data<T>* Clone(Buffer* buf) const { |
| 234 Array_Data<T>* clone = New(header_.num_elements, buf); |
| 235 memcpy(clone->storage(), |
| 236 storage(), |
| 237 header_.num_bytes - sizeof(Array_Data<T>)); |
| 238 |
| 239 ArraySerializationHelper<T>::CloneElements(&clone->header_, |
| 240 clone->storage(), buf); |
| 241 return clone; |
| 242 } |
| 243 |
| 244 void CloseHandles() { |
| 245 // TODO(darin): Implement! |
| 246 } |
| 247 |
| 248 void EncodePointersAndHandles(std::vector<Handle>* handles) { |
| 249 ArraySerializationHelper<T>::EncodePointersAndHandles(&header_, storage(), |
| 250 handles); |
| 251 } |
| 252 |
| 253 bool DecodePointersAndHandles(Message* message) { |
| 254 return ArraySerializationHelper<T>::DecodePointersAndHandles(&header_, |
| 255 storage(), |
| 256 message); |
| 257 } |
| 258 |
133 private: | 259 private: |
134 friend class internal::ObjectTraits<Array_Data<T> >; | |
135 | |
136 Array_Data(size_t num_bytes, size_t num_elements) { | 260 Array_Data(size_t num_bytes, size_t num_elements) { |
137 header_.num_bytes = static_cast<uint32_t>(num_bytes); | 261 header_.num_bytes = static_cast<uint32_t>(num_bytes); |
138 header_.num_elements = static_cast<uint32_t>(num_elements); | 262 header_.num_elements = static_cast<uint32_t>(num_elements); |
139 } | 263 } |
140 ~Array_Data() {} | 264 ~Array_Data() {} |
141 | 265 |
142 internal::ArrayHeader header_; | 266 internal::ArrayHeader header_; |
143 | 267 |
144 // Elements of type internal::ArrayDataTraits<T>::StorageType follow. | 268 // Elements of type internal::ArrayDataTraits<T>::StorageType follow. |
145 }; | 269 }; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 static Ref ToRef(MessagePipeHandle& data) { return Ref(&data); } | 363 static Ref ToRef(MessagePipeHandle& data) { return Ref(&data); } |
240 static ConstRef ToConstRef(const MessagePipeHandle& data) { | 364 static ConstRef ToConstRef(const MessagePipeHandle& data) { |
241 return ConstRef(const_cast<MessagePipeHandle*>(&data)); | 365 return ConstRef(const_cast<MessagePipeHandle*>(&data)); |
242 } | 366 } |
243 }; | 367 }; |
244 | 368 |
245 } // namespace internal | 369 } // namespace internal |
246 } // namespace mojo | 370 } // namespace mojo |
247 | 371 |
248 #endif // MOJO_PUBLIC_BINDINGS_LIB_ARRAY_INTERNAL_H_ | 372 #endif // MOJO_PUBLIC_BINDINGS_LIB_ARRAY_INTERNAL_H_ |
OLD | NEW |