OLD | NEW |
| (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/union.h" | |
6 | |
7 #include <assert.h> | |
8 #include <string.h> | |
9 | |
10 #include "mojo/public/c/bindings/lib/type_descriptor.h" | |
11 | |
12 #define UNION_TAG_UNKNOWN ((uint32_t)0xFFFFFFFF) | |
13 | |
14 size_t MojomUnion_ComputeSerializedSize( | |
15 const struct MojomTypeDescriptorUnion* in_type_desc, | |
16 const struct MojomUnionLayout* in_union_data) { | |
17 assert(in_type_desc); | |
18 assert(in_union_data); | |
19 | |
20 for (size_t i = 0; i < in_type_desc->num_entries; i++) { | |
21 const struct MojomTypeDescriptorUnionEntry* entry = | |
22 &(in_type_desc->entries[i]); | |
23 if (in_union_data->tag != entry->tag) | |
24 continue; | |
25 | |
26 // We should skip non-pointer types. | |
27 if (!MojomType_IsPointer(entry->elem_type)) | |
28 break; | |
29 | |
30 return MojomType_DispatchComputeSerializedSize( | |
31 entry->elem_type, entry->elem_descriptor, entry->nullable, | |
32 &(in_union_data->data.pointer.ptr)); | |
33 } | |
34 return 0; | |
35 } | |
36 | |
37 void MojomUnion_EncodePointersAndHandles( | |
38 const struct MojomTypeDescriptorUnion* in_type_desc, | |
39 struct MojomUnionLayout* inout_union, | |
40 uint32_t in_buf_size, | |
41 struct MojomHandleBuffer* inout_handles_buffer) { | |
42 assert(in_buf_size >= sizeof(struct MojomUnionLayout)); | |
43 | |
44 for (size_t i = 0; i < in_type_desc->num_entries; i++) { | |
45 const struct MojomTypeDescriptorUnionEntry* entry = | |
46 &(in_type_desc->entries[i]); | |
47 | |
48 if (inout_union->tag != entry->tag) | |
49 continue; | |
50 | |
51 if (entry->elem_type == MOJOM_TYPE_DESCRIPTOR_TYPE_POD) | |
52 break; | |
53 | |
54 MojomType_DispatchEncodePointersAndHandles( | |
55 entry->elem_type, | |
56 entry->elem_descriptor, | |
57 entry->nullable, | |
58 &inout_union->data, | |
59 in_buf_size - ((char*)&inout_union->data - (char*)inout_union), | |
60 inout_handles_buffer); | |
61 | |
62 break; | |
63 } | |
64 } | |
65 | |
66 void MojomUnion_DecodePointersAndHandles( | |
67 const struct MojomTypeDescriptorUnion* in_type_desc, | |
68 struct MojomUnionLayout* inout_union, | |
69 uint32_t in_union_size, | |
70 MojoHandle* inout_handles, | |
71 uint32_t in_num_handles) { | |
72 assert(in_union_size >= sizeof(struct MojomUnionLayout)); | |
73 assert(inout_handles != NULL || in_num_handles == 0); | |
74 | |
75 for (size_t i = 0; i < in_type_desc->num_entries; i++) { | |
76 const struct MojomTypeDescriptorUnionEntry* entry = | |
77 &(in_type_desc->entries[i]); | |
78 | |
79 if (inout_union->tag != entry->tag) | |
80 continue; | |
81 | |
82 if (entry->elem_type == MOJOM_TYPE_DESCRIPTOR_TYPE_POD) | |
83 break; | |
84 | |
85 MojomType_DispatchDecodePointersAndHandles( | |
86 entry->elem_type, | |
87 entry->elem_descriptor, | |
88 entry->nullable, | |
89 &inout_union->data, | |
90 in_union_size - ((char*)&inout_union->data - (char*)inout_union), | |
91 inout_handles, | |
92 in_num_handles); | |
93 | |
94 break; | |
95 } | |
96 } | |
97 | |
98 MojomValidationResult MojomUnion_Validate( | |
99 const struct MojomTypeDescriptorUnion* in_type_desc, | |
100 bool in_nullable, | |
101 const struct MojomUnionLayout* in_union, | |
102 uint32_t in_union_size, | |
103 uint32_t in_num_handles, | |
104 struct MojomValidationContext* inout_context) { | |
105 for (size_t i = 0; i < in_type_desc->num_entries; i++) { | |
106 const struct MojomTypeDescriptorUnionEntry* entry = | |
107 &(in_type_desc->entries[i]); | |
108 | |
109 if (in_union->tag != entry->tag) | |
110 continue; | |
111 | |
112 if (entry->elem_type == MOJOM_TYPE_DESCRIPTOR_TYPE_POD) | |
113 break; | |
114 | |
115 if (!in_nullable && in_union->size != sizeof(struct MojomUnionLayout)) | |
116 return MOJOM_VALIDATION_UNEXPECTED_NULL_UNION; | |
117 | |
118 return MojomType_DispatchValidate( | |
119 entry->elem_type, | |
120 entry->elem_descriptor, | |
121 entry->nullable, | |
122 &(in_union->data), | |
123 in_union_size - ((char*)&(in_union->data) - (char*)in_union), | |
124 in_num_handles, | |
125 inout_context); | |
126 } | |
127 return MOJOM_VALIDATION_ERROR_NONE; | |
128 } | |
129 | |
130 bool MojomUnion_DeepCopy(struct MojomBuffer* buffer, | |
131 const struct MojomTypeDescriptorUnion* in_type_desc, | |
132 const struct MojomUnionLayout* in_union_data, | |
133 struct MojomUnionLayout* out_union_data) { | |
134 memcpy(out_union_data, in_union_data, sizeof(struct MojomUnionLayout)); | |
135 | |
136 // Unions with size 0 are null. | |
137 if (in_union_data->size == 0) | |
138 return true; | |
139 | |
140 for (size_t i = 0; i < in_type_desc->num_entries; i++) { | |
141 const struct MojomTypeDescriptorUnionEntry* entry = | |
142 &(in_type_desc->entries[i]); | |
143 if (in_union_data->tag != entry->tag) | |
144 continue; | |
145 | |
146 // We should skip non-pointer types. | |
147 if (entry->elem_type == MOJOM_TYPE_DESCRIPTOR_TYPE_POD) | |
148 return true; | |
149 | |
150 return MojomType_DispatchDeepCopy( | |
151 buffer, entry->elem_type, entry->elem_descriptor, | |
152 &(in_union_data->data), &(out_union_data->data)); | |
153 } | |
154 // We reach here if we don't recognize the tag. If it's the UNKNOWN tag, it's | |
155 // not a failure. If it's an unrecognized tag (erroneous or because this union | |
156 // is from a future-version), we don't know how to copy it, so the copy is a | |
157 // failure. | |
158 return in_union_data->tag < in_type_desc->num_fields || | |
159 in_union_data->tag == UNION_TAG_UNKNOWN; | |
160 } | |
OLD | NEW |