skip to content
==> include/mesh/jobs/wire.h <==
1/* @ajax/mesh-jobs-wire: the binary encoding of the job table's ops, the job frames and the job log
2 * (jobs.rs's `W` and `R`): little-endian u8/u32/u64, bytes as a u32 length then the bytes, strings as
3 * UTF-8 bytes, ranges as a u32 count then (start, end) u64 pairs.
4 *
5 * The reader stops at its first failure and keeps the message (jobs.rs's exact text: "job frame:
6 * short (3 of 8 bytes at 17)", "job frame: not UTF-8"); every later read fails too. */
7#ifndef MESH_JOBS_WIRE_H
8#define MESH_JOBS_WIRE_H
9
10#include "mesh/jobs/ranges.h"
11#include "mesh/strbuf.h"
12
13#include <stdbool.h>
14#include <stddef.h>
15#include <stdint.h>
16
17void mj_w_u8(msb *w, uint8_t v);
18void mj_w_u32(msb *w, uint32_t v);
19void mj_w_u64(msb *w, uint64_t v);
20void mj_w_bytes(msb *w, const void *b, size_t n);
21void mj_w_str(msb *w, const char *s);
22void mj_w_ranges(msb *w, const mj_ranges *r);
23
24typedef struct {
25    const uint8_t *b;
26    size_t n, at;
27    char *err; /* the first failure (owned), or NULL */
28} mj_rd;
29
30static inline mj_rd mj_rd_new(const void *b, size_t n) { return (mj_rd){(const uint8_t *)b, n, 0, NULL}; }
31void mj_rd_free(mj_rd *r);                     /* frees err */
32char *mj_rd_take_err(mj_rd *r);                /* the message, now the caller's */
33bool mj_rd_fail(mj_rd *r, char *msg);          /* records msg (owned) unless one is there; false */
34bool mj_rd_take(mj_rd *r, size_t n, const uint8_t **p);
35bool mj_rd_u8(mj_rd *r, uint8_t *v);
36bool mj_rd_u32(mj_rd *r, uint32_t *v);
37bool mj_rd_u64(mj_rd *r, uint64_t *v);
38bool mj_rd_bytes(mj_rd *r, uint8_t **b, size_t *n); /* a fresh copy (never NULL on success) */
39bool mj_rd_str(mj_rd *r, char **s);                 /* checked UTF-8, NUL-terminated copy */
40bool mj_rd_ranges(mj_rd *r, mj_ranges *out);
41static inline bool mj_rd_done(const mj_rd *r) { return r->at == r->n; }
42
43/* Rust's String::from_utf8 test: well-formed UTF-8 (no overlongs, surrogates or values past U+10FFFF). */
44bool mj_utf8_ok(const uint8_t *b, size_t n);
45/* Rust's String::from_utf8_lossy: each maximal invalid subsequence becomes U+FFFD. A new string. */
46char *mj_utf8_lossy(const uint8_t *b, size_t n);
47
48#endif