==> 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}