15void pc_pb_writer_init(PbWriter *w, uint8_t *buf,
size_t cap)
23bool pc_pb_write_varint(PbWriter *w, uint64_t v)
33 uint8_t b = (uint8_t)(v & 0x7F);
41 if (w->pos + n > w->cap)
46 memcpy(w->buf + w->pos, tmp, n);
51bool pc_pb_write_tag(PbWriter *w, uint32_t field, uint8_t wire_type)
53 return pc_pb_write_varint(w, ((uint64_t)field << 3) | (wire_type & 0x07));
57static bool pc_pb_write_le(PbWriter *w, uint64_t v,
size_t n)
68 if (w->pos + n > w->cap)
73 for (
size_t i = 0; i < n; i++)
75 w->buf[w->pos++] = (uint8_t)(v >> (8 * i));
80bool pc_pb_uint64(PbWriter *w, uint32_t field, uint64_t v)
82 return pc_pb_write_tag(w, field, PB_WT_VARINT) && pc_pb_write_varint(w, v);
85bool pc_pb_int64(PbWriter *w, uint32_t field, int64_t v)
87 return pc_pb_uint64(w, field, (uint64_t)v);
90bool pc_pb_sint64(PbWriter *w, uint32_t field, int64_t v)
92 uint64_t zz = ((uint64_t)v << 1) ^ (uint64_t)(v >> 63);
93 return pc_pb_uint64(w, field, zz);
96bool pc_pb_bool(PbWriter *w, uint32_t field,
bool v)
98 return pc_pb_uint64(w, field, v ? 1 : 0);
101bool pc_pb_fixed32(PbWriter *w, uint32_t field, uint32_t v)
103 return pc_pb_write_tag(w, field, PB_WT_I32) && pc_pb_write_le(w, v, 4);
106bool pc_pb_fixed64(PbWriter *w, uint32_t field, uint64_t v)
108 return pc_pb_write_tag(w, field, PB_WT_I64) && pc_pb_write_le(w, v, 8);
111bool pc_pb_float(PbWriter *w, uint32_t field,
float v)
114 memcpy(&bits, &v, 4);
115 return pc_pb_fixed32(w, field, bits);
118bool pc_pb_double(PbWriter *w, uint32_t field,
double v)
121 memcpy(&bits, &v, 8);
122 return pc_pb_fixed64(w, field, bits);
125bool pc_pb_bytes(PbWriter *w, uint32_t field,
const uint8_t *data,
size_t len)
127 if (!pc_pb_write_tag(w, field, PB_WT_LEN) || !pc_pb_write_varint(w, len))
142 if (!data || w->pos + len > w->cap)
147 memcpy(w->buf + w->pos, data, len);
152bool pc_pb_string(PbWriter *w, uint32_t field,
const char *s)
159 return pc_pb_bytes(w, field, (
const uint8_t *)s, strnlen(s, w->cap + 1));
162size_t pc_pb_writer_finish(PbWriter *w)
164 return w->error ? 0 : w->pos;
167bool pc_pb_read_varint(
const uint8_t *buf,
size_t len,
size_t *pos, uint64_t *out)
169 if (!buf || !pos || !out)
176 for (
size_t b = 0; b < 10; b++)
182 uint8_t c = buf[i++];
183 v |= (uint64_t)(c & 0x7F) << shift;
195bool pc_pb_read_field(
const uint8_t *buf,
size_t len,
size_t *pos, PbField *out)
197 if (!buf || !pos || !out || *pos >= len)
202 if (!pc_pb_read_varint(buf, len, pos, &tag))
206 out->field_number = (uint32_t)(tag >> 3);
207 out->wire_type = (uint8_t)(tag & 0x07);
212 switch (out->wire_type)
215 return pc_pb_read_varint(buf, len, pos, &out->value);
222 for (
size_t i = 0; i < 8; i++)
224 v |= (uint64_t)buf[*pos + i] << (8 * i);
236 for (
size_t i = 0; i < 4; i++)
238 v |= (uint32_t)buf[*pos + i] << (8 * i);
246 if (!pc_pb_read_varint(buf, len, pos, &l))
254 out->data = buf + *pos;
255 out->len = (size_t)l;
264int64_t pc_pb_zigzag64(uint64_t v)
266 return (int64_t)(v >> 1) ^ -(int64_t)(v & 1);
269int32_t pc_pb_zigzag32(uint32_t v)
271 return (int32_t)(v >> 1) ^ -(int32_t)(v & 1);
274float pc_pb_float_bits(uint32_t bits)
277 memcpy(&f, &bits, 4);
281double pc_pb_double_bits(uint64_t bits)
284 memcpy(&d, &bits, 8);
Protocol Buffers wire codec (PC_ENABLE_PROTOBUF) - zero-heap streaming writer.