11#if DETWS_ENABLE_MSGPACK
16void msgpack_init(MsgpackWriter *w, uint8_t *buf,
size_t cap)
21size_t msgpack_len(
const MsgpackWriter *w)
26bool msgpack_ok(
const MsgpackWriter *w)
33static void put(MsgpackWriter *w, uint8_t b)
39static void put_be(MsgpackWriter *w, uint64_t val,
int nbytes)
44void msgpack_uint(MsgpackWriter *w, uint64_t v)
58 else if (v <= 0xffffffffULL)
70void msgpack_int(MsgpackWriter *w, int64_t v)
74 msgpack_uint(w, (uint64_t)v);
87 put_be(w, (uint64_t)(uint16_t)v, 2);
89 else if (v >= -2147483648LL)
92 put_be(w, (uint64_t)(uint32_t)v, 4);
97 put_be(w, (uint64_t)v, 8);
101void msgpack_str_n(MsgpackWriter *w,
const char *s,
size_t len)
104 put(w, (uint8_t)(0xa0 | len));
105 else if (len <= 0xff)
108 put(w, (uint8_t)len);
110 else if (len <= 0xffff)
120 for (
size_t i = 0; i < len; i++)
121 put(w, (uint8_t)s[i]);
124void msgpack_str(MsgpackWriter *w,
const char *s)
126 msgpack_str_n(w, s, s ? strnlen(s, w->cap + 1) : 0);
129void msgpack_bytes(MsgpackWriter *w,
const uint8_t *data,
size_t len)
134 put(w, (uint8_t)len);
136 else if (len <= 0xffff)
146 for (
size_t i = 0; i < len; i++)
150void msgpack_bool(MsgpackWriter *w,
bool b)
152 put(w, b ? 0xc3 : 0xc2);
155void msgpack_nil(MsgpackWriter *w)
160void msgpack_float(MsgpackWriter *w,
float f)
163 memcpy(&bits, &f,
sizeof(bits));
168void msgpack_array(MsgpackWriter *w,
size_t count)
171 put(w, (uint8_t)(0x90 | count));
172 else if (count <= 0xffff)
184void msgpack_map(MsgpackWriter *w,
size_t count)
187 put(w, (uint8_t)(0x80 | count));
188 else if (count <= 0xffff)
204void msgpack_reader_init(MsgpackReader *r,
const uint8_t *buf,
size_t len)
209bool msgpack_reader_ok(
const MsgpackReader *r)
216static bool take_be(MsgpackReader *r,
size_t nbytes, uint64_t *out)
221MsgpackType msgpack_peek(MsgpackReader *r)
223 if (r->err || r->pos >= r->len)
224 return MsgpackType::MSGPACK_TYPE_INVALID;
225 uint8_t b = r->buf[r->pos];
227 return MsgpackType::MSGPACK_TYPE_UINT;
229 return MsgpackType::MSGPACK_TYPE_INT;
233 return MsgpackType::MSGPACK_TYPE_MAP;
235 return MsgpackType::MSGPACK_TYPE_ARRAY;
237 return MsgpackType::MSGPACK_TYPE_STR;
241 return MsgpackType::MSGPACK_TYPE_NIL;
244 return MsgpackType::MSGPACK_TYPE_BOOL;
248 return MsgpackType::MSGPACK_TYPE_BIN;
251 return MsgpackType::MSGPACK_TYPE_FLOAT;
256 return MsgpackType::MSGPACK_TYPE_UINT;
261 return MsgpackType::MSGPACK_TYPE_INT;
265 return MsgpackType::MSGPACK_TYPE_STR;
268 return MsgpackType::MSGPACK_TYPE_ARRAY;
271 return MsgpackType::MSGPACK_TYPE_MAP;
273 return MsgpackType::MSGPACK_TYPE_INVALID;
277bool msgpack_read_uint(MsgpackReader *r, uint64_t *out)
279 if (r->err || r->pos >= r->len)
284 uint8_t b = r->buf[r->pos];
295 if (!take_be(r, 1, &v))
299 if (!take_be(r, 2, &v))
303 if (!take_be(r, 4, &v))
307 if (!take_be(r, 8, &v))
318bool msgpack_read_int(MsgpackReader *r, int64_t *out)
320 if (r->err || r->pos >= r->len)
325 uint8_t b = r->buf[r->pos];
342 if (!take_be(r, 1, &v))
347 if (!take_be(r, 2, &v))
352 if (!take_be(r, 4, &v))
357 if (!take_be(r, 8, &v))
362 if (!take_be(r, 1, &v))
364 *out = (int8_t)(uint8_t)v;
367 if (!take_be(r, 2, &v))
369 *out = (int16_t)(uint16_t)v;
372 if (!take_be(r, 4, &v))
374 *out = (int32_t)(uint32_t)v;
377 if (!take_be(r, 8, &v))
387bool msgpack_read_bool(MsgpackReader *r,
bool *out)
389 if (r->err || r->pos >= r->len)
394 uint8_t b = r->buf[r->pos];
408bool msgpack_read_nil(MsgpackReader *r)
410 if (r->err || r->pos >= r->len || r->buf[r->pos] != 0xc0)
419bool msgpack_read_float(MsgpackReader *r,
float *out)
421 if (r->err || r->pos >= r->len)
426 uint8_t b = r->buf[r->pos];
430 if (!take_be(r, 4, &v))
432 uint32_t bits = (uint32_t)v;
433 memcpy(out, &bits,
sizeof(*out));
438 if (!take_be(r, 8, &v))
441 memcpy(&d, &v,
sizeof(d));
450static bool read_blob(MsgpackReader *r,
bool want_str,
const uint8_t **out,
size_t *len)
452 if (r->err || r->pos >= r->len)
457 uint8_t b = r->buf[r->pos];
460 if (want_str && b >= 0xa0 && b <= 0xbf)
462 n = (size_t)(b & 0x1f);
467 const uint8_t f8 = want_str ? 0xd9 : 0xc4;
468 const uint8_t f16 = want_str ? 0xda : 0xc5;
469 const uint8_t f32 = want_str ? 0xdb : 0xc6;
472 if (!take_be(r, 1, &v))
477 if (!take_be(r, 2, &v))
482 if (!take_be(r, 4, &v))
492 if (r->pos + n > r->len)
497 *out = &r->buf[r->pos];
503bool msgpack_read_str(MsgpackReader *r,
const char **out,
size_t *len)
505 return read_blob(r,
true, (
const uint8_t **)out, len);
508bool msgpack_read_bytes(MsgpackReader *r,
const uint8_t **out,
size_t *len)
510 return read_blob(r,
false, out, len);
514static bool read_count(MsgpackReader *r,
bool want_map,
size_t *count)
516 if (r->err || r->pos >= r->len)
521 uint8_t b = r->buf[r->pos];
522 const uint8_t fix_lo = want_map ? 0x80 : 0x90;
523 const uint8_t fix_hi = want_map ? 0x8f : 0x9f;
524 const uint8_t f16 = want_map ? 0xde : 0xdc;
525 const uint8_t f32 = want_map ? 0xdf : 0xdd;
526 if (b >= fix_lo && b <= fix_hi)
528 *count = (size_t)(b & 0x0f);
535 if (!take_be(r, 2, &v))
540 if (!take_be(r, 4, &v))
552bool msgpack_read_array(MsgpackReader *r,
size_t *count)
554 return read_count(r,
false, count);
557bool msgpack_read_map(MsgpackReader *r,
size_t *count)
559 return read_count(r,
true, count);
Shared byte-cursor mechanics for the binary codecs (one source of truth).
void det_bw_put_be(W *w, uint64_t val, int nbytes)
Append the low nbytes of val, big-endian (network order).
bool det_br_take_be(R *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...
void det_br_init(R *r, const uint8_t *buf, size_t len)
Bind a read cursor to buf (length len) at offset 0.
void det_bw_put(W *w, uint8_t b)
Append one byte; on overflow set the flag but keep counting pos.
bool det_br_ok(const R *r)
True while no malformed / out-of-bounds read has occurred.
bool det_bw_ok(const W *w)
True while every write has fit in the buffer.
void det_bw_init(W *w, uint8_t *buf, size_t cap)
Bind a write cursor to buf (capacity cap) and reset it.
size_t det_bw_len(const W *w)
Bytes the payload needs so far (keeps counting past cap on overflow).
Layer 6 (Presentation) - zero-heap MessagePack encoder and decoder.