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

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

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

Powered by Google App Engine
This is Rietveld 408576698