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

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

Powered by Google App Engine
This is Rietveld 408576698