111
|
1 /* { dg-do compile } */
|
|
2
|
|
3 typedef unsigned _GCC_ATTR_ALIGN_u32t;
|
|
4 typedef _GCC_ATTR_ALIGN_u32t _Uint32t __attribute__ ((__aligned__ (4)));
|
|
5 typedef unsigned int _GCC_ATTR_ALIGN_u8t __attribute__ ((__mode__ (__QI__)));
|
|
6 typedef _GCC_ATTR_ALIGN_u8t _Uint8t __attribute__ ((__aligned__ (1)));
|
|
7 typedef unsigned _Sizet;
|
|
8 typedef _Sizet size_t;
|
|
9 typedef _Uint8t uint8_t;
|
|
10 typedef _Uint32t uint32_t;
|
|
11 typedef enum
|
|
12 {
|
|
13 PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_LABEL_OPTIONAL,
|
|
14 PROTOBUF_C_LABEL_REPEATED
|
|
15 }
|
|
16 ProtobufCLabel;
|
|
17 typedef enum
|
|
18 {
|
|
19 PROTOBUF_C_TYPE_INT32, PROTOBUF_C_TYPE_SINT32, PROTOBUF_C_TYPE_SFIXED32,
|
|
20 PROTOBUF_C_TYPE_INT64, PROTOBUF_C_TYPE_SINT64, PROTOBUF_C_TYPE_SFIXED64,
|
|
21 PROTOBUF_C_TYPE_UINT32, PROTOBUF_C_TYPE_FIXED32, PROTOBUF_C_TYPE_UINT64,
|
|
22 PROTOBUF_C_TYPE_FIXED64, PROTOBUF_C_TYPE_FLOAT, PROTOBUF_C_TYPE_DOUBLE,
|
|
23 PROTOBUF_C_TYPE_BOOL, PROTOBUF_C_TYPE_ENUM, PROTOBUF_C_TYPE_STRING,
|
|
24 PROTOBUF_C_TYPE_BYTES, PROTOBUF_C_TYPE_MESSAGE,
|
|
25 }
|
|
26 ProtobufCType;
|
|
27 typedef struct _ProtobufCBinaryData ProtobufCBinaryData;
|
|
28 struct _ProtobufCBinaryData
|
|
29 {
|
|
30 size_t len;
|
|
31 };
|
|
32 typedef struct _ProtobufCMessageDescriptor ProtobufCMessageDescriptor;
|
|
33 typedef struct _ProtobufCFieldDescriptor ProtobufCFieldDescriptor;
|
|
34 typedef struct _ProtobufCMessage ProtobufCMessage;
|
|
35 struct _ProtobufCFieldDescriptor
|
|
36 {
|
|
37 uint32_t id;
|
|
38 ProtobufCLabel label;
|
|
39 ProtobufCType type;
|
|
40 unsigned offset;
|
|
41 };
|
|
42 struct _ProtobufCMessageDescriptor
|
|
43 {
|
|
44 unsigned n_fields;
|
|
45 const ProtobufCFieldDescriptor *fields;
|
|
46 };
|
|
47 struct _ProtobufCMessage
|
|
48 {
|
|
49 const ProtobufCMessageDescriptor *descriptor;
|
|
50 };
|
|
51 typedef enum
|
|
52 {
|
|
53 PROTOBUF_C_WIRE_TYPE_VARINT, PROTOBUF_C_WIRE_TYPE_64BIT,
|
|
54 PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED, PROTOBUF_C_WIRE_TYPE_START_GROUP,
|
|
55 PROTOBUF_C_WIRE_TYPE_END_GROUP, PROTOBUF_C_WIRE_TYPE_32BIT
|
|
56 }
|
|
57 ProtobufCWireType;
|
|
58 size_t tag_pack (uint32_t, uint8_t *);
|
|
59 size_t prefixed_message_pack (ProtobufCMessage *, uint8_t *);
|
|
60 static inline size_t
|
|
61 uint32_pack (uint32_t value, uint8_t * out)
|
|
62 {
|
|
63 unsigned rv = 0;
|
|
64 if (value >= 0x80)
|
|
65 {
|
|
66 if (value >= 0x80)
|
|
67 {
|
|
68 value >>= 7;
|
|
69 }
|
|
70 }
|
|
71 out[rv++] = value;
|
|
72 }
|
|
73
|
|
74 static inline size_t
|
|
75 binary_data_pack (const ProtobufCBinaryData * bd, uint8_t * out)
|
|
76 {
|
|
77 size_t len = bd->len;
|
|
78 size_t rv = uint32_pack (len, out);
|
|
79 return rv + len;
|
|
80 }
|
|
81
|
|
82 static size_t
|
|
83 required_field_pack (const ProtobufCFieldDescriptor * field,
|
|
84 const void *member, uint8_t * out)
|
|
85 {
|
|
86 size_t rv = tag_pack (field->id, out);
|
|
87 switch (field->type)
|
|
88 {
|
|
89 case PROTOBUF_C_TYPE_BYTES:
|
|
90 {
|
|
91 const ProtobufCBinaryData *bd =
|
|
92 ((const ProtobufCBinaryData *) member);
|
|
93 out[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED;
|
|
94 return rv + binary_data_pack (bd, out + rv);
|
|
95 }
|
|
96 case PROTOBUF_C_TYPE_MESSAGE:
|
|
97 {
|
|
98 out[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED;
|
|
99 return rv +
|
|
100 prefixed_message_pack (*(ProtobufCMessage * const *) member,
|
|
101 out + rv);
|
|
102 }
|
|
103 }
|
|
104 }
|
|
105
|
|
106 size_t
|
|
107 protobuf_c_message_pack (const ProtobufCMessage * message, uint8_t * out)
|
|
108 {
|
|
109 unsigned i;
|
|
110 size_t rv = 0;
|
|
111 for (i = 0; i < message->descriptor->n_fields; i++)
|
|
112 {
|
|
113 const ProtobufCFieldDescriptor *field = message->descriptor->fields + i;
|
|
114 const void *member = ((const char *) message) + field->offset;
|
|
115 if (field->label == PROTOBUF_C_LABEL_REQUIRED)
|
|
116 rv += required_field_pack (field, member, out + rv);
|
|
117 }
|
|
118 }
|