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

Side by Side Diff: mojo/public/c/lib/bindings/array.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/include/mojo/system/wait_set.h ('k') | mojo/public/c/lib/bindings/buffer.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/array.h>
6
7 #include <assert.h>
8 #include <mojo/bindings/buffer.h>
9 #include <mojo/bindings/interface.h>
10 #include <mojo/bindings/internal/type_descriptor.h>
11 #include <mojo/bindings/internal/util.h>
12 #include <mojo/bindings/union.h>
13 #include <stddef.h>
14 #include <stdint.h>
15 #include <string.h>
16
17 struct MojomArrayHeader* MojomArray_New(struct MojomBuffer* buf,
18 uint32_t num_elements,
19 uint32_t element_byte_size) {
20 assert(buf);
21
22 uint64_t num_bytes = sizeof(struct MojomArrayHeader) +
23 (uint64_t)num_elements * element_byte_size;
24 if (num_bytes > UINT32_MAX)
25 return NULL;
26
27 struct MojomArrayHeader* arr =
28 (struct MojomArrayHeader*)MojomBuffer_Allocate(buf, (uint32_t)num_bytes);
29 if (arr == NULL)
30 return NULL;
31
32 assert((uintptr_t)arr + MOJOM_INTERNAL_ROUND_TO_8(num_bytes) ==
33 (uintptr_t)buf->buf + buf->num_bytes_used);
34
35 arr->num_elements = num_elements;
36 arr->num_bytes = MOJOM_INTERNAL_ROUND_TO_8((uint32_t)num_bytes);
37
38 return arr;
39 }
40
41 // Gets the |index|th element (whose type is described by |type|) of |array|.
42 // Only supports non-POD types.
43 static void* array_index_by_type(const struct MojomArrayHeader* array,
44 enum MojomTypeDescriptorType type,
45 size_t index) {
46 switch (type) {
47 case MOJOM_TYPE_DESCRIPTOR_TYPE_STRUCT_PTR:
48 case MOJOM_TYPE_DESCRIPTOR_TYPE_MAP_PTR:
49 case MOJOM_TYPE_DESCRIPTOR_TYPE_ARRAY_PTR:
50 return MOJOM_ARRAY_INDEX(array, union MojomPointer, index);
51 case MOJOM_TYPE_DESCRIPTOR_TYPE_UNION:
52 return MOJOM_ARRAY_INDEX(array, struct MojomUnionLayout, index);
53 case MOJOM_TYPE_DESCRIPTOR_TYPE_HANDLE:
54 return MOJOM_ARRAY_INDEX(array, MojoHandle, index);
55 case MOJOM_TYPE_DESCRIPTOR_TYPE_INTERFACE:
56 return MOJOM_ARRAY_INDEX(array, struct MojomInterfaceData, index);
57 case MOJOM_TYPE_DESCRIPTOR_TYPE_UNION_PTR:
58 case MOJOM_TYPE_DESCRIPTOR_TYPE_POD:
59 // This is a type that isn't supported in an array.
60 assert(0);
61 break;
62 }
63 return NULL;
64 }
65
66 size_t MojomArray_ComputeSerializedSize(
67 const struct MojomTypeDescriptorArray* in_type_desc,
68 const struct MojomArrayHeader* in_array) {
69 assert(in_array);
70 assert(in_type_desc);
71
72 size_t size = in_array->num_bytes;
73 if (!MojomType_IsPointer(in_type_desc->elem_type) &&
74 in_type_desc->elem_type != MOJOM_TYPE_DESCRIPTOR_TYPE_UNION)
75 return size;
76
77 for (uint32_t i = 0; i < in_array->num_elements; i++) {
78 size += MojomType_DispatchComputeSerializedSize(
79 in_type_desc->elem_type,
80 in_type_desc->elem_descriptor,
81 in_type_desc->nullable,
82 array_index_by_type(in_array, in_type_desc->elem_type, i));
83 }
84
85 return size;
86 }
87
88 void MojomArray_EncodePointersAndHandles(
89 const struct MojomTypeDescriptorArray* in_type_desc,
90 struct MojomArrayHeader* inout_array,
91 uint32_t in_array_size,
92 struct MojomHandleBuffer* inout_handles_buffer) {
93 assert(in_type_desc);
94 assert(inout_array);
95 assert(in_array_size >= sizeof(struct MojomArrayHeader));
96 assert(in_array_size >= inout_array->num_bytes);
97
98 // Nothing to encode for POD types.
99 if (in_type_desc->elem_type == MOJOM_TYPE_DESCRIPTOR_TYPE_POD)
100 return;
101
102 for (size_t i = 0; i < inout_array->num_elements; i++) {
103 char* elem_data =
104 array_index_by_type(inout_array, in_type_desc->elem_type, i);
105 assert(elem_data < (char*)inout_array + in_array_size);
106
107 MojomType_DispatchEncodePointersAndHandles(
108 in_type_desc->elem_type,
109 in_type_desc->elem_descriptor,
110 in_type_desc->nullable,
111 elem_data,
112 in_array_size - (uint32_t)(elem_data - (char*)inout_array),
113 inout_handles_buffer);
114 }
115 }
116
117 void MojomArray_DecodePointersAndHandles(
118 const struct MojomTypeDescriptorArray* in_type_desc,
119 struct MojomArrayHeader* inout_array,
120 uint32_t in_array_size,
121 MojoHandle* inout_handles,
122 uint32_t in_num_handles) {
123 assert(in_type_desc);
124 assert(inout_array);
125 assert(inout_handles != NULL || in_num_handles == 0);
126
127 // Nothing to encode for POD types.
128 if (in_type_desc->elem_type == MOJOM_TYPE_DESCRIPTOR_TYPE_POD)
129 return;
130
131 for (size_t i = 0; i < inout_array->num_elements; i++) {
132 char* elem_data =
133 array_index_by_type(inout_array, in_type_desc->elem_type, i);
134 assert(elem_data < (char*)inout_array + in_array_size);
135
136 MojomType_DispatchDecodePointersAndHandles(
137 in_type_desc->elem_type,
138 in_type_desc->elem_descriptor,
139 in_type_desc->nullable,
140 elem_data,
141 in_array_size - (uint32_t)(elem_data - (char*)inout_array),
142 inout_handles,
143 in_num_handles);
144 }
145 }
146
147 // Rounds up to nearest byte.
148 static uint64_t bits_to_bytes(uint64_t bits) {
149 return (bits + 7) / 8;
150 }
151
152 static MojomValidationResult validate_array_header(
153 const struct MojomTypeDescriptorArray* in_type_desc,
154 const struct MojomArrayHeader* in_array,
155 uint32_t in_buf_size) {
156 if (in_buf_size < sizeof(struct MojomArrayHeader))
157 return MOJOM_VALIDATION_ILLEGAL_MEMORY_RANGE;
158
159 if (in_array->num_bytes < sizeof(struct MojomArrayHeader))
160 return MOJOM_VALIDATION_UNEXPECTED_ARRAY_HEADER;
161
162 if (in_array->num_bytes > in_buf_size)
163 return MOJOM_VALIDATION_ILLEGAL_MEMORY_RANGE;
164
165 if (in_type_desc->num_elements != 0 &&
166 in_array->num_elements != in_type_desc->num_elements)
167 return MOJOM_VALIDATION_UNEXPECTED_ARRAY_HEADER;
168
169 // Array size is less than what we need to fit the elements.
170 if (in_array->num_bytes <
171 sizeof(struct MojomArrayHeader) +
172 bits_to_bytes((uint64_t)in_type_desc->elem_num_bits *
173 (uint64_t)in_array->num_elements)) {
174 return MOJOM_VALIDATION_UNEXPECTED_ARRAY_HEADER;
175 }
176
177 return MOJOM_VALIDATION_ERROR_NONE;
178 }
179
180 MojomValidationResult MojomArray_Validate(
181 const struct MojomTypeDescriptorArray* in_type_desc,
182 const struct MojomArrayHeader* in_array,
183 uint32_t in_array_size,
184 uint32_t in_num_handles,
185 struct MojomValidationContext* inout_context) {
186 assert(in_type_desc);
187 assert(in_array);
188
189 MojomValidationResult result =
190 validate_array_header(in_type_desc, in_array, in_array_size);
191 if (result != MOJOM_VALIDATION_ERROR_NONE)
192 return result;
193
194 // From here on out, all pointers need to point past the end of this struct.
195 inout_context->next_pointer = (char*)in_array + in_array->num_bytes;
196
197 // Nothing to validate for POD types.
198 if (in_type_desc->elem_type == MOJOM_TYPE_DESCRIPTOR_TYPE_POD)
199 return MOJOM_VALIDATION_ERROR_NONE;
200
201 for (size_t i = 0; i < in_array->num_elements; i++) {
202 char* elem_data =
203 array_index_by_type(in_array, in_type_desc->elem_type, i);
204
205 MojomValidationResult result = MojomType_DispatchValidate(
206 in_type_desc->elem_type,
207 in_type_desc->elem_descriptor,
208 in_type_desc->nullable,
209 elem_data,
210 in_array_size - (uint32_t)(elem_data - (char*)in_array),
211 in_num_handles,
212 inout_context);
213 if (result != MOJOM_VALIDATION_ERROR_NONE)
214 return result;
215 }
216
217 return MOJOM_VALIDATION_ERROR_NONE;
218 }
219
220 bool MojomArray_DeepCopy(
221 struct MojomBuffer* buffer,
222 const struct MojomTypeDescriptorArray* in_type_desc,
223 const struct MojomArrayHeader* in_array,
224 struct MojomArrayHeader** out_array) {
225 assert(in_type_desc);
226 assert(in_array);
227 assert(out_array);
228
229 *out_array = MojomBuffer_Allocate(buffer, in_array->num_bytes);
230 if (*out_array == NULL)
231 return false;
232
233 memcpy(*out_array, in_array, in_array->num_bytes);
234
235 // Nothing else to copy for POD types.
236 if (in_type_desc->elem_type == MOJOM_TYPE_DESCRIPTOR_TYPE_POD)
237 return true;
238
239 for (size_t i = 0; i < in_array->num_elements; i++) {
240 void* in_elem_data =
241 array_index_by_type(in_array, in_type_desc->elem_type, i);
242 void* out_elem_data =
243 array_index_by_type(*out_array, in_type_desc->elem_type, i);
244
245 if (!MojomType_DispatchDeepCopy(buffer, in_type_desc->elem_type,
246 in_type_desc->elem_descriptor, in_elem_data,
247 out_elem_data)) {
248 return false;
249 }
250 }
251
252 return true;
253 }
OLDNEW
« no previous file with comments | « mojo/public/c/include/mojo/system/wait_set.h ('k') | mojo/public/c/lib/bindings/buffer.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698