| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "mojo/public/c/bindings/union.h" | 5 #include "mojo/public/c/bindings/union.h" |
| 6 | 6 |
| 7 #include <assert.h> | 7 #include <assert.h> |
| 8 #include <string.h> |
| 8 | 9 |
| 9 #include "mojo/public/c/bindings/lib/type_descriptor.h" | 10 #include "mojo/public/c/bindings/lib/type_descriptor.h" |
| 10 | 11 |
| 12 #define UNION_TAG_UNKNOWN ((uint32_t)0xFFFFFFFF) |
| 13 |
| 11 size_t MojomUnion_ComputeSerializedSize( | 14 size_t MojomUnion_ComputeSerializedSize( |
| 12 const struct MojomTypeDescriptorUnion* in_type_desc, | 15 const struct MojomTypeDescriptorUnion* in_type_desc, |
| 13 const struct MojomUnionLayout* in_union_data) { | 16 const struct MojomUnionLayout* in_union_data) { |
| 14 assert(in_type_desc); | 17 assert(in_type_desc); |
| 15 assert(in_union_data); | 18 assert(in_union_data); |
| 16 | 19 |
| 17 for (size_t i = 0; i < in_type_desc->num_entries; i++) { | 20 for (size_t i = 0; i < in_type_desc->num_entries; i++) { |
| 18 const struct MojomTypeDescriptorUnionEntry* entry = | 21 const struct MojomTypeDescriptorUnionEntry* entry = |
| 19 &(in_type_desc->entries[i]); | 22 &(in_type_desc->entries[i]); |
| 20 if (in_union_data->tag != entry->tag) | 23 if (in_union_data->tag != entry->tag) |
| 21 continue; | 24 continue; |
| 22 | 25 |
| 23 // We should skip non-pointer types. | 26 // We should skip non-pointer types. |
| 24 if (!MojomType_IsPointer(entry->elem_type)) | 27 if (!MojomType_IsPointer(entry->elem_type)) |
| 25 continue; | 28 break; |
| 26 | 29 |
| 27 return MojomType_DispatchComputeSerializedSize( | 30 return MojomType_DispatchComputeSerializedSize( |
| 28 entry->elem_type, entry->elem_descriptor, entry->nullable, | 31 entry->elem_type, entry->elem_descriptor, entry->nullable, |
| 29 &(in_union_data->data.pointer.ptr)); | 32 &(in_union_data->data.pointer.ptr)); |
| 30 } | 33 } |
| 31 return 0; | 34 return 0; |
| 32 } | 35 } |
| 33 | 36 |
| 34 void MojomUnion_EncodePointersAndHandles( | 37 void MojomUnion_EncodePointersAndHandles( |
| 35 const struct MojomTypeDescriptorUnion* in_type_desc, | 38 const struct MojomTypeDescriptorUnion* in_type_desc, |
| 36 struct MojomUnionLayout* inout_union, | 39 struct MojomUnionLayout* inout_union, |
| 37 uint32_t in_buf_size, | 40 uint32_t in_buf_size, |
| 38 struct MojomHandleBuffer* inout_handles_buffer) { | 41 struct MojomHandleBuffer* inout_handles_buffer) { |
| 39 assert(in_buf_size >= sizeof(struct MojomUnionLayout)); | 42 assert(in_buf_size >= sizeof(struct MojomUnionLayout)); |
| 40 | 43 |
| 41 for (size_t i = 0; i < in_type_desc->num_entries; i++) { | 44 for (size_t i = 0; i < in_type_desc->num_entries; i++) { |
| 42 const struct MojomTypeDescriptorUnionEntry* entry = | 45 const struct MojomTypeDescriptorUnionEntry* entry = |
| 43 &(in_type_desc->entries[i]); | 46 &(in_type_desc->entries[i]); |
| 44 | 47 |
| 45 if (inout_union->tag != entry->tag) | 48 if (inout_union->tag != entry->tag) |
| 46 continue; | 49 continue; |
| 47 | 50 |
| 48 if (entry->elem_type == MOJOM_TYPE_DESCRIPTOR_TYPE_POD) | 51 if (entry->elem_type == MOJOM_TYPE_DESCRIPTOR_TYPE_POD) |
| 49 continue; | 52 break; |
| 50 | 53 |
| 51 MojomType_DispatchEncodePointersAndHandles( | 54 MojomType_DispatchEncodePointersAndHandles( |
| 52 entry->elem_type, | 55 entry->elem_type, |
| 53 entry->elem_descriptor, | 56 entry->elem_descriptor, |
| 54 entry->nullable, | 57 entry->nullable, |
| 55 &inout_union->data, | 58 &inout_union->data, |
| 56 in_buf_size - ((char*)&inout_union->data - (char*)inout_union), | 59 in_buf_size - ((char*)&inout_union->data - (char*)inout_union), |
| 57 inout_handles_buffer); | 60 inout_handles_buffer); |
| 61 |
| 62 break; |
| 58 } | 63 } |
| 59 } | 64 } |
| 60 | 65 |
| 61 void MojomUnion_DecodePointersAndHandles( | 66 void MojomUnion_DecodePointersAndHandles( |
| 62 const struct MojomTypeDescriptorUnion* in_type_desc, | 67 const struct MojomTypeDescriptorUnion* in_type_desc, |
| 63 struct MojomUnionLayout* inout_union, | 68 struct MojomUnionLayout* inout_union, |
| 64 uint32_t in_union_size, | 69 uint32_t in_union_size, |
| 65 MojoHandle* inout_handles, | 70 MojoHandle* inout_handles, |
| 66 uint32_t in_num_handles) { | 71 uint32_t in_num_handles) { |
| 67 assert(in_union_size >= sizeof(struct MojomUnionLayout)); | 72 assert(in_union_size >= sizeof(struct MojomUnionLayout)); |
| 68 assert(inout_handles != NULL || in_num_handles == 0); | 73 assert(inout_handles != NULL || in_num_handles == 0); |
| 69 | 74 |
| 70 for (size_t i = 0; i < in_type_desc->num_entries; i++) { | 75 for (size_t i = 0; i < in_type_desc->num_entries; i++) { |
| 71 const struct MojomTypeDescriptorUnionEntry* entry = | 76 const struct MojomTypeDescriptorUnionEntry* entry = |
| 72 &(in_type_desc->entries[i]); | 77 &(in_type_desc->entries[i]); |
| 73 | 78 |
| 74 if (inout_union->tag != entry->tag) | 79 if (inout_union->tag != entry->tag) |
| 75 continue; | 80 continue; |
| 76 | 81 |
| 77 if (entry->elem_type == MOJOM_TYPE_DESCRIPTOR_TYPE_POD) | 82 if (entry->elem_type == MOJOM_TYPE_DESCRIPTOR_TYPE_POD) |
| 78 continue; | 83 break; |
| 79 | 84 |
| 80 MojomType_DispatchDecodePointersAndHandles( | 85 MojomType_DispatchDecodePointersAndHandles( |
| 81 entry->elem_type, | 86 entry->elem_type, |
| 82 entry->elem_descriptor, | 87 entry->elem_descriptor, |
| 83 entry->nullable, | 88 entry->nullable, |
| 84 &inout_union->data, | 89 &inout_union->data, |
| 85 in_union_size - ((char*)&inout_union->data - (char*)inout_union), | 90 in_union_size - ((char*)&inout_union->data - (char*)inout_union), |
| 86 inout_handles, | 91 inout_handles, |
| 87 in_num_handles); | 92 in_num_handles); |
| 93 |
| 94 break; |
| 88 } | 95 } |
| 89 } | 96 } |
| 90 | 97 |
| 91 MojomValidationResult MojomUnion_Validate( | 98 MojomValidationResult MojomUnion_Validate( |
| 92 const struct MojomTypeDescriptorUnion* in_type_desc, | 99 const struct MojomTypeDescriptorUnion* in_type_desc, |
| 93 bool in_nullable, | 100 bool in_nullable, |
| 94 const struct MojomUnionLayout* in_union, | 101 const struct MojomUnionLayout* in_union, |
| 95 uint32_t in_union_size, | 102 uint32_t in_union_size, |
| 96 uint32_t in_num_handles, | 103 uint32_t in_num_handles, |
| 97 struct MojomValidationContext* inout_context) { | 104 struct MojomValidationContext* inout_context) { |
| 98 for (size_t i = 0; i < in_type_desc->num_entries; i++) { | 105 for (size_t i = 0; i < in_type_desc->num_entries; i++) { |
| 99 const struct MojomTypeDescriptorUnionEntry* entry = | 106 const struct MojomTypeDescriptorUnionEntry* entry = |
| 100 &(in_type_desc->entries[i]); | 107 &(in_type_desc->entries[i]); |
| 101 | 108 |
| 102 if (in_union->tag != entry->tag) | 109 if (in_union->tag != entry->tag) |
| 103 continue; | 110 continue; |
| 104 | 111 |
| 105 if (entry->elem_type == MOJOM_TYPE_DESCRIPTOR_TYPE_POD) | 112 if (entry->elem_type == MOJOM_TYPE_DESCRIPTOR_TYPE_POD) |
| 106 continue; | 113 break; |
| 107 | 114 |
| 108 if (!in_nullable && in_union->size != sizeof(struct MojomUnionLayout)) | 115 if (!in_nullable && in_union->size != sizeof(struct MojomUnionLayout)) |
| 109 return MOJOM_VALIDATION_UNEXPECTED_NULL_UNION; | 116 return MOJOM_VALIDATION_UNEXPECTED_NULL_UNION; |
| 110 | 117 |
| 111 MojomValidationResult result = MojomType_DispatchValidate( | 118 return MojomType_DispatchValidate( |
| 112 entry->elem_type, | 119 entry->elem_type, |
| 113 entry->elem_descriptor, | 120 entry->elem_descriptor, |
| 114 entry->nullable, | 121 entry->nullable, |
| 115 &(in_union->data), | 122 &(in_union->data), |
| 116 in_union_size - ((char*)&(in_union->data) - (char*)in_union), | 123 in_union_size - ((char*)&(in_union->data) - (char*)in_union), |
| 117 in_num_handles, | 124 in_num_handles, |
| 118 inout_context); | 125 inout_context); |
| 119 if (result != MOJOM_VALIDATION_ERROR_NONE) | |
| 120 return result; | |
| 121 } | 126 } |
| 122 return MOJOM_VALIDATION_ERROR_NONE; | 127 return MOJOM_VALIDATION_ERROR_NONE; |
| 123 } | 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 |