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

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

Issue 27034003: Mojo C++ bindings (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix compilation issue on Official Linux builder Created 7 years, 2 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
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_BINDINGS_SERIALIZATION_H_
6 #define MOJO_PUBLIC_BINDINGS_LIB_BINDINGS_SERIALIZATION_H_
7
8 #include <string.h>
9
10 #include <vector>
11
12 #include "mojo/public/bindings/lib/bindings.h"
13 #include "mojo/public/bindings/lib/message.h"
14
15 namespace mojo {
16 namespace internal {
17
18 size_t Align(size_t size);
19
20 // Pointers are encoded as relative offsets. The offsets are relative to the
21 // address of where the offset value is stored, such that the pointer may be
22 // recovered with the expression:
23 //
24 // ptr = reinterpret_cast<char*>(offset) + *offset
25 //
26 // A null pointer is encoded as an offset value of 0.
27 //
28 void EncodePointer(const void* ptr, uint64_t* offset);
29 const void* DecodePointerRaw(const uint64_t* offset);
30
31 template <typename T>
32 inline void DecodePointer(const uint64_t* offset, T** ptr) {
33 *ptr = reinterpret_cast<T*>(const_cast<void*>(DecodePointerRaw(offset)));
34 }
35
36 // Check that the given pointer references memory contained within the message.
37 bool ValidatePointer(const void* ptr, const Message& message);
38
39 // Handles are encoded as indices into a vector of handles. These functions
40 // manipulate the value of |handle|, mapping it to and from an index.
41 void EncodeHandle(Handle* handle, std::vector<Handle>* handles);
42 bool DecodeHandle(Handle* handle, const std::vector<Handle>& handles);
43
44 // All objects (structs and arrays) support the following operations:
45 // - computing size
46 // - cloning
47 // - encoding pointers and handles
48 // - decoding pointers and handles
49 //
50 // The following functions are used to select the proper ObjectTraits<>
51 // specialization.
52
53 template <typename T>
54 inline size_t ComputeAlignedSizeOf(const T* obj) {
55 return obj ? ObjectTraits<T>::ComputeAlignedSizeOf(obj) : 0;
56 }
57
58 template <typename T>
59 inline T* Clone(const T* obj, Buffer* buf) {
60 return obj ? ObjectTraits<T>::Clone(obj, buf) : NULL;
61 }
62
63 template <typename T>
64 inline void EncodePointersAndHandles(T* obj,
65 std::vector<Handle>* handles) {
66 ObjectTraits<T>::EncodePointersAndHandles(obj, handles);
67 }
68
69 template <typename T>
70 inline bool DecodePointersAndHandles(T* obj, const Message& message) {
71 return ObjectTraits<T>::DecodePointersAndHandles(obj, message);
72 }
73
74 // The following 2 functions are used to encode/decode all objects (structs and
75 // arrays) in a consistent manner.
76
77 template <typename T>
78 inline void Encode(T* obj, std::vector<Handle>* handles) {
79 if (obj->ptr)
80 EncodePointersAndHandles(obj->ptr, handles);
81 EncodePointer(obj->ptr, &obj->offset);
82 }
83
84 template <typename T>
85 inline bool Decode(T* obj, const Message& message) {
86 DecodePointer(&obj->offset, &obj->ptr);
87 if (obj->ptr) {
88 if (!ValidatePointer(obj->ptr, message))
89 return false;
90 if (!DecodePointersAndHandles(obj->ptr, message))
91 return false;
92 }
93 return true;
94 }
95
96 // What follows is code to support the ObjectTraits<> specialization of
97 // Array<T>. There are two interesting cases: arrays of primitives and arrays
98 // of objects. Arrays of objects are represented as arrays of pointers to
99 // objects.
100
101 template <typename T>
102 struct ArrayHelper {
103 typedef T ElementType;
104
105 static size_t ComputeAlignedSizeOfElements(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 EncodePointersAndHandles(const ArrayHeader* header,
116 ElementType* elements,
117 std::vector<Handle>* handles) {
118 }
119 static bool DecodePointersAndHandles(const ArrayHeader* header,
120 ElementType* elements,
121 const Message& message) {
122 return true;
123 }
dmichael (off chromium) 2013/10/14 22:41:19 Would it be better to simply leave all of these fu
124 };
125
126 template <>
127 struct ArrayHelper<Handle> {
128 typedef Handle ElementType;
129
130 static size_t ComputeAlignedSizeOfElements(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 static bool DecodePointersAndHandles(const ArrayHeader* header,
144 ElementType* elements,
145 const Message& message);
146 };
147
148 template <typename P>
149 struct ArrayHelper<P*> {
150 typedef StructPointer<P> ElementType;
151
152 static size_t ComputeAlignedSizeOfElements(const ArrayHeader* header,
153 const ElementType* elements) {
154 size_t result = 0;
155 for (uint32_t i = 0; i < header->num_elements; ++i)
156 result += ComputeAlignedSizeOf(elements[i].ptr);
dmichael (off chromium) 2013/10/14 22:41:19 Sorry if this is a dumb question, but it looks lik
157 return result;
158 }
159
160 static void CloneElements(const ArrayHeader* header,
161 ElementType* elements,
162 Buffer* buf) {
163 for (uint32_t i = 0; i < header->num_elements; ++i)
164 elements[i].ptr = Clone(elements[i].ptr, buf);
165 }
166
167 static void EncodePointersAndHandles(const ArrayHeader* header,
168 ElementType* elements,
169 std::vector<Handle>* handles) {
170 for (uint32_t i = 0; i < header->num_elements; ++i)
171 Encode(&elements[i], handles);
172 }
173 static bool DecodePointersAndHandles(const ArrayHeader* header,
174 ElementType* elements,
175 const Message& message) {
176 for (uint32_t i = 0; i < header->num_elements; ++i) {
177 if (!Decode(&elements[i], message))
178 return false;
179 }
180 return true;
181 }
182 };
183
184 template <typename T>
185 class ObjectTraits<Array<T> > {
186 public:
187 static size_t ComputeAlignedSizeOf(const Array<T>* array) {
188 return Align(array->header_.num_bytes) +
189 ArrayHelper<T>::ComputeAlignedSizeOfElements(&array->header_,
190 array->storage());
191 }
192
193 static Array<T>* Clone(const Array<T>* array, Buffer* buf) {
194 Array<T>* clone = Array<T>::New(buf, array->header_.num_elements);
195 memcpy(clone->storage(),
196 array->storage(),
197 array->header_.num_bytes - sizeof(Array<T>));
198
199 ArrayHelper<T>::CloneElements(&clone->header_, clone->storage(), buf);
200 return clone;
201 }
202
203 static void EncodePointersAndHandles(Array<T>* array,
204 std::vector<Handle>* handles) {
205 ArrayHelper<T>::EncodePointersAndHandles(&array->header_, array->storage(),
206 handles);
207 }
208
209 static bool DecodePointersAndHandles(Array<T>* array,
210 const Message& message) {
211 return ArrayHelper<T>::DecodePointersAndHandles(&array->header_,
212 array->storage(),
213 message);
214 }
215 };
216
217 } // namespace internal
218 } // namespace mojo
219
220 #endif // MOJO_PUBLIC_BINDINGS_LIB_BINDINGS_SERIALIZATION_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698