| /* { dg-do compile } */ |
| |
| typedef unsigned _GCC_ATTR_ALIGN_u32t; |
| typedef _GCC_ATTR_ALIGN_u32t _Uint32t __attribute__ ((__aligned__ (4))); |
| typedef unsigned int _GCC_ATTR_ALIGN_u8t __attribute__ ((__mode__ (__QI__))); |
| typedef _GCC_ATTR_ALIGN_u8t _Uint8t __attribute__ ((__aligned__ (1))); |
| typedef unsigned _Sizet; |
| typedef _Sizet size_t; |
| typedef _Uint8t uint8_t; |
| typedef _Uint32t uint32_t; |
| typedef enum |
| { |
| PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_LABEL_OPTIONAL, |
| PROTOBUF_C_LABEL_REPEATED |
| } |
| ProtobufCLabel; |
| typedef enum |
| { |
| PROTOBUF_C_TYPE_INT32, PROTOBUF_C_TYPE_SINT32, PROTOBUF_C_TYPE_SFIXED32, |
| PROTOBUF_C_TYPE_INT64, PROTOBUF_C_TYPE_SINT64, PROTOBUF_C_TYPE_SFIXED64, |
| PROTOBUF_C_TYPE_UINT32, PROTOBUF_C_TYPE_FIXED32, PROTOBUF_C_TYPE_UINT64, |
| PROTOBUF_C_TYPE_FIXED64, PROTOBUF_C_TYPE_FLOAT, PROTOBUF_C_TYPE_DOUBLE, |
| PROTOBUF_C_TYPE_BOOL, PROTOBUF_C_TYPE_ENUM, PROTOBUF_C_TYPE_STRING, |
| PROTOBUF_C_TYPE_BYTES, PROTOBUF_C_TYPE_MESSAGE, |
| } |
| ProtobufCType; |
| typedef struct _ProtobufCBinaryData ProtobufCBinaryData; |
| struct _ProtobufCBinaryData |
| { |
| size_t len; |
| }; |
| typedef struct _ProtobufCMessageDescriptor ProtobufCMessageDescriptor; |
| typedef struct _ProtobufCFieldDescriptor ProtobufCFieldDescriptor; |
| typedef struct _ProtobufCMessage ProtobufCMessage; |
| struct _ProtobufCFieldDescriptor |
| { |
| uint32_t id; |
| ProtobufCLabel label; |
| ProtobufCType type; |
| unsigned offset; |
| }; |
| struct _ProtobufCMessageDescriptor |
| { |
| unsigned n_fields; |
| const ProtobufCFieldDescriptor *fields; |
| }; |
| struct _ProtobufCMessage |
| { |
| const ProtobufCMessageDescriptor *descriptor; |
| }; |
| typedef enum |
| { |
| PROTOBUF_C_WIRE_TYPE_VARINT, PROTOBUF_C_WIRE_TYPE_64BIT, |
| PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED, PROTOBUF_C_WIRE_TYPE_START_GROUP, |
| PROTOBUF_C_WIRE_TYPE_END_GROUP, PROTOBUF_C_WIRE_TYPE_32BIT |
| } |
| ProtobufCWireType; |
| size_t tag_pack (uint32_t, uint8_t *); |
| size_t prefixed_message_pack (ProtobufCMessage *, uint8_t *); |
| static inline size_t |
| uint32_pack (uint32_t value, uint8_t * out) |
| { |
| unsigned rv = 0; |
| if (value >= 0x80) |
| { |
| if (value >= 0x80) |
| { |
| value >>= 7; |
| } |
| } |
| out[rv++] = value; |
| } |
| |
| static inline size_t |
| binary_data_pack (const ProtobufCBinaryData * bd, uint8_t * out) |
| { |
| size_t len = bd->len; |
| size_t rv = uint32_pack (len, out); |
| return rv + len; |
| } |
| |
| static size_t |
| required_field_pack (const ProtobufCFieldDescriptor * field, |
| const void *member, uint8_t * out) |
| { |
| size_t rv = tag_pack (field->id, out); |
| switch (field->type) |
| { |
| case PROTOBUF_C_TYPE_BYTES: |
| { |
| const ProtobufCBinaryData *bd = |
| ((const ProtobufCBinaryData *) member); |
| out[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED; |
| return rv + binary_data_pack (bd, out + rv); |
| } |
| case PROTOBUF_C_TYPE_MESSAGE: |
| { |
| out[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED; |
| return rv + |
| prefixed_message_pack (*(ProtobufCMessage * const *) member, |
| out + rv); |
| } |
| } |
| } |
| |
| size_t |
| protobuf_c_message_pack (const ProtobufCMessage * message, uint8_t * out) |
| { |
| unsigned i; |
| size_t rv = 0; |
| for (i = 0; i < message->descriptor->n_fields; i++) |
| { |
| const ProtobufCFieldDescriptor *field = message->descriptor->fields + i; |
| const void *member = ((const char *) message) + field->offset; |
| if (field->label == PROTOBUF_C_LABEL_REQUIRED) |
| rv += required_field_pack (field, member, out + rv); |
| } |
| } |