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

Side by Side Diff: mojo/public/c/bindings/lib/type_descriptor.c

Issue 2232833003: Change the canonical way to include the C bindings headers to <mojo/bindings/*.h>. (Closed) Base URL: https://github.com/domokit/mojo.git@work791_mojo_tests
Patch Set: rebased Created 4 years, 4 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
« no previous file with comments | « mojo/public/c/bindings/lib/type_descriptor.h ('k') | mojo/public/c/bindings/lib/union.c » ('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 2016 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 #include "mojo/public/c/bindings/lib/type_descriptor.h"
6
7 #include <assert.h>
8 #include <stddef.h>
9
10 #include "mojo/public/c/bindings/array.h"
11 #include "mojo/public/c/bindings/interface.h"
12 #include "mojo/public/c/bindings/lib/util.h"
13 #include "mojo/public/c/bindings/map.h"
14 #include "mojo/public/c/bindings/struct.h"
15 #include "mojo/public/c/bindings/union.h"
16
17 const struct MojomTypeDescriptorArray g_mojom_string_type_description = {
18 .elem_type = MOJOM_TYPE_DESCRIPTOR_TYPE_POD,
19 .elem_descriptor = NULL,
20 .num_elements = 0,
21 .elem_num_bits = 8,
22 .nullable = false,
23 };
24
25 // The encoding of a MojoHandle is an index into an array of Handles. A
26 // null/invalid handle is encoded as index (which is unsigned) "-1", which
27 // equates to the highest possible index.
28 static const MojoHandle kEncodedHandleInvalid = (MojoHandle)-1;
29
30 bool MojomType_IsPointer(enum MojomTypeDescriptorType type) {
31 return type == MOJOM_TYPE_DESCRIPTOR_TYPE_STRUCT_PTR ||
32 type == MOJOM_TYPE_DESCRIPTOR_TYPE_MAP_PTR ||
33 type == MOJOM_TYPE_DESCRIPTOR_TYPE_ARRAY_PTR ||
34 type == MOJOM_TYPE_DESCRIPTOR_TYPE_UNION_PTR;
35 }
36
37 size_t MojomType_DispatchComputeSerializedSize(
38 enum MojomTypeDescriptorType type,
39 const void* type_desc,
40 bool nullable,
41 const void* data) {
42 const void* data_ptr = data;
43 size_t size = 0;
44 switch (type) {
45 case MOJOM_TYPE_DESCRIPTOR_TYPE_MAP_PTR:
46 case MOJOM_TYPE_DESCRIPTOR_TYPE_STRUCT_PTR: {
47 data_ptr = ((const union MojomPointer*)data_ptr)->ptr;
48 if (!nullable || data_ptr != NULL)
49 return MojomStruct_ComputeSerializedSize(
50 (const struct MojomTypeDescriptorStruct*)type_desc,
51 (const struct MojomStructHeader*)data_ptr);
52 break;
53 }
54 case MOJOM_TYPE_DESCRIPTOR_TYPE_ARRAY_PTR:
55 data_ptr = ((const union MojomPointer*)data_ptr)->ptr;
56 if (!nullable || data_ptr != NULL)
57 return MojomArray_ComputeSerializedSize(type_desc, data_ptr);
58 break;
59 case MOJOM_TYPE_DESCRIPTOR_TYPE_UNION_PTR:
60 data_ptr = ((const union MojomPointer*)data_ptr)->ptr;
61 if (data_ptr != NULL)
62 size = sizeof(struct MojomUnionLayout);
63 // Fall through.
64 case MOJOM_TYPE_DESCRIPTOR_TYPE_UNION: {
65 const struct MojomUnionLayout* udata = data_ptr;
66 // Unions inside unions may be set to null by setting their pointer to
67 // NULL, OR by setting the union's |size| to 0.
68 if (!nullable || (udata && udata->size != 0)) {
69 return size + MojomUnion_ComputeSerializedSize(
70 (const struct MojomTypeDescriptorUnion*)type_desc,
71 (const struct MojomUnionLayout*)data);
72 }
73 break;
74 }
75 case MOJOM_TYPE_DESCRIPTOR_TYPE_HANDLE:
76 case MOJOM_TYPE_DESCRIPTOR_TYPE_INTERFACE:
77 case MOJOM_TYPE_DESCRIPTOR_TYPE_POD:
78 // We should never end up here.
79 assert(false);
80 break;
81 }
82 return size;
83 }
84
85 static void encode_pointer(union MojomPointer* pointer, uint32_t max_offset) {
86 if (pointer->ptr == NULL) {
87 pointer->offset = 0;
88 } else {
89 assert((char*)pointer->ptr > (char*)pointer);
90 assert((size_t)((char*)pointer->ptr - (char*)pointer) < max_offset);
91 pointer->offset = (char*)(pointer->ptr) - (char*)pointer;
92 }
93 }
94
95 static void decode_pointer(union MojomPointer* pointer) {
96 if (pointer->offset == 0) {
97 pointer->ptr = NULL;
98 } else {
99 pointer->ptr = (char*)pointer + pointer->offset;
100 }
101 }
102
103 static void encode_handle(bool nullable, MojoHandle* handle,
104 struct MojomHandleBuffer* handles_buffer) {
105 assert(handle);
106 assert(handles_buffer);
107 assert(handles_buffer->handles);
108
109 if (*handle == MOJO_HANDLE_INVALID) {
110 assert(nullable);
111 *handle = kEncodedHandleInvalid;
112 } else {
113 assert(handles_buffer->num_handles_used < handles_buffer->num_handles);
114
115 handles_buffer->handles[handles_buffer->num_handles_used] = *handle;
116 *handle = handles_buffer->num_handles_used;
117 handles_buffer->num_handles_used++;
118 }
119 }
120
121 // *handle is an index into inout_handles, or is encoded NULL.
122 static void decode_handle(MojoHandle* handle,
123 MojoHandle inout_handles[], uint32_t in_num_handles) {
124 assert(handle);
125 assert(inout_handles);
126
127 if (*handle == kEncodedHandleInvalid) {
128 *handle = MOJO_HANDLE_INVALID;
129 } else {
130 assert(*handle < in_num_handles);
131 MojoHandle index = *handle;
132 *handle = inout_handles[index];
133 inout_handles[index] = MOJO_HANDLE_INVALID;
134 }
135 }
136
137 void MojomType_DispatchEncodePointersAndHandles(
138 enum MojomTypeDescriptorType in_elem_type,
139 const void* in_type_desc,
140 bool in_nullable,
141 void* inout_buf,
142 uint32_t in_buf_size,
143 struct MojomHandleBuffer* inout_handles_buffer) {
144 assert(inout_buf);
145
146 void* union_buf = inout_buf;
147 switch (in_elem_type) {
148 case MOJOM_TYPE_DESCRIPTOR_TYPE_MAP_PTR:
149 case MOJOM_TYPE_DESCRIPTOR_TYPE_STRUCT_PTR: {
150 struct MojomStructHeader* inout_struct =
151 ((union MojomPointer*)inout_buf)->ptr;
152 encode_pointer(inout_buf, in_buf_size);
153 if (!in_nullable || inout_struct != NULL)
154 MojomStruct_EncodePointersAndHandles(
155 (const struct MojomTypeDescriptorStruct*)in_type_desc,
156 inout_struct,
157 in_buf_size - ((char*)inout_struct - (char*)inout_buf),
158 inout_handles_buffer);
159 break;
160 }
161 case MOJOM_TYPE_DESCRIPTOR_TYPE_ARRAY_PTR: {
162 struct MojomArrayHeader* inout_array =
163 ((union MojomPointer*)inout_buf)->ptr;
164 encode_pointer(inout_buf, in_buf_size);
165 if (!in_nullable || inout_array != NULL)
166 MojomArray_EncodePointersAndHandles(
167 (const struct MojomTypeDescriptorArray*)in_type_desc,
168 inout_array,
169 in_buf_size - ((char*)inout_array - (char*)inout_buf),
170 inout_handles_buffer);
171 break;
172 }
173 case MOJOM_TYPE_DESCRIPTOR_TYPE_UNION_PTR:
174 union_buf = ((union MojomPointer*)inout_buf)->ptr;
175 encode_pointer(inout_buf, in_buf_size);
176 // Fall through
177 case MOJOM_TYPE_DESCRIPTOR_TYPE_UNION: {
178 struct MojomUnionLayout* u_data = union_buf;
179 if (!in_nullable || (u_data != NULL && u_data->size != 0))
180 MojomUnion_EncodePointersAndHandles(
181 (const struct MojomTypeDescriptorUnion*)in_type_desc,
182 inout_buf,
183 in_buf_size,
184 inout_handles_buffer);
185 break;
186 }
187 case MOJOM_TYPE_DESCRIPTOR_TYPE_HANDLE:
188 encode_handle(in_nullable, (MojoHandle*)inout_buf, inout_handles_buffer);
189 break;
190 case MOJOM_TYPE_DESCRIPTOR_TYPE_INTERFACE: {
191 struct MojomInterfaceData* interface = inout_buf;
192 encode_handle(in_nullable, &interface->handle, inout_handles_buffer);
193 break;
194 }
195 case MOJOM_TYPE_DESCRIPTOR_TYPE_POD:
196 // We shouldn't ever end up here.
197 assert(false);
198 break;
199 }
200 }
201
202 void MojomType_DispatchDecodePointersAndHandles(
203 enum MojomTypeDescriptorType in_elem_type,
204 const void* in_type_desc,
205 bool in_nullable,
206 void* inout_buf,
207 uint32_t in_buf_size,
208 MojoHandle* inout_handles,
209 uint32_t in_num_handles) {
210 assert(inout_buf);
211
212 void* union_buf = inout_buf;
213 switch (in_elem_type) {
214 case MOJOM_TYPE_DESCRIPTOR_TYPE_MAP_PTR:
215 case MOJOM_TYPE_DESCRIPTOR_TYPE_STRUCT_PTR: {
216 decode_pointer(inout_buf);
217 struct MojomStructHeader* inout_struct =
218 ((union MojomPointer*)inout_buf)->ptr;
219 assert(inout_struct == NULL ||
220 (char*)inout_struct < ((char*)inout_buf) + in_buf_size);
221 if (!in_nullable || inout_struct != NULL)
222 MojomStruct_DecodePointersAndHandles(
223 (const struct MojomTypeDescriptorStruct*)in_type_desc,
224 inout_struct,
225 in_buf_size - ((char*)inout_struct - (char*)inout_buf),
226 inout_handles,
227 in_num_handles);
228 break;
229 }
230 case MOJOM_TYPE_DESCRIPTOR_TYPE_ARRAY_PTR: {
231 decode_pointer(inout_buf);
232 struct MojomArrayHeader* inout_array =
233 ((union MojomPointer*)inout_buf)->ptr;
234 assert(inout_array == NULL ||
235 (char*)inout_array < ((char*)inout_buf) + in_buf_size);
236 if (!in_nullable || inout_array != NULL)
237 MojomArray_DecodePointersAndHandles(
238 (const struct MojomTypeDescriptorArray*)in_type_desc,
239 inout_array,
240 in_buf_size - ((char*)inout_array - (char*)inout_buf),
241 inout_handles,
242 in_num_handles);
243 break;
244 }
245 case MOJOM_TYPE_DESCRIPTOR_TYPE_UNION_PTR:
246 decode_pointer(inout_buf);
247 union_buf = ((union MojomPointer*)inout_buf)->ptr;
248 assert(union_buf == NULL ||
249 (char*)union_buf < ((char*)inout_buf) + in_buf_size);
250 // Fall through
251 case MOJOM_TYPE_DESCRIPTOR_TYPE_UNION: {
252 struct MojomUnionLayout* u_data = union_buf;
253 if (!in_nullable || (u_data != NULL && u_data->size != 0))
254 MojomUnion_DecodePointersAndHandles(
255 (const struct MojomTypeDescriptorUnion*)in_type_desc,
256 inout_buf,
257 in_buf_size,
258 inout_handles,
259 in_num_handles);
260 break;
261 }
262 case MOJOM_TYPE_DESCRIPTOR_TYPE_HANDLE:
263 decode_handle((MojoHandle*)inout_buf, inout_handles,
264 in_num_handles);
265 break;
266 case MOJOM_TYPE_DESCRIPTOR_TYPE_INTERFACE: {
267 struct MojomInterfaceData* interface = inout_buf;
268 decode_handle(&interface->handle, inout_handles,
269 in_num_handles);
270 break;
271 }
272 case MOJOM_TYPE_DESCRIPTOR_TYPE_POD:
273 // We shouldn't ever end up here.
274 assert(false);
275 break;
276 }
277 }
278
279 // Validates that the offset (|pointer->offset|) points to a new memory region,
280 // i.e. one that hasn't been referenced yet. If so, moves the expected offset
281 // (for the next pointer) forward.
282 static MojomValidationResult validate_pointer(
283 const union MojomPointer* pointer,
284 size_t max_offset,
285 bool is_nullable,
286 struct MojomValidationContext* inout_context) {
287 // Offset must be <= UINT32_MAX and within range.
288 if (pointer->offset > max_offset || pointer->offset > UINT32_MAX)
289 return MOJOM_VALIDATION_ILLEGAL_POINTER;
290
291 if (pointer->offset != 0) {
292 if ((char*)pointer + pointer->offset < inout_context->next_pointer)
293 return MOJOM_VALIDATION_ILLEGAL_MEMORY_RANGE;
294
295 inout_context->next_pointer = (char*)pointer + pointer->offset;
296 }
297
298 // Offset must be 8-byte aligned: this check is sufficient, given that all
299 // objects are rounded to 8-bytes.
300 if ((pointer->offset & 7) != 0)
301 return MOJOM_VALIDATION_MISALIGNED_OBJECT;
302
303 if (!is_nullable && pointer->offset == 0)
304 return MOJOM_VALIDATION_UNEXPECTED_NULL_POINTER;
305
306 return MOJOM_VALIDATION_ERROR_NONE;
307 }
308
309 static MojomValidationResult validate_handle(
310 MojoHandle encoded_handle, uint32_t num_handles, bool is_nullable,
311 struct MojomValidationContext* inout_context) {
312 if (!is_nullable && encoded_handle == kEncodedHandleInvalid)
313 return MOJOM_VALIDATION_UNEXPECTED_INVALID_HANDLE;
314
315 if (encoded_handle != kEncodedHandleInvalid) {
316 if (encoded_handle >= num_handles ||
317 encoded_handle < inout_context->next_handle_index)
318 return MOJOM_VALIDATION_ILLEGAL_HANDLE;
319
320 inout_context->next_handle_index = encoded_handle + 1;
321 }
322
323 return MOJOM_VALIDATION_ERROR_NONE;
324 }
325
326 MojomValidationResult MojomType_DispatchValidate(
327 enum MojomTypeDescriptorType in_elem_type, const void* in_type_desc,
328 bool in_nullable, const void* in_buf, uint32_t in_buf_size,
329 uint32_t in_num_handles, struct MojomValidationContext* inout_context) {
330 assert(in_buf);
331
332 struct MojomUnionLayout* union_data = (struct MojomUnionLayout*)in_buf;
333 switch (in_elem_type) {
334 case MOJOM_TYPE_DESCRIPTOR_TYPE_MAP_PTR:
335 case MOJOM_TYPE_DESCRIPTOR_TYPE_STRUCT_PTR: {
336 union MojomPointer* pointer = (union MojomPointer*)in_buf;
337 MojomValidationResult result =
338 validate_pointer(pointer, in_buf_size, in_nullable, inout_context);
339 if (result != MOJOM_VALIDATION_ERROR_NONE || pointer->offset == 0)
340 return result;
341
342 result = MojomStruct_Validate(
343 (const struct MojomTypeDescriptorStruct*)in_type_desc,
344 (const struct MojomStructHeader*)((char*)in_buf + pointer->offset),
345 in_buf_size - pointer->offset, in_num_handles, inout_context);
346
347 if (result == MOJOM_VALIDATION_ERROR_NONE &&
348 in_elem_type == MOJOM_TYPE_DESCRIPTOR_TYPE_MAP_PTR) {
349 return MojomMap_Validate(
350 (const struct MojomTypeDescriptorStruct*)in_type_desc,
351 (const struct MojomStructHeader*)((char*)in_buf + pointer->offset),
352 in_buf_size - pointer->offset, in_num_handles, inout_context);
353 }
354
355 return result;
356 }
357 case MOJOM_TYPE_DESCRIPTOR_TYPE_ARRAY_PTR: {
358 union MojomPointer* pointer = (union MojomPointer*)in_buf;
359 MojomValidationResult result =
360 validate_pointer(pointer, in_buf_size, in_nullable, inout_context);
361 if (result != MOJOM_VALIDATION_ERROR_NONE || pointer->offset == 0)
362 return result;
363
364 return MojomArray_Validate(
365 (const struct MojomTypeDescriptorArray*)in_type_desc,
366 (const struct MojomArrayHeader*)((char*)in_buf + pointer->offset),
367 in_buf_size - pointer->offset, in_num_handles, inout_context);
368 }
369 case MOJOM_TYPE_DESCRIPTOR_TYPE_UNION_PTR: {
370 union MojomPointer* pointer = (union MojomPointer*)in_buf;
371 MojomValidationResult result =
372 validate_pointer(pointer, in_buf_size, in_nullable, inout_context);
373 if (result != MOJOM_VALIDATION_ERROR_NONE || pointer->offset == 0)
374 return result;
375
376 // Since this union is a pointer, we update |next_pointer| to be past the
377 // union data.
378 inout_context->next_pointer += sizeof(struct MojomUnionLayout);
379
380 union_data = (struct MojomUnionLayout*)((char*)in_buf + pointer->offset);
381 // Fall through.
382 }
383 case MOJOM_TYPE_DESCRIPTOR_TYPE_UNION:
384 if (union_data->size == 0) {
385 return in_nullable ? MOJOM_VALIDATION_ERROR_NONE
386 : MOJOM_VALIDATION_UNEXPECTED_NULL_UNION;
387 }
388
389 return MojomUnion_Validate(
390 (const struct MojomTypeDescriptorUnion*)in_type_desc, in_nullable,
391 union_data, in_buf_size - ((char*)union_data - (char*)in_buf),
392 in_num_handles, inout_context);
393 case MOJOM_TYPE_DESCRIPTOR_TYPE_HANDLE:
394 return validate_handle(*(const MojoHandle*)in_buf, in_num_handles,
395 in_nullable, inout_context);
396 case MOJOM_TYPE_DESCRIPTOR_TYPE_INTERFACE:
397 return validate_handle(((const struct MojomInterfaceData*)in_buf)->handle,
398 in_num_handles, in_nullable, inout_context);
399 case MOJOM_TYPE_DESCRIPTOR_TYPE_POD:
400 break;
401 }
402 return MOJOM_VALIDATION_ERROR_NONE;
403 }
404
405 bool MojomType_DispatchDeepCopy(struct MojomBuffer* buffer,
406 enum MojomTypeDescriptorType in_elem_type,
407 const void* in_type_desc,
408 const void* in_data,
409 void* out_data) {
410 assert(in_data);
411
412 const struct MojomUnionLayout* in_union_data =
413 (const struct MojomUnionLayout*)in_data;
414 struct MojomUnionLayout* out_union_data = (struct MojomUnionLayout*)out_data;
415 const union MojomPointer* in_pointer = in_data;
416 switch (in_elem_type) {
417 case MOJOM_TYPE_DESCRIPTOR_TYPE_MAP_PTR:
418 case MOJOM_TYPE_DESCRIPTOR_TYPE_STRUCT_PTR:
419 if (in_pointer->ptr == NULL) {
420 ((union MojomPointer*)out_data)->ptr = NULL;
421 break;
422 }
423 return MojomStruct_DeepCopy(
424 buffer, (const struct MojomTypeDescriptorStruct*)in_type_desc,
425 ((union MojomPointer*)in_data)->ptr,
426 out_data);
427 case MOJOM_TYPE_DESCRIPTOR_TYPE_ARRAY_PTR:
428 if (in_pointer->ptr == NULL) {
429 ((union MojomPointer*)out_data)->ptr = NULL;
430 break;
431 }
432 return MojomArray_DeepCopy(
433 buffer, (const struct MojomTypeDescriptorArray*)in_type_desc,
434 ((union MojomPointer*)in_data)->ptr,
435 out_data);
436 case MOJOM_TYPE_DESCRIPTOR_TYPE_UNION_PTR:
437 in_union_data = ((const union MojomPointer*)in_data)->ptr;
438 if (in_union_data == NULL) {
439 ((union MojomPointer*)out_data)->ptr = NULL;
440 break;
441 }
442 out_union_data =
443 MojomBuffer_Allocate(buffer, sizeof(struct MojomUnionLayout));
444 if (out_union_data == NULL)
445 return false;
446 ((union MojomPointer*)out_data)->ptr = out_union_data;
447 // Fall through.
448 case MOJOM_TYPE_DESCRIPTOR_TYPE_UNION:
449 return MojomUnion_DeepCopy(buffer,
450 (const struct MojomTypeDescriptorUnion*)in_type_desc,
451 in_union_data,
452 out_union_data);
453 case MOJOM_TYPE_DESCRIPTOR_TYPE_HANDLE:
454 case MOJOM_TYPE_DESCRIPTOR_TYPE_INTERFACE:
455 case MOJOM_TYPE_DESCRIPTOR_TYPE_POD:
456 break;
457 }
458
459 return true;
460 }
OLDNEW
« no previous file with comments | « mojo/public/c/bindings/lib/type_descriptor.h ('k') | mojo/public/c/bindings/lib/union.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698