| // Copyright 2017 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef LIB_FIDL_INTERNAL_H_ |
| #define LIB_FIDL_INTERNAL_H_ |
| |
| #include <assert.h> |
| #include <lib/fidl/coding.h> |
| #include <stdbool.h> |
| #include <stdint.h> |
| #include <string.h> |
| #include <zircon/assert.h> |
| #include <zircon/fidl.h> |
| #include <zircon/syscalls/object.h> |
| #include <zircon/types.h> |
| |
| #ifdef __Fuchsia__ |
| #ifdef __cplusplus |
| #include <zircon/syscalls.h> |
| #endif |
| #endif |
| |
| #ifdef __cplusplus |
| #include <type_traits> |
| #endif // __cplusplus |
| |
| #ifdef __cplusplus |
| |
| namespace fidl { |
| namespace internal { |
| |
| // Certain encoding/decoding/validating functions expect their input byte buffers to not contain a |
| // transactional message header. This function trims the first 16 bytes from a buffer that |
| // previously contained space for the header, to prepare it to be used as an input for such |
| // functions. |
| inline zx_status_t fidl_exclude_header_bytes(const void* bytes, uint32_t num_bytes, |
| uint8_t** out_bytes, uint32_t* out_num_bytes, |
| const char** out_error_msg) { |
| if (unlikely(num_bytes < sizeof(fidl_message_header_t))) { |
| if (out_error_msg) { |
| *out_error_msg = "Message too short to contain header"; |
| } |
| return ZX_ERR_INVALID_ARGS; |
| } |
| *out_num_bytes = num_bytes - (uint32_t)(sizeof(fidl_message_header_t)); |
| |
| if (unlikely(bytes == NULL)) { |
| if (out_error_msg) { |
| *out_error_msg = "Cannot decode null bytes"; |
| } |
| return ZX_ERR_INVALID_ARGS; |
| } |
| *out_bytes = (uint8_t*)bytes + sizeof(fidl_message_header_t); |
| return ZX_OK; |
| } |
| |
| } // namespace internal |
| } // namespace fidl |
| |
| #endif |
| |
| __BEGIN_CDECLS |
| |
| zx_status_t FidlHandleCloseMany(const zx_handle_t* handles, size_t num_handles); |
| zx_status_t FidlHandleDispositionCloseMany(const zx_handle_disposition_t* handle_dispositions, |
| size_t num_handles); |
| zx_status_t FidlHandleInfoCloseMany(const zx_handle_info_t* handle_infos, size_t num_handles); |
| |
| // All sizes here are given as uint32_t. Fidl message sizes are bounded to well below UINT32_MAX. |
| // This also applies to arrays and vectors. For arrays, element_count * element_size will always fit |
| // with 32 bits. For vectors, max_count * element_size will always fit within 32 bits. |
| |
| // Pointers to other type tables within a type are always nonnull, with the exception of vectors. |
| // In that case, a null pointer indicates that the element type of the vector has no interesting |
| // information to be decoded (i.e. no pointers or handles). The vector type still needs to be |
| // emitted as it contains the information about the size of its secondary object. Contrast this with |
| // arrays: being inline, ones with no interesting coding information can be elided, just like a |
| // uint32 field in a struct is elided. |
| |
| typedef bool FidlNullability; |
| static const FidlNullability kFidlNullability_Nonnullable = false; |
| static const FidlNullability kFidlNullability_Nullable = true; |
| |
| typedef bool FidlStrictness; |
| static const FidlStrictness kFidlStrictness_Flexible = false; |
| static const FidlStrictness kFidlStrictness_Strict = true; |
| |
| typedef bool FidlIsResource; |
| static const FidlIsResource kFidlIsResource_Resource = true; |
| static const FidlIsResource kFidlIsResource_NotResource = false; |
| |
| // Indicates if a struct is empty. |
| typedef bool FidlEmpty; |
| static const FidlEmpty kFidlEmpty_IsNotEmpty = false; |
| static const FidlEmpty kFidlEmpty_IsEmpty = true; |
| |
| // TODO(https://fxbug.dev/42119024): Remove either this FidlAlign function or the FIDL_ALIGN macro in |
| // zircon/fidl.h. |
| // clang-format off |
| #ifdef __cplusplus |
| constexpr |
| #endif // __cplusplus |
| static inline uint64_t FidlAlign(uint32_t offset) { |
| const uint64_t alignment_mask = FIDL_ALIGNMENT - 1; |
| return (offset + alignment_mask) & ~alignment_mask; |
| } |
| // clang-format on |
| |
| // Determine if the pointer is aligned to |FIDL_ALIGNMENT|. |
| static inline bool FidlIsAligned(const uint8_t* ptr) { |
| uintptr_t uintptr = (uintptr_t)(ptr); |
| const uint64_t alignment_mask = FIDL_ALIGNMENT - 1; |
| return (uintptr & alignment_mask) == 0; |
| } |
| |
| // Add |size| to out-of-line |offset|, maintaining alignment. For example, a pointer to a struct |
| // that is 4 bytes still needs to advance the next out-of-line offset by 8 to maintain |
| // the aligned-to-FIDL_ALIGNMENT property. |
| // Returns false on overflow. Otherwise, resulting offset is stored in |out_offset|. |
| static inline bool FidlAddOutOfLine(uint32_t offset, uint32_t size, uint32_t* out_offset) { |
| const uint32_t kMask = FIDL_ALIGNMENT - 1; |
| uint32_t new_offset = offset; |
| if (add_overflow(new_offset, size, &new_offset) || add_overflow(new_offset, kMask, &new_offset)) { |
| return false; |
| } |
| new_offset &= ~kMask; |
| *out_offset = new_offset; |
| return true; |
| } |
| |
| inline bool FidlIsZeroEnvelope(const fidl_envelope_t* envelope) { |
| static_assert(sizeof(*envelope) == sizeof(uint64_t), ""); |
| uint64_t uval; |
| memcpy(&uval, envelope, sizeof(*envelope)); |
| return uval == 0; |
| } |
| |
| // Checks that the handle meets specified type and rights requirements. If the |
| // handle has execess rights, the rights will be reduced to the required rights. |
| // |
| // The handle pointed to by |handle_ptr| may be overwritten. If it is overwritten, |
| // the original handle will be closed. |
| // |
| // For details on rules used for these checks, see the implementation. |
| zx_status_t FidlEnsureHandleRights(zx_handle_t* handle_ptr, zx_rights_t actual_type, |
| zx_obj_type_t actual_rights, zx_obj_type_t required_object_type, |
| zx_rights_t required_rights, const char** error); |
| |
| // Checks that the handle's actual rights meet specified type and rights requirements. |
| // If the handle has execess rights, the rights will be reduced to the required rights. |
| // |
| // The handle pointed to by |handle_ptr| may be overwritten. If it is overwritten, |
| // the original handle will be closed. |
| // |
| // For details on rules used for these checks, see the implementation. |
| zx_status_t FidlEnsureActualHandleRights(zx_handle_t* handle_ptr, |
| zx_obj_type_t required_object_type, |
| zx_rights_t required_rights, const char** error); |
| |
| // Converts an array of |zx_handle_disposition_t| to an array of |zx_handle_info_t|. |
| // |
| // This behaves similarly to what happens when a handle is written using |
| // zx_channel_write_etc and then read using zx_channel_read_etc. |
| // The handle type and rights are checked and the output handle may have reduced |
| // rights if the input has excess rights. |
| // |
| // This takes ownership of the input handles. |
| zx_status_t FidlHandleDispositionsToHandleInfos(zx_handle_disposition_t* handle_dispositions, |
| zx_handle_info_t* handle_infos, |
| uint32_t num_handles); |
| |
| typedef uint8_t FidlStructElementType; |
| static const FidlStructElementType kFidlStructElementType_Field = (uint8_t)1u; |
| static const FidlStructElementType kFidlStructElementType_Padding64 = (uint8_t)2u; |
| static const FidlStructElementType kFidlStructElementType_Padding32 = (uint8_t)3u; |
| static const FidlStructElementType kFidlStructElementType_Padding16 = (uint8_t)4u; |
| |
| struct FidlStructElementHeader { |
| FidlStructElementType element_type; |
| FidlIsResource is_resource; |
| }; |
| |
| struct FidlStructField { |
| struct FidlStructElementHeader header; |
| |
| uint32_t offset_v2; |
| |
| const fidl_type_t* field_type; |
| }; |
| |
| struct FidlStructPadding { |
| struct FidlStructElementHeader header; |
| |
| uint32_t offset_v2; |
| |
| // Masks with 0xff on bytes with padding and 0x00 otherwise. |
| // They are used by VisitInternalPadding to zero (encoding) and validate (decoding) |
| // padding bytes. |
| union { |
| uint16_t mask_16; |
| uint32_t mask_32; |
| uint64_t mask_64; |
| }; |
| }; |
| |
| // A struct element is either a field or padding. |
| struct FidlStructElement { |
| union { |
| struct FidlStructElementHeader header; |
| struct FidlStructField field; |
| struct FidlStructPadding padding; |
| }; |
| |
| #ifdef __cplusplus |
| static constexpr FidlStructElement Field(const fidl_type* type, uint32_t offset_v2, |
| FidlIsResource is_resource) { |
| return FidlStructElement{ |
| .field = |
| FidlStructField{ |
| .header = |
| FidlStructElementHeader{ |
| .element_type = kFidlStructElementType_Field, |
| .is_resource = is_resource, |
| }, |
| .offset_v2 = offset_v2, |
| .field_type = type, |
| }, |
| }; |
| } |
| static constexpr FidlStructElement Padding64(uint32_t offset_v2, uint64_t mask) { |
| return FidlStructElement{ |
| .padding = |
| FidlStructPadding{ |
| .header = |
| FidlStructElementHeader{ |
| .element_type = kFidlStructElementType_Padding64, |
| .is_resource = kFidlIsResource_NotResource, |
| }, |
| .offset_v2 = offset_v2, |
| .mask_64 = mask, |
| }, |
| }; |
| } |
| static constexpr FidlStructElement Padding32(uint32_t offset_v2, uint32_t mask) { |
| return FidlStructElement{ |
| .padding = |
| FidlStructPadding{ |
| .header = |
| FidlStructElementHeader{ |
| .element_type = kFidlStructElementType_Padding32, |
| .is_resource = kFidlIsResource_NotResource, |
| }, |
| .offset_v2 = offset_v2, |
| .mask_32 = mask, |
| }, |
| }; |
| } |
| static constexpr FidlStructElement Padding16(uint32_t offset_v2, uint16_t mask) { |
| return FidlStructElement{ |
| .padding = |
| FidlStructPadding{ |
| .header = |
| FidlStructElementHeader{ |
| .element_type = kFidlStructElementType_Padding16, |
| .is_resource = kFidlIsResource_NotResource, |
| }, |
| .offset_v2 = offset_v2, |
| .mask_16 = mask, |
| }, |
| }; |
| } |
| #endif // __cplusplus |
| }; |
| |
| struct FidlTableField { |
| const fidl_type_t* type; |
| uint32_t ordinal; |
| }; |
| |
| struct FidlUnionField { |
| const fidl_type_t* type; |
| }; |
| |
| // TODO(https://fxbug.dev/42119025): Consider starting enum values for FidlTypeTag from 1, not 0. |
| typedef uint8_t FidlTypeTag; |
| static const uint8_t kFidlTypePrimitive = 0; |
| static const uint8_t kFidlTypeEnum = 1; |
| static const uint8_t kFidlTypeBits = 2; |
| static const uint8_t kFidlTypeStruct = 3; |
| static const uint8_t kFidlTypeStructPointer = 4; |
| static const uint8_t kFidlTypeArray = 5; |
| static const uint8_t kFidlTypeString = 6; |
| static const uint8_t kFidlTypeHandle = 7; |
| static const uint8_t kFidlTypeVector = 8; |
| static const uint8_t kFidlTypeTable = 9; |
| static const uint8_t kFidlTypeXUnion = 10; |
| static const uint8_t kFidlTypeUnion = 10; |
| |
| // TODO(https://fxbug.dev/42119025): Consider starting enum values for FidlCodedPrimitive from 1, not 0. |
| typedef uint8_t FidlCodedPrimitiveSubtype; |
| static const uint8_t kFidlCodedPrimitiveSubtype_Bool = 0; |
| static const uint8_t kFidlCodedPrimitiveSubtype_Int8 = 1; |
| static const uint8_t kFidlCodedPrimitiveSubtype_Int16 = 2; |
| static const uint8_t kFidlCodedPrimitiveSubtype_Int32 = 3; |
| static const uint8_t kFidlCodedPrimitiveSubtype_Int64 = 4; |
| static const uint8_t kFidlCodedPrimitiveSubtype_Uint8 = 5; |
| static const uint8_t kFidlCodedPrimitiveSubtype_Uint16 = 6; |
| static const uint8_t kFidlCodedPrimitiveSubtype_Uint32 = 7; |
| static const uint8_t kFidlCodedPrimitiveSubtype_Uint64 = 8; |
| static const uint8_t kFidlCodedPrimitiveSubtype_Float32 = 9; |
| static const uint8_t kFidlCodedPrimitiveSubtype_Float64 = 10; |
| |
| typedef bool (*EnumValidationPredicate)(uint64_t); |
| |
| // Coding Table Definitions |
| // |
| // FIDL coding tables describe the layout and constraints of the messages. |
| // Each coding table must start with a `tag`, to identify the kind of the |
| // coding table at runtime. For improved convenience working with these types, |
| // we provide an empty C++ type `fidl_type_t`, which is inherited by the |
| // coding tables in C++ mode, and dispatches to one of the subclasses based |
| // on the tag. |
| // |
| // Coding tables are generated in C files to avoid delayed-initialization |
| // issues, but are meant to be consumed by C++ files such as the walker. |
| // Hence parts of below are ifdef'ed with C++-specific blocks. |
| |
| struct FidlCodedPrimitive; |
| struct FidlCodedEnum; |
| struct FidlCodedBits; |
| struct FidlCodedStruct; |
| struct FidlCodedStructPointer; |
| struct FidlCodedTable; |
| struct FidlCodedUnion; |
| struct FidlCodedArray; |
| struct FidlCodedHandle; |
| struct FidlCodedString; |
| struct FidlCodedVector; |
| |
| #ifdef __cplusplus |
| |
| // Empty struct containing helper functions for casting to derived |
| // coding table types. C++ empty base class optimization ensure that this |
| // struct shares the same starting address with any of its subclasses. |
| struct fidl_type { |
| constexpr FidlTypeTag type_tag() const; |
| constexpr const FidlCodedPrimitive& coded_primitive() const; |
| constexpr const FidlCodedEnum& coded_enum() const; |
| constexpr const FidlCodedBits& coded_bits() const; |
| constexpr const FidlCodedStruct& coded_struct() const; |
| constexpr const FidlCodedStructPointer& coded_struct_pointer() const; |
| constexpr const FidlCodedTable& coded_table() const; |
| constexpr const FidlCodedUnion& coded_union() const; |
| constexpr const FidlCodedArray& coded_array() const; |
| constexpr const FidlCodedHandle& coded_handle() const; |
| constexpr const FidlCodedString& coded_string() const; |
| constexpr const FidlCodedVector& coded_vector() const; |
| |
| // This prevents designated initializers from working in C++20 |
| #if __cplusplus <= 201703L |
| private: |
| // Prevent instances of this class from being accidentally used standalone |
| // as a value. |
| constexpr fidl_type() = default; |
| #endif |
| }; |
| |
| #define FIDL_INTERNAL_INHERIT_TYPE_T \ |
| final: \ |
| fidl_type |
| |
| #else // __cplusplus |
| |
| // No inheritance in C mode. This is okay because inheriting |
| // from an empty class does not affect the object layout at all. |
| #define FIDL_INTERNAL_INHERIT_TYPE_T |
| |
| #endif // __cplusplus |
| |
| struct FidlCodedPrimitive FIDL_INTERNAL_INHERIT_TYPE_T { |
| const FidlTypeTag tag; |
| const FidlCodedPrimitiveSubtype type; |
| }; |
| |
| struct FidlCodedEnum FIDL_INTERNAL_INHERIT_TYPE_T { |
| const FidlTypeTag tag; |
| const FidlCodedPrimitiveSubtype underlying_type; |
| const FidlStrictness strictness; |
| // The validate predicate is only used for strict enums, and is NULL for |
| // flexible enums. |
| const EnumValidationPredicate validate; |
| const char* name; // may be nullptr if omitted at compile time |
| }; |
| |
| struct FidlCodedBits FIDL_INTERNAL_INHERIT_TYPE_T { |
| const FidlTypeTag tag; |
| const FidlCodedPrimitiveSubtype underlying_type; |
| const FidlStrictness strictness; |
| const uint64_t mask; |
| const char* name; // may be nullptr if omitted at compile time |
| }; |
| |
| // Though the |size| is implied by the fields, computing that information is not |
| // the purview of this library. It's easier for the compiler to stash it. |
| struct FidlCodedStruct FIDL_INTERNAL_INHERIT_TYPE_T { |
| const FidlTypeTag tag; |
| const FidlEmpty is_empty; |
| // element_count should be a uint32_t, but for the sake of binary size |
| // a uint16_t is used (all existing values fit within this size). |
| // If a larger size is needed, replace FidlCodedStruct or add a second |
| // variant that supports the larger size. |
| const uint16_t element_count; |
| const uint32_t size_v2; |
| const struct FidlStructElement* const elements; |
| const char* name; // may be nullptr if omitted at compile time |
| }; |
| |
| struct FidlCodedStructPointer FIDL_INTERNAL_INHERIT_TYPE_T { |
| const FidlTypeTag tag; |
| const struct FidlCodedStruct* const struct_type; |
| }; |
| |
| struct FidlCodedTable FIDL_INTERNAL_INHERIT_TYPE_T { |
| const FidlTypeTag tag; |
| const FidlIsResource is_resource; |
| const uint32_t field_count; |
| const struct FidlTableField* const fields; |
| const char* name; // may be nullptr if omitted at compile time |
| }; |
| |
| struct FidlCodedUnion FIDL_INTERNAL_INHERIT_TYPE_T { |
| const FidlTypeTag tag; |
| const FidlNullability nullable; |
| const FidlStrictness strictness; |
| const FidlIsResource is_resource; |
| const uint32_t field_count; |
| // The fields are in ordinal order, with ordinal 1 at index 0. |
| const struct FidlUnionField* const fields; |
| const char* name; // may be nullptr if omitted at compile time |
| }; |
| |
| // An array is essentially a struct with |array_size / element_size| of the same field, named at |
| // |element|. |
| struct FidlCodedArray FIDL_INTERNAL_INHERIT_TYPE_T { |
| const FidlTypeTag tag; |
| // element_size should be a uint32_t, but for the sake of binary size |
| // a uint16_t is used (all existing values fit within this size). |
| // If a larger size is needed, replace FidlCodedArray or add a second |
| // variant that supports the larger size. |
| const uint16_t element_size_v2; |
| const uint32_t array_size_v2; |
| const fidl_type_t* const element; |
| }; |
| |
| struct FidlCodedHandle FIDL_INTERNAL_INHERIT_TYPE_T { |
| const FidlTypeTag tag; |
| const FidlNullability nullable; |
| const zx_obj_type_t handle_subtype; |
| const zx_rights_t handle_rights; |
| |
| static_assert(ZX_OBJ_TYPE_UPPER_BOUND <= UINT32_MAX, ""); |
| }; |
| |
| struct FidlCodedString FIDL_INTERNAL_INHERIT_TYPE_T { |
| const FidlTypeTag tag; |
| const FidlNullability nullable; |
| const uint32_t max_size; |
| }; |
| |
| // Note that: |
| // - |max_count * element_size| is guaranteed to fit into a uint32_t. |
| // - |element| will always be non-null. |
| struct FidlCodedVector FIDL_INTERNAL_INHERIT_TYPE_T { |
| const FidlTypeTag tag; |
| const FidlNullability nullable; |
| const uint32_t max_count; |
| const uint32_t element_size_v2; |
| const fidl_type_t* const element; |
| }; |
| |
| #ifdef __cplusplus |
| |
| struct FidlHasTypeTag final : fidl_type { |
| const FidlTypeTag tag; |
| |
| FidlHasTypeTag() = delete; |
| }; |
| |
| __ALWAYS_INLINE constexpr FidlTypeTag fidl_type::type_tag() const { |
| return static_cast<const FidlHasTypeTag*>(this)->tag; |
| } |
| |
| __ALWAYS_INLINE constexpr const FidlCodedPrimitive& fidl_type::coded_primitive() const { |
| return *static_cast<const FidlCodedPrimitive*>(this); |
| } |
| |
| __ALWAYS_INLINE constexpr const FidlCodedEnum& fidl_type::coded_enum() const { |
| return *static_cast<const FidlCodedEnum*>(this); |
| } |
| |
| __ALWAYS_INLINE constexpr const FidlCodedBits& fidl_type::coded_bits() const { |
| return *static_cast<const FidlCodedBits*>(this); |
| } |
| |
| __ALWAYS_INLINE constexpr const FidlCodedStruct& fidl_type::coded_struct() const { |
| return *static_cast<const FidlCodedStruct*>(this); |
| } |
| |
| __ALWAYS_INLINE constexpr const FidlCodedStructPointer& fidl_type::coded_struct_pointer() const { |
| return *static_cast<const FidlCodedStructPointer*>(this); |
| } |
| |
| __ALWAYS_INLINE constexpr const FidlCodedTable& fidl_type::coded_table() const { |
| return *static_cast<const FidlCodedTable*>(this); |
| } |
| |
| __ALWAYS_INLINE constexpr const FidlCodedUnion& fidl_type::coded_union() const { |
| return *static_cast<const FidlCodedUnion*>(this); |
| } |
| |
| __ALWAYS_INLINE constexpr const FidlCodedArray& fidl_type::coded_array() const { |
| return *static_cast<const FidlCodedArray*>(this); |
| } |
| |
| __ALWAYS_INLINE constexpr const FidlCodedHandle& fidl_type::coded_handle() const { |
| return *static_cast<const FidlCodedHandle*>(this); |
| } |
| |
| __ALWAYS_INLINE constexpr const FidlCodedString& fidl_type::coded_string() const { |
| return *static_cast<const FidlCodedString*>(this); |
| } |
| |
| __ALWAYS_INLINE constexpr const FidlCodedVector& fidl_type::coded_vector() const { |
| return *static_cast<const FidlCodedVector*>(this); |
| } |
| |
| #endif // __cplusplus |
| |
| extern const struct FidlCodedPrimitive fidl_internal_kBoolTable; |
| extern const struct FidlCodedPrimitive fidl_internal_kInt8Table; |
| extern const struct FidlCodedPrimitive fidl_internal_kInt16Table; |
| extern const struct FidlCodedPrimitive fidl_internal_kInt32Table; |
| extern const struct FidlCodedPrimitive fidl_internal_kInt64Table; |
| extern const struct FidlCodedPrimitive fidl_internal_kUint8Table; |
| extern const struct FidlCodedPrimitive fidl_internal_kUint16Table; |
| extern const struct FidlCodedPrimitive fidl_internal_kUint32Table; |
| extern const struct FidlCodedPrimitive fidl_internal_kUint64Table; |
| extern const struct FidlCodedPrimitive fidl_internal_kFloat32Table; |
| extern const struct FidlCodedPrimitive fidl_internal_kFloat64Table; |
| |
| extern const struct FidlCodedEnum fidl_internal_kFrameworkErrTable; |
| |
| // Backwards-compatible names |
| typedef struct FidlCodedUnion FidlCodedXUnion; |
| typedef struct FidlUnionField FidlXUnionField; |
| |
| __END_CDECLS |
| |
| #ifdef __cplusplus |
| // All the data in coding tables should be pure data. |
| static_assert(std::is_standard_layout<FidlTypeTag>::value, ""); |
| static_assert(std::is_standard_layout<FidlStructField>::value, ""); |
| static_assert(std::is_standard_layout<FidlTableField>::value, ""); |
| static_assert(std::is_standard_layout<FidlCodedStruct>::value, ""); |
| static_assert(std::is_standard_layout<FidlCodedStructPointer>::value, ""); |
| static_assert(std::is_standard_layout<FidlCodedUnion>::value, ""); |
| static_assert(std::is_standard_layout<FidlCodedArray>::value, ""); |
| static_assert(std::is_standard_layout<FidlCodedVector>::value, ""); |
| static_assert(std::is_standard_layout<FidlCodedString>::value, ""); |
| static_assert(std::is_standard_layout<FidlCodedHandle>::value, ""); |
| static_assert(std::is_standard_layout<FidlStructElement>::value, ""); |
| #endif // __cplusplus |
| |
| static_assert(offsetof(struct FidlCodedStruct, tag) == 0, ""); |
| static_assert(offsetof(struct FidlCodedStructPointer, tag) == 0, ""); |
| static_assert(offsetof(struct FidlCodedUnion, tag) == 0, ""); |
| static_assert(offsetof(struct FidlCodedArray, tag) == 0, ""); |
| static_assert(offsetof(struct FidlCodedVector, tag) == 0, ""); |
| static_assert(offsetof(struct FidlCodedString, tag) == 0, ""); |
| static_assert(offsetof(struct FidlCodedHandle, tag) == 0, ""); |
| |
| // Take caution when increasing the size numbers below. While they |
| // can be changed as needed when the structure evolves, these growing |
| // has a large impact on binary size and memory footprint. |
| |
| static_assert(sizeof(struct FidlCodedPrimitive) == 2, ""); |
| static_assert(sizeof(struct FidlCodedEnum) == 24, ""); |
| static_assert(sizeof(struct FidlCodedBits) == 24, ""); |
| static_assert(sizeof(struct FidlCodedStruct) == 24, ""); |
| static_assert(sizeof(struct FidlCodedStructPointer) == 16, ""); |
| static_assert(sizeof(struct FidlCodedUnion) == 24, ""); |
| static_assert(sizeof(struct FidlCodedArray) == 16, ""); |
| static_assert(sizeof(struct FidlCodedVector) == 24, ""); |
| static_assert(sizeof(struct FidlCodedString) == 8, ""); |
| static_assert(sizeof(struct FidlCodedHandle) == 12, ""); |
| |
| static_assert(sizeof(struct FidlStructField) == 16, ""); |
| static_assert(sizeof(struct FidlTableField) == 16, ""); |
| static_assert(sizeof(struct FidlUnionField) == 8, ""); |
| |
| static_assert(sizeof(struct FidlStructElement) == 16, ""); |
| |
| #endif // LIB_FIDL_INTERNAL_H_ |