| 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/lib/type_descriptor.h" | |
| 6 | |
| 7 #include <assert.h> | |
| 8 #include <stddef.h> | |
| 9 | |
| 10 #include "mojo/public/c/bindings/array.h" | |
| 11 #include "mojo/public/c/bindings/interface.h" | |
| 12 #include "mojo/public/c/bindings/lib/util.h" | |
| 13 #include "mojo/public/c/bindings/map.h" | |
| 14 #include "mojo/public/c/bindings/struct.h" | |
| 15 #include "mojo/public/c/bindings/union.h" | |
| 16 | |
| 17 const struct MojomTypeDescriptorArray g_mojom_string_type_description = { | |
| 18 .elem_type = MOJOM_TYPE_DESCRIPTOR_TYPE_POD, | |
| 19 .elem_descriptor = NULL, | |
| 20 .num_elements = 0, | |
| 21 .elem_num_bits = 8, | |
| 22 .nullable = false, | |
| 23 }; | |
| 24 | |
| 25 // The encoding of a MojoHandle is an index into an array of Handles. A | |
| 26 // null/invalid handle is encoded as index (which is unsigned) "-1", which | |
| 27 // equates to the highest possible index. | |
| 28 static const MojoHandle kEncodedHandleInvalid = (MojoHandle)-1; | |
| 29 | |
| 30 bool MojomType_IsPointer(enum MojomTypeDescriptorType type) { | |
| 31 return type == MOJOM_TYPE_DESCRIPTOR_TYPE_STRUCT_PTR || | |
| 32 type == MOJOM_TYPE_DESCRIPTOR_TYPE_MAP_PTR || | |
| 33 type == MOJOM_TYPE_DESCRIPTOR_TYPE_ARRAY_PTR || | |
| 34 type == MOJOM_TYPE_DESCRIPTOR_TYPE_UNION_PTR; | |
| 35 } | |
| 36 | |
| 37 size_t MojomType_DispatchComputeSerializedSize( | |
| 38 enum MojomTypeDescriptorType type, | |
| 39 const void* type_desc, | |
| 40 bool nullable, | |
| 41 const void* data) { | |
| 42 const void* data_ptr = data; | |
| 43 size_t size = 0; | |
| 44 switch (type) { | |
| 45 case MOJOM_TYPE_DESCRIPTOR_TYPE_MAP_PTR: | |
| 46 case MOJOM_TYPE_DESCRIPTOR_TYPE_STRUCT_PTR: { | |
| 47 data_ptr = ((const union MojomPointer*)data_ptr)->ptr; | |
| 48 if (!nullable || data_ptr != NULL) | |
| 49 return MojomStruct_ComputeSerializedSize( | |
| 50 (const struct MojomTypeDescriptorStruct*)type_desc, | |
| 51 (const struct MojomStructHeader*)data_ptr); | |
| 52 break; | |
| 53 } | |
| 54 case MOJOM_TYPE_DESCRIPTOR_TYPE_ARRAY_PTR: | |
| 55 data_ptr = ((const union MojomPointer*)data_ptr)->ptr; | |
| 56 if (!nullable || data_ptr != NULL) | |
| 57 return MojomArray_ComputeSerializedSize(type_desc, data_ptr); | |
| 58 break; | |
| 59 case MOJOM_TYPE_DESCRIPTOR_TYPE_UNION_PTR: | |
| 60 data_ptr = ((const union MojomPointer*)data_ptr)->ptr; | |
| 61 if (data_ptr != NULL) | |
| 62 size = sizeof(struct MojomUnionLayout); | |
| 63 // Fall through. | |
| 64 case MOJOM_TYPE_DESCRIPTOR_TYPE_UNION: { | |
| 65 const struct MojomUnionLayout* udata = data_ptr; | |
| 66 // Unions inside unions may be set to null by setting their pointer to | |
| 67 // NULL, OR by setting the union's |size| to 0. | |
| 68 if (!nullable || (udata && udata->size != 0)) { | |
| 69 return size + MojomUnion_ComputeSerializedSize( | |
| 70 (const struct MojomTypeDescriptorUnion*)type_desc, | |
| 71 (const struct MojomUnionLayout*)data); | |
| 72 } | |
| 73 break; | |
| 74 } | |
| 75 case MOJOM_TYPE_DESCRIPTOR_TYPE_HANDLE: | |
| 76 case MOJOM_TYPE_DESCRIPTOR_TYPE_INTERFACE: | |
| 77 case MOJOM_TYPE_DESCRIPTOR_TYPE_POD: | |
| 78 // We should never end up here. | |
| 79 assert(false); | |
| 80 break; | |
| 81 } | |
| 82 return size; | |
| 83 } | |
| 84 | |
| 85 static void encode_pointer(union MojomPointer* pointer, uint32_t max_offset) { | |
| 86 if (pointer->ptr == NULL) { | |
| 87 pointer->offset = 0; | |
| 88 } else { | |
| 89 assert((char*)pointer->ptr > (char*)pointer); | |
| 90 assert((size_t)((char*)pointer->ptr - (char*)pointer) < max_offset); | |
| 91 pointer->offset = (char*)(pointer->ptr) - (char*)pointer; | |
| 92 } | |
| 93 } | |
| 94 | |
| 95 static void decode_pointer(union MojomPointer* pointer) { | |
| 96 if (pointer->offset == 0) { | |
| 97 pointer->ptr = NULL; | |
| 98 } else { | |
| 99 pointer->ptr = (char*)pointer + pointer->offset; | |
| 100 } | |
| 101 } | |
| 102 | |
| 103 static void encode_handle(bool nullable, MojoHandle* handle, | |
| 104 struct MojomHandleBuffer* handles_buffer) { | |
| 105 assert(handle); | |
| 106 assert(handles_buffer); | |
| 107 assert(handles_buffer->handles); | |
| 108 | |
| 109 if (*handle == MOJO_HANDLE_INVALID) { | |
| 110 assert(nullable); | |
| 111 *handle = kEncodedHandleInvalid; | |
| 112 } else { | |
| 113 assert(handles_buffer->num_handles_used < handles_buffer->num_handles); | |
| 114 | |
| 115 handles_buffer->handles[handles_buffer->num_handles_used] = *handle; | |
| 116 *handle = handles_buffer->num_handles_used; | |
| 117 handles_buffer->num_handles_used++; | |
| 118 } | |
| 119 } | |
| 120 | |
| 121 // *handle is an index into inout_handles, or is encoded NULL. | |
| 122 static void decode_handle(MojoHandle* handle, | |
| 123 MojoHandle inout_handles[], uint32_t in_num_handles) { | |
| 124 assert(handle); | |
| 125 assert(inout_handles); | |
| 126 | |
| 127 if (*handle == kEncodedHandleInvalid) { | |
| 128 *handle = MOJO_HANDLE_INVALID; | |
| 129 } else { | |
| 130 assert(*handle < in_num_handles); | |
| 131 MojoHandle index = *handle; | |
| 132 *handle = inout_handles[index]; | |
| 133 inout_handles[index] = MOJO_HANDLE_INVALID; | |
| 134 } | |
| 135 } | |
| 136 | |
| 137 void MojomType_DispatchEncodePointersAndHandles( | |
| 138 enum MojomTypeDescriptorType in_elem_type, | |
| 139 const void* in_type_desc, | |
| 140 bool in_nullable, | |
| 141 void* inout_buf, | |
| 142 uint32_t in_buf_size, | |
| 143 struct MojomHandleBuffer* inout_handles_buffer) { | |
| 144 assert(inout_buf); | |
| 145 | |
| 146 void* union_buf = inout_buf; | |
| 147 switch (in_elem_type) { | |
| 148 case MOJOM_TYPE_DESCRIPTOR_TYPE_MAP_PTR: | |
| 149 case MOJOM_TYPE_DESCRIPTOR_TYPE_STRUCT_PTR: { | |
| 150 struct MojomStructHeader* inout_struct = | |
| 151 ((union MojomPointer*)inout_buf)->ptr; | |
| 152 encode_pointer(inout_buf, in_buf_size); | |
| 153 if (!in_nullable || inout_struct != NULL) | |
| 154 MojomStruct_EncodePointersAndHandles( | |
| 155 (const struct MojomTypeDescriptorStruct*)in_type_desc, | |
| 156 inout_struct, | |
| 157 in_buf_size - ((char*)inout_struct - (char*)inout_buf), | |
| 158 inout_handles_buffer); | |
| 159 break; | |
| 160 } | |
| 161 case MOJOM_TYPE_DESCRIPTOR_TYPE_ARRAY_PTR: { | |
| 162 struct MojomArrayHeader* inout_array = | |
| 163 ((union MojomPointer*)inout_buf)->ptr; | |
| 164 encode_pointer(inout_buf, in_buf_size); | |
| 165 if (!in_nullable || inout_array != NULL) | |
| 166 MojomArray_EncodePointersAndHandles( | |
| 167 (const struct MojomTypeDescriptorArray*)in_type_desc, | |
| 168 inout_array, | |
| 169 in_buf_size - ((char*)inout_array - (char*)inout_buf), | |
| 170 inout_handles_buffer); | |
| 171 break; | |
| 172 } | |
| 173 case MOJOM_TYPE_DESCRIPTOR_TYPE_UNION_PTR: | |
| 174 union_buf = ((union MojomPointer*)inout_buf)->ptr; | |
| 175 encode_pointer(inout_buf, in_buf_size); | |
| 176 // Fall through | |
| 177 case MOJOM_TYPE_DESCRIPTOR_TYPE_UNION: { | |
| 178 struct MojomUnionLayout* u_data = union_buf; | |
| 179 if (!in_nullable || (u_data != NULL && u_data->size != 0)) | |
| 180 MojomUnion_EncodePointersAndHandles( | |
| 181 (const struct MojomTypeDescriptorUnion*)in_type_desc, | |
| 182 inout_buf, | |
| 183 in_buf_size, | |
| 184 inout_handles_buffer); | |
| 185 break; | |
| 186 } | |
| 187 case MOJOM_TYPE_DESCRIPTOR_TYPE_HANDLE: | |
| 188 encode_handle(in_nullable, (MojoHandle*)inout_buf, inout_handles_buffer); | |
| 189 break; | |
| 190 case MOJOM_TYPE_DESCRIPTOR_TYPE_INTERFACE: { | |
| 191 struct MojomInterfaceData* interface = inout_buf; | |
| 192 encode_handle(in_nullable, &interface->handle, inout_handles_buffer); | |
| 193 break; | |
| 194 } | |
| 195 case MOJOM_TYPE_DESCRIPTOR_TYPE_POD: | |
| 196 // We shouldn't ever end up here. | |
| 197 assert(false); | |
| 198 break; | |
| 199 } | |
| 200 } | |
| 201 | |
| 202 void MojomType_DispatchDecodePointersAndHandles( | |
| 203 enum MojomTypeDescriptorType in_elem_type, | |
| 204 const void* in_type_desc, | |
| 205 bool in_nullable, | |
| 206 void* inout_buf, | |
| 207 uint32_t in_buf_size, | |
| 208 MojoHandle* inout_handles, | |
| 209 uint32_t in_num_handles) { | |
| 210 assert(inout_buf); | |
| 211 | |
| 212 void* union_buf = inout_buf; | |
| 213 switch (in_elem_type) { | |
| 214 case MOJOM_TYPE_DESCRIPTOR_TYPE_MAP_PTR: | |
| 215 case MOJOM_TYPE_DESCRIPTOR_TYPE_STRUCT_PTR: { | |
| 216 decode_pointer(inout_buf); | |
| 217 struct MojomStructHeader* inout_struct = | |
| 218 ((union MojomPointer*)inout_buf)->ptr; | |
| 219 assert(inout_struct == NULL || | |
| 220 (char*)inout_struct < ((char*)inout_buf) + in_buf_size); | |
| 221 if (!in_nullable || inout_struct != NULL) | |
| 222 MojomStruct_DecodePointersAndHandles( | |
| 223 (const struct MojomTypeDescriptorStruct*)in_type_desc, | |
| 224 inout_struct, | |
| 225 in_buf_size - ((char*)inout_struct - (char*)inout_buf), | |
| 226 inout_handles, | |
| 227 in_num_handles); | |
| 228 break; | |
| 229 } | |
| 230 case MOJOM_TYPE_DESCRIPTOR_TYPE_ARRAY_PTR: { | |
| 231 decode_pointer(inout_buf); | |
| 232 struct MojomArrayHeader* inout_array = | |
| 233 ((union MojomPointer*)inout_buf)->ptr; | |
| 234 assert(inout_array == NULL || | |
| 235 (char*)inout_array < ((char*)inout_buf) + in_buf_size); | |
| 236 if (!in_nullable || inout_array != NULL) | |
| 237 MojomArray_DecodePointersAndHandles( | |
| 238 (const struct MojomTypeDescriptorArray*)in_type_desc, | |
| 239 inout_array, | |
| 240 in_buf_size - ((char*)inout_array - (char*)inout_buf), | |
| 241 inout_handles, | |
| 242 in_num_handles); | |
| 243 break; | |
| 244 } | |
| 245 case MOJOM_TYPE_DESCRIPTOR_TYPE_UNION_PTR: | |
| 246 decode_pointer(inout_buf); | |
| 247 union_buf = ((union MojomPointer*)inout_buf)->ptr; | |
| 248 assert(union_buf == NULL || | |
| 249 (char*)union_buf < ((char*)inout_buf) + in_buf_size); | |
| 250 // Fall through | |
| 251 case MOJOM_TYPE_DESCRIPTOR_TYPE_UNION: { | |
| 252 struct MojomUnionLayout* u_data = union_buf; | |
| 253 if (!in_nullable || (u_data != NULL && u_data->size != 0)) | |
| 254 MojomUnion_DecodePointersAndHandles( | |
| 255 (const struct MojomTypeDescriptorUnion*)in_type_desc, | |
| 256 inout_buf, | |
| 257 in_buf_size, | |
| 258 inout_handles, | |
| 259 in_num_handles); | |
| 260 break; | |
| 261 } | |
| 262 case MOJOM_TYPE_DESCRIPTOR_TYPE_HANDLE: | |
| 263 decode_handle((MojoHandle*)inout_buf, inout_handles, | |
| 264 in_num_handles); | |
| 265 break; | |
| 266 case MOJOM_TYPE_DESCRIPTOR_TYPE_INTERFACE: { | |
| 267 struct MojomInterfaceData* interface = inout_buf; | |
| 268 decode_handle(&interface->handle, inout_handles, | |
| 269 in_num_handles); | |
| 270 break; | |
| 271 } | |
| 272 case MOJOM_TYPE_DESCRIPTOR_TYPE_POD: | |
| 273 // We shouldn't ever end up here. | |
| 274 assert(false); | |
| 275 break; | |
| 276 } | |
| 277 } | |
| 278 | |
| 279 // Validates that the offset (|pointer->offset|) points to a new memory region, | |
| 280 // i.e. one that hasn't been referenced yet. If so, moves the expected offset | |
| 281 // (for the next pointer) forward. | |
| 282 static MojomValidationResult validate_pointer( | |
| 283 const union MojomPointer* pointer, | |
| 284 size_t max_offset, | |
| 285 bool is_nullable, | |
| 286 struct MojomValidationContext* inout_context) { | |
| 287 // Offset must be <= UINT32_MAX and within range. | |
| 288 if (pointer->offset > max_offset || pointer->offset > UINT32_MAX) | |
| 289 return MOJOM_VALIDATION_ILLEGAL_POINTER; | |
| 290 | |
| 291 if (pointer->offset != 0) { | |
| 292 if ((char*)pointer + pointer->offset < inout_context->next_pointer) | |
| 293 return MOJOM_VALIDATION_ILLEGAL_MEMORY_RANGE; | |
| 294 | |
| 295 inout_context->next_pointer = (char*)pointer + pointer->offset; | |
| 296 } | |
| 297 | |
| 298 // Offset must be 8-byte aligned: this check is sufficient, given that all | |
| 299 // objects are rounded to 8-bytes. | |
| 300 if ((pointer->offset & 7) != 0) | |
| 301 return MOJOM_VALIDATION_MISALIGNED_OBJECT; | |
| 302 | |
| 303 if (!is_nullable && pointer->offset == 0) | |
| 304 return MOJOM_VALIDATION_UNEXPECTED_NULL_POINTER; | |
| 305 | |
| 306 return MOJOM_VALIDATION_ERROR_NONE; | |
| 307 } | |
| 308 | |
| 309 static MojomValidationResult validate_handle( | |
| 310 MojoHandle encoded_handle, uint32_t num_handles, bool is_nullable, | |
| 311 struct MojomValidationContext* inout_context) { | |
| 312 if (!is_nullable && encoded_handle == kEncodedHandleInvalid) | |
| 313 return MOJOM_VALIDATION_UNEXPECTED_INVALID_HANDLE; | |
| 314 | |
| 315 if (encoded_handle != kEncodedHandleInvalid) { | |
| 316 if (encoded_handle >= num_handles || | |
| 317 encoded_handle < inout_context->next_handle_index) | |
| 318 return MOJOM_VALIDATION_ILLEGAL_HANDLE; | |
| 319 | |
| 320 inout_context->next_handle_index = encoded_handle + 1; | |
| 321 } | |
| 322 | |
| 323 return MOJOM_VALIDATION_ERROR_NONE; | |
| 324 } | |
| 325 | |
| 326 MojomValidationResult MojomType_DispatchValidate( | |
| 327 enum MojomTypeDescriptorType in_elem_type, const void* in_type_desc, | |
| 328 bool in_nullable, const void* in_buf, uint32_t in_buf_size, | |
| 329 uint32_t in_num_handles, struct MojomValidationContext* inout_context) { | |
| 330 assert(in_buf); | |
| 331 | |
| 332 struct MojomUnionLayout* union_data = (struct MojomUnionLayout*)in_buf; | |
| 333 switch (in_elem_type) { | |
| 334 case MOJOM_TYPE_DESCRIPTOR_TYPE_MAP_PTR: | |
| 335 case MOJOM_TYPE_DESCRIPTOR_TYPE_STRUCT_PTR: { | |
| 336 union MojomPointer* pointer = (union MojomPointer*)in_buf; | |
| 337 MojomValidationResult result = | |
| 338 validate_pointer(pointer, in_buf_size, in_nullable, inout_context); | |
| 339 if (result != MOJOM_VALIDATION_ERROR_NONE || pointer->offset == 0) | |
| 340 return result; | |
| 341 | |
| 342 result = MojomStruct_Validate( | |
| 343 (const struct MojomTypeDescriptorStruct*)in_type_desc, | |
| 344 (const struct MojomStructHeader*)((char*)in_buf + pointer->offset), | |
| 345 in_buf_size - pointer->offset, in_num_handles, inout_context); | |
| 346 | |
| 347 if (result == MOJOM_VALIDATION_ERROR_NONE && | |
| 348 in_elem_type == MOJOM_TYPE_DESCRIPTOR_TYPE_MAP_PTR) { | |
| 349 return MojomMap_Validate( | |
| 350 (const struct MojomTypeDescriptorStruct*)in_type_desc, | |
| 351 (const struct MojomStructHeader*)((char*)in_buf + pointer->offset), | |
| 352 in_buf_size - pointer->offset, in_num_handles, inout_context); | |
| 353 } | |
| 354 | |
| 355 return result; | |
| 356 } | |
| 357 case MOJOM_TYPE_DESCRIPTOR_TYPE_ARRAY_PTR: { | |
| 358 union MojomPointer* pointer = (union MojomPointer*)in_buf; | |
| 359 MojomValidationResult result = | |
| 360 validate_pointer(pointer, in_buf_size, in_nullable, inout_context); | |
| 361 if (result != MOJOM_VALIDATION_ERROR_NONE || pointer->offset == 0) | |
| 362 return result; | |
| 363 | |
| 364 return MojomArray_Validate( | |
| 365 (const struct MojomTypeDescriptorArray*)in_type_desc, | |
| 366 (const struct MojomArrayHeader*)((char*)in_buf + pointer->offset), | |
| 367 in_buf_size - pointer->offset, in_num_handles, inout_context); | |
| 368 } | |
| 369 case MOJOM_TYPE_DESCRIPTOR_TYPE_UNION_PTR: { | |
| 370 union MojomPointer* pointer = (union MojomPointer*)in_buf; | |
| 371 MojomValidationResult result = | |
| 372 validate_pointer(pointer, in_buf_size, in_nullable, inout_context); | |
| 373 if (result != MOJOM_VALIDATION_ERROR_NONE || pointer->offset == 0) | |
| 374 return result; | |
| 375 | |
| 376 // Since this union is a pointer, we update |next_pointer| to be past the | |
| 377 // union data. | |
| 378 inout_context->next_pointer += sizeof(struct MojomUnionLayout); | |
| 379 | |
| 380 union_data = (struct MojomUnionLayout*)((char*)in_buf + pointer->offset); | |
| 381 // Fall through. | |
| 382 } | |
| 383 case MOJOM_TYPE_DESCRIPTOR_TYPE_UNION: | |
| 384 if (union_data->size == 0) { | |
| 385 return in_nullable ? MOJOM_VALIDATION_ERROR_NONE | |
| 386 : MOJOM_VALIDATION_UNEXPECTED_NULL_UNION; | |
| 387 } | |
| 388 | |
| 389 return MojomUnion_Validate( | |
| 390 (const struct MojomTypeDescriptorUnion*)in_type_desc, in_nullable, | |
| 391 union_data, in_buf_size - ((char*)union_data - (char*)in_buf), | |
| 392 in_num_handles, inout_context); | |
| 393 case MOJOM_TYPE_DESCRIPTOR_TYPE_HANDLE: | |
| 394 return validate_handle(*(const MojoHandle*)in_buf, in_num_handles, | |
| 395 in_nullable, inout_context); | |
| 396 case MOJOM_TYPE_DESCRIPTOR_TYPE_INTERFACE: | |
| 397 return validate_handle(((const struct MojomInterfaceData*)in_buf)->handle, | |
| 398 in_num_handles, in_nullable, inout_context); | |
| 399 case MOJOM_TYPE_DESCRIPTOR_TYPE_POD: | |
| 400 break; | |
| 401 } | |
| 402 return MOJOM_VALIDATION_ERROR_NONE; | |
| 403 } | |
| 404 | |
| 405 bool MojomType_DispatchDeepCopy(struct MojomBuffer* buffer, | |
| 406 enum MojomTypeDescriptorType in_elem_type, | |
| 407 const void* in_type_desc, | |
| 408 const void* in_data, | |
| 409 void* out_data) { | |
| 410 assert(in_data); | |
| 411 | |
| 412 const struct MojomUnionLayout* in_union_data = | |
| 413 (const struct MojomUnionLayout*)in_data; | |
| 414 struct MojomUnionLayout* out_union_data = (struct MojomUnionLayout*)out_data; | |
| 415 const union MojomPointer* in_pointer = in_data; | |
| 416 switch (in_elem_type) { | |
| 417 case MOJOM_TYPE_DESCRIPTOR_TYPE_MAP_PTR: | |
| 418 case MOJOM_TYPE_DESCRIPTOR_TYPE_STRUCT_PTR: | |
| 419 if (in_pointer->ptr == NULL) { | |
| 420 ((union MojomPointer*)out_data)->ptr = NULL; | |
| 421 break; | |
| 422 } | |
| 423 return MojomStruct_DeepCopy( | |
| 424 buffer, (const struct MojomTypeDescriptorStruct*)in_type_desc, | |
| 425 ((union MojomPointer*)in_data)->ptr, | |
| 426 out_data); | |
| 427 case MOJOM_TYPE_DESCRIPTOR_TYPE_ARRAY_PTR: | |
| 428 if (in_pointer->ptr == NULL) { | |
| 429 ((union MojomPointer*)out_data)->ptr = NULL; | |
| 430 break; | |
| 431 } | |
| 432 return MojomArray_DeepCopy( | |
| 433 buffer, (const struct MojomTypeDescriptorArray*)in_type_desc, | |
| 434 ((union MojomPointer*)in_data)->ptr, | |
| 435 out_data); | |
| 436 case MOJOM_TYPE_DESCRIPTOR_TYPE_UNION_PTR: | |
| 437 in_union_data = ((const union MojomPointer*)in_data)->ptr; | |
| 438 if (in_union_data == NULL) { | |
| 439 ((union MojomPointer*)out_data)->ptr = NULL; | |
| 440 break; | |
| 441 } | |
| 442 out_union_data = | |
| 443 MojomBuffer_Allocate(buffer, sizeof(struct MojomUnionLayout)); | |
| 444 if (out_union_data == NULL) | |
| 445 return false; | |
| 446 ((union MojomPointer*)out_data)->ptr = out_union_data; | |
| 447 // Fall through. | |
| 448 case MOJOM_TYPE_DESCRIPTOR_TYPE_UNION: | |
| 449 return MojomUnion_DeepCopy(buffer, | |
| 450 (const struct MojomTypeDescriptorUnion*)in_type_desc, | |
| 451 in_union_data, | |
| 452 out_union_data); | |
| 453 case MOJOM_TYPE_DESCRIPTOR_TYPE_HANDLE: | |
| 454 case MOJOM_TYPE_DESCRIPTOR_TYPE_INTERFACE: | |
| 455 case MOJOM_TYPE_DESCRIPTOR_TYPE_POD: | |
| 456 break; | |
| 457 } | |
| 458 | |
| 459 return true; | |
| 460 } | |
| OLD | NEW |