18static void put(
pc_span *w, uint8_t b)
24static void put_be(
pc_span *w, uint64_t val, int32_t nbytes)
29void pc_msgpack_uint(
pc_span *w, uint64_t v)
45 else if (v <= 0xffffffffULL)
57void pc_msgpack_int(
pc_span *w, int64_t v)
61 pc_msgpack_uint(w, (uint64_t)v);
76 put_be(w, (uint64_t)(uint16_t)v, 2);
78 else if (v >= -2147483648LL)
81 put_be(w, (uint64_t)(uint32_t)v, 4);
86 put_be(w, (uint64_t)v, 8);
90void pc_msgpack_str_n(
pc_span *w,
const char *s,
size_t len)
94 put(w, (uint8_t)(0xa0 | len));
101 else if (len <= 0xffff)
111 for (
size_t i = 0; i < len; i++)
113 put(w, (uint8_t)s[i]);
117void pc_msgpack_str(
pc_span *w,
const char *s)
119 pc_msgpack_str_n(w, s, s ? strnlen(s, w->
cap + 1) : 0);
122void pc_msgpack_bytes(
pc_span *w,
const uint8_t *data,
size_t len)
127 put(w, (uint8_t)len);
129 else if (len <= 0xffff)
139 for (
size_t i = 0; i < len; i++)
145void pc_msgpack_bool(
pc_span *w,
bool b)
147 put(w, b ? 0xc3 : 0xc2);
150void pc_msgpack_null(
pc_span *w)
155void pc_msgpack_float(
pc_span *w,
float f)
158 memcpy(&bits, &f,
sizeof(bits));
163void pc_msgpack_array(
pc_span *w,
size_t count)
167 put(w, (uint8_t)(0x90 | count));
169 else if (count <= 0xffff)
181void pc_msgpack_map(
pc_span *w,
size_t count)
185 put(w, (uint8_t)(0x80 | count));
187 else if (count <= 0xffff)
199void pc_msgpack_label(
pc_span *w,
const char *name, int64_t num)
202 pc_msgpack_int(w, num);
211static bool take_be(
pc_cspan *r,
size_t nbytes, uint64_t *out)
222 uint8_t b = r->
buf[r->
pos];
284bool pc_msgpack_read_uint(
pc_cspan *r, uint64_t *out)
291 uint8_t b = r->
buf[r->
pos];
302 if (!take_be(r, 1, &v))
308 if (!take_be(r, 2, &v))
314 if (!take_be(r, 4, &v))
320 if (!take_be(r, 8, &v))
333bool pc_msgpack_read_int(
pc_cspan *r, int64_t *out)
340 uint8_t b = r->
buf[r->
pos];
357 if (!take_be(r, 1, &v))
364 if (!take_be(r, 2, &v))
371 if (!take_be(r, 4, &v))
378 if (!take_be(r, 8, &v))
385 if (!take_be(r, 1, &v))
389 *out = (int8_t)(uint8_t)v;
392 if (!take_be(r, 2, &v))
396 *out = (int16_t)(uint16_t)v;
399 if (!take_be(r, 4, &v))
403 *out = (int32_t)(uint32_t)v;
406 if (!take_be(r, 8, &v))
418bool pc_msgpack_read_bool(
pc_cspan *r,
bool *out)
425 uint8_t b = r->
buf[r->
pos];
443bool pc_msgpack_read_null(
pc_cspan *r)
454bool pc_msgpack_read_float(
pc_cspan *r,
float *out)
461 uint8_t b = r->
buf[r->
pos];
465 if (!take_be(r, 4, &v))
469 uint32_t bits = (uint32_t)v;
470 memcpy(out, &bits,
sizeof(*out));
475 if (!take_be(r, 8, &v))
480 memcpy(&d, &v,
sizeof(d));
489static bool read_blob(
pc_cspan *r,
bool want_str,
const uint8_t **out,
size_t *len)
496 uint8_t b = r->
buf[r->
pos];
499 if (want_str && b >= 0xa0 && b <= 0xbf)
501 n = (size_t)(b & 0x1f);
506 const uint8_t f8 = want_str ? 0xd9 : 0xc4;
507 const uint8_t f16 = want_str ? 0xda : 0xc5;
508 const uint8_t f32 = want_str ? 0xdb : 0xc6;
511 if (!take_be(r, 1, &v))
518 if (!take_be(r, 2, &v))
525 if (!take_be(r, 4, &v))
548bool pc_msgpack_read_str(
pc_cspan *r,
const char **out,
size_t *len)
550 return read_blob(r,
true, (
const uint8_t **)out, len);
553bool pc_msgpack_read_bytes(
pc_cspan *r,
const uint8_t **out,
size_t *len)
555 return read_blob(r,
false, out, len);
559static bool read_count(
pc_cspan *r,
bool want_map,
size_t *count)
566 uint8_t b = r->
buf[r->
pos];
567 const uint8_t fix_lo = want_map ? 0x80 : 0x90;
568 const uint8_t fix_hi = want_map ? 0x8f : 0x9f;
569 const uint8_t f16 = want_map ? 0xde : 0xdc;
570 const uint8_t f32 = want_map ? 0xdf : 0xdd;
571 if (b >= fix_lo && b <= fix_hi)
573 *count = (size_t)(b & 0x0f);
580 if (!take_be(r, 2, &v))
587 if (!take_be(r, 4, &v))
601bool pc_msgpack_read_array(
pc_cspan *r,
size_t *count)
603 return read_count(r,
false, count);
606bool pc_msgpack_read_map(
pc_cspan *r,
size_t *count)
608 return read_count(r,
true, count);
The byte verbs - append into a pc_span, take out of a pc_cspan.
void pc_bw_put_be(pc_span *w, uint64_t val, int32_t nbytes)
Append the low nbytes of val, big-endian (network order).
void pc_bw_put(pc_span *w, uint8_t b)
Append one byte; on overflow set the flag but keep counting pos.
bool pc_br_take_be(pc_cspan *r, size_t nbytes, uint64_t *out)
Read nbytes big-endian immediately after the tag byte at pos, advancing past the tag and the argument...
pc_codec_type
The next item's type, reported by pc_codec::peek without consuming it.
@ PC_CODEC_INVALID
end of buffer, a prior error, or an item this format does not carry
Layer 6 (Presentation) - zero-heap MessagePack encoder and decoder.
const uint8_t * buf
first byte, or nullptr when there is nothing to read
size_t len
readable bytes at buf (0 whenever buf is nullptr)
bool err
sticky: a read ran past len
A writable byte region: the storage, the capacity that belongs to it, and what has been produced into...
size_t cap
bytes writable at buf (0 whenever buf is nullptr)