Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(669)

Side by Side Diff: mojo/public/bindings/lib/array_internal.h

Issue 220243007: Mojo: Move mojo/public/bindings/lib to mojo/public/cpp/bindings/lib. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « mojo/public/bindings/lib/array.cc ('k') | mojo/public/bindings/lib/array_internal.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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_BINDINGS_LIB_ARRAY_INTERNAL_H_
6 #define MOJO_PUBLIC_BINDINGS_LIB_ARRAY_INTERNAL_H_
7
8 #include <new>
9
10 #include "mojo/public/bindings/lib/bindings_internal.h"
11 #include "mojo/public/bindings/lib/bindings_serialization.h"
12 #include "mojo/public/cpp/bindings/buffer.h"
13 #include "mojo/public/cpp/bindings/passable.h"
14 #include "mojo/public/cpp/system/core.h"
15
16 namespace mojo {
17 template <typename T> class Array;
18
19 namespace internal {
20
21 template <typename T>
22 struct ArrayDataTraits {
23 typedef T StorageType;
24 typedef Array<T> Wrapper;
25 typedef T& Ref;
26 typedef T const& ConstRef;
27
28 static size_t GetStorageSize(size_t num_elements) {
29 return sizeof(StorageType) * num_elements;
30 }
31 static Ref ToRef(StorageType* storage, size_t offset) {
32 return storage[offset];
33 }
34 static ConstRef ToConstRef(const StorageType* storage, size_t offset) {
35 return storage[offset];
36 }
37 };
38
39 template <typename P>
40 struct ArrayDataTraits<P*> {
41 typedef StructPointer<P> StorageType;
42 typedef Array<typename P::Wrapper> Wrapper;
43 typedef P*& Ref;
44 typedef P* const& ConstRef;
45
46 static size_t GetStorageSize(size_t num_elements) {
47 return sizeof(StorageType) * num_elements;
48 }
49 static Ref ToRef(StorageType* storage, size_t offset) {
50 return storage[offset].ptr;
51 }
52 static ConstRef ToConstRef(const StorageType* storage, size_t offset) {
53 return storage[offset].ptr;
54 }
55 };
56
57 // Specialization of Arrays for bools, optimized for space. It has the
58 // following differences from a generalized Array:
59 // * Each element takes up a single bit of memory.
60 // * Accessing a non-const single element uses a helper class |BitRef|, which
61 // emulates a reference to a bool.
62 template <>
63 struct ArrayDataTraits<bool> {
64 // Helper class to emulate a reference to a bool, used for direct element
65 // access.
66 class BitRef {
67 public:
68 ~BitRef();
69 BitRef& operator=(bool value);
70 BitRef& operator=(const BitRef& value);
71 operator bool() const;
72 private:
73 friend struct ArrayDataTraits<bool>;
74 BitRef(uint8_t* storage, uint8_t mask);
75 BitRef();
76 uint8_t* storage_;
77 uint8_t mask_;
78 };
79
80 typedef uint8_t StorageType;
81 typedef Array<bool> Wrapper;
82 typedef BitRef Ref;
83 typedef bool ConstRef;
84
85 static size_t GetStorageSize(size_t num_elements) {
86 return ((num_elements + 7) / 8);
87 }
88 static BitRef ToRef(StorageType* storage, size_t offset) {
89 return BitRef(&storage[offset / 8], 1 << (offset % 8));
90 }
91 static bool ToConstRef(const StorageType* storage, size_t offset) {
92 return (storage[offset / 8] & (1 << (offset % 8))) != 0;
93 }
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
190 template <typename T>
191 class Array_Data {
192 public:
193 typedef ArrayDataTraits<T> Traits;
194 typedef typename Traits::StorageType StorageType;
195 typedef typename Traits::Wrapper Wrapper;
196 typedef typename Traits::Ref Ref;
197 typedef typename Traits::ConstRef ConstRef;
198
199 static Array_Data<T>* New(size_t num_elements, Buffer* buf) {
200 size_t num_bytes = sizeof(Array_Data<T>) +
201 Traits::GetStorageSize(num_elements);
202 return new (buf->Allocate(num_bytes)) Array_Data<T>(num_bytes,
203 num_elements);
204 }
205
206 size_t size() const { return header_.num_elements; }
207
208 Ref at(size_t offset) {
209 assert(offset < static_cast<size_t>(header_.num_elements));
210 return Traits::ToRef(storage(), offset);
211 }
212
213 ConstRef at(size_t offset) const {
214 assert(offset < static_cast<size_t>(header_.num_elements));
215 return Traits::ToConstRef(storage(), offset);
216 }
217
218 StorageType* storage() {
219 return reinterpret_cast<StorageType*>(
220 reinterpret_cast<char*>(this) + sizeof(*this));
221 }
222
223 const StorageType* storage() const {
224 return reinterpret_cast<const StorageType*>(
225 reinterpret_cast<const char*>(this) + sizeof(*this));
226 }
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
259 private:
260 Array_Data(size_t num_bytes, size_t num_elements) {
261 header_.num_bytes = static_cast<uint32_t>(num_bytes);
262 header_.num_elements = static_cast<uint32_t>(num_elements);
263 }
264 ~Array_Data() {}
265
266 internal::ArrayHeader header_;
267
268 // Elements of type internal::ArrayDataTraits<T>::StorageType follow.
269 };
270 MOJO_COMPILE_ASSERT(sizeof(Array_Data<char>) == 8, bad_sizeof_Array_Data);
271
272 // UTF-8 encoded
273 typedef Array_Data<char> String_Data;
274
275 template <typename T, bool kIsObject> struct ArrayTraits {};
276
277 template <typename T> struct ArrayTraits<T, true> {
278 typedef Array_Data<typename T::Data*> DataType;
279 typedef const T& ConstRef;
280 typedef T& Ref;
281 static typename T::Data* ToArrayElement(const T& value) {
282 return Unwrap(value);
283 }
284 // Something sketchy is indeed happening here...
285 static Ref ToRef(typename T::Data*& data) {
286 return *reinterpret_cast<T*>(&data);
287 }
288 static ConstRef ToConstRef(typename T::Data* const& data) {
289 return *reinterpret_cast<const T*>(&data);
290 }
291 };
292
293 template <typename T> struct ArrayTraits<T, false> {
294 typedef Array_Data<T> DataType;
295 typedef const T& ConstRef;
296 typedef T& Ref;
297 static T ToArrayElement(const T& value) {
298 return value;
299 }
300 static Ref ToRef(T& data) { return data; }
301 static ConstRef ToConstRef(const T& data) { return data; }
302 };
303
304 template <> struct ArrayTraits<bool, false> {
305 typedef Array_Data<bool> DataType;
306 typedef bool ConstRef;
307 typedef ArrayDataTraits<bool>::Ref Ref;
308 static bool ToArrayElement(const bool& value) {
309 return value;
310 }
311 static Ref ToRef(const Ref& data) { return data; }
312 static ConstRef ToConstRef(ConstRef data) { return data; }
313 };
314
315 template <> struct ArrayTraits<Handle, false> {
316 typedef Array_Data<Handle> DataType;
317 typedef Passable<Handle> ConstRef;
318 typedef AssignableAndPassable<Handle> Ref;
319 static Handle ToArrayElement(const Handle& value) {
320 return value;
321 }
322 static Ref ToRef(Handle& data) { return Ref(&data); }
323 static ConstRef ToConstRef(const Handle& data) {
324 return ConstRef(const_cast<Handle*>(&data));
325 }
326 };
327
328 template <> struct ArrayTraits<DataPipeConsumerHandle, false> {
329 typedef Array_Data<DataPipeConsumerHandle> DataType;
330 typedef Passable<DataPipeConsumerHandle> ConstRef;
331 typedef AssignableAndPassable<DataPipeConsumerHandle> Ref;
332 static DataPipeConsumerHandle ToArrayElement(
333 const DataPipeConsumerHandle& value) {
334 return value;
335 }
336 static Ref ToRef(DataPipeConsumerHandle& data) { return Ref(&data); }
337 static ConstRef ToConstRef(const DataPipeConsumerHandle& data) {
338 return ConstRef(const_cast<DataPipeConsumerHandle*>(&data));
339 }
340 };
341
342 template <> struct ArrayTraits<DataPipeProducerHandle, false> {
343 typedef Array_Data<DataPipeProducerHandle> DataType;
344 typedef Passable<DataPipeProducerHandle> ConstRef;
345 typedef AssignableAndPassable<DataPipeProducerHandle> Ref;
346 static DataPipeProducerHandle ToArrayElement(
347 const DataPipeProducerHandle& value) {
348 return value;
349 }
350 static Ref ToRef(DataPipeProducerHandle& data) { return Ref(&data); }
351 static ConstRef ToConstRef(const DataPipeProducerHandle& data) {
352 return ConstRef(const_cast<DataPipeProducerHandle*>(&data));
353 }
354 };
355
356 template <> struct ArrayTraits<MessagePipeHandle, false> {
357 typedef Array_Data<MessagePipeHandle> DataType;
358 typedef Passable<MessagePipeHandle> ConstRef;
359 typedef AssignableAndPassable<MessagePipeHandle> Ref;
360 static MessagePipeHandle ToArrayElement(const MessagePipeHandle& value) {
361 return value;
362 }
363 static Ref ToRef(MessagePipeHandle& data) { return Ref(&data); }
364 static ConstRef ToConstRef(const MessagePipeHandle& data) {
365 return ConstRef(const_cast<MessagePipeHandle*>(&data));
366 }
367 };
368
369 } // namespace internal
370 } // namespace mojo
371
372 #endif // MOJO_PUBLIC_BINDINGS_LIB_ARRAY_INTERNAL_H_
OLDNEW
« no previous file with comments | « mojo/public/bindings/lib/array.cc ('k') | mojo/public/bindings/lib/array_internal.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698