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