skip to content
==> src/encode.c <==
1/* manifest.rs's encode_entry and encode_ext: little-endian words and NUL-padded names. */
2#include "mesh/manifest_encode.h"
3
4#include "mesh/abi/base.h"
5#include "mesh/abi/placement.h"
6
7#include <string.h>
8
9static void put(uint8_t *b, size_t off, uint32_t v) {
10    for (int i = 0; i < 4; i++) b[off + (size_t)i] = (uint8_t)(v >> (8 * i));
11}
12
13static void put_str(uint8_t *b, size_t off, const char *s, size_t max) {
14    size_t n = strlen(s);
15    if (n > max) n = max;
16    memcpy(b + off, s, n);
17}
18
19void mesh_manifest_encode_entry(const mesh_manifest *m, const mesh_image *im, uint8_t b[MESH_PT_BYTES]) {
20    memset(b, 0, MESH_PT_BYTES);
21    put_str(b, MESH_PT_NAME, m->name, MESH_NAME_MAX);
22    mesh_manifest_window w = m->has_request ? m->request : (mesh_manifest_window){0, 0, 0, 0};
23    const struct {
24        size_t off;
25        uint32_t v;
26    } words[] = {
27        {MESH_PT_VIEW_OFF, im->view_off}, {MESH_PT_VIEW_BYTES, m->view_bytes}, {MESH_PT_SNAP_BYTES, m->snap_bytes},
28        {MESH_PT_NODES, m->nodes}, {MESH_PT_WARPS, m->warps}, {MESH_PT_POLICY, m->policy}, {MESH_PT_HZ, m->hz},
29        {MESH_PT_FANOUT, m->fanout}, {MESH_PT_PEER, m->peer}, {MESH_PT_READS_MASK, im->reads_mask},
30        {MESH_PT_INPUT_OFF, m->input_off}, {MESH_PT_INPUT_LEN, m->input_len},
31        {MESH_PT_REQ_OFF, w.req_off}, {MESH_PT_REQ_MAX, w.req_max}, {MESH_PT_RESP_OFF, w.resp_off}, {MESH_PT_RESP_MAX, w.resp_max},
32        {MESH_PT_REGS, im->regs}, {MESH_PT_CODE_BYTES, im->code_bytes}, {MESH_PT_VIEW_ABI, m->view_abi},
33        {MESH_PT_FLAGS, (m->batch ? MESH_FL_BATCH : 0u) | (m->autostart ? MESH_FL_AUTOSTART : 0u)},
34        {MESH_PT_ARG_MODE, m->arg_mode}, {MESH_PT_ARG_OFF, m->arg_off}, {MESH_PT_RT_ABI, im->rt_abi}, {MESH_PT_LOADS, im->loads},
35    };
36    for (size_t i = 0; i < sizeof words / sizeof words[0]; i++) put(b, words[i].off, words[i].v);
37    for (int i = 0; i < 8; i++) b[MESH_PT_PTX_HASH + (size_t)i] = (uint8_t)(im->ptx_hash >> (8 * i));
38}
39
40void mesh_manifest_encode_ext(const mesh_manifest *m, uint8_t b[MESH_PX_BYTES]) {
41    memset(b, 0, MESH_PX_BYTES);
42    for (size_t i = 0; i < MESH_COUNTERS; i++) put_str(b, MESH_PX_COUNTER_NAMES + MESH_NAME_BYTES * i, m->counters[i], MESH_NAME_MAX);
43    put(b, MESH_PX_FIELD_COUNT, (uint32_t)m->nfields);
44    put(b, MESH_PX_PLACE_CAP, m->place ? m->place->cap : MESH_PLACE_CAP_NONE);
45    put(b, MESH_PX_PARAM, m->param);
46    put(b, MESH_PX_SHARED, m->shared_bytes);
47    put(b, MESH_PX_SCRATCH_BYTES, m->scratch_bytes);
48    for (size_t i = 0; i < m->nfields; i++) {
49        size_t r = MESH_PX_FIELDS + MESH_FIELD_BYTES * i;
50        put_str(b, r + MESH_FD_NAME, m->fields[i].name, MESH_FD_NAME_MAX);
51        put(b, r + MESH_FD_TYPE, m->fields[i].ty);
52        put(b, r + MESH_FD_OFF, m->fields[i].off);
53    }
54}