==> tests/compose.c <==1/* place.rs: gather_scatter_state, composer_matches_frames. */
2#include "mesh/check.h"
3#include "mesh/place_compose.h"
4
5#include <stdlib.h>
6
7static mps_spec spec(void) {
8 mps_region st[] = {{0x0, 0x8}, {0x100, 0x4}}, out[] = {{0x1000, 0x40}, {0x1400, 0x40}};
9 return mps_new(2, st, 2, 0x4, out, 2, 0x2000, 4);
10}
11
12/* A fake view: byte i of region (o, n) is (o + i) ^ salt. */
13static void view(void *ctx, uint32_t o, uint32_t n, uint8_t *out) {
14 uint8_t salt = (uint8_t)(uintptr_t)ctx;
15 for (uint32_t i = 0; i < n; i++) out[i] = (uint8_t)(o + i) ^ salt;
16}
17
18typedef struct {
19 uint32_t off[4], len[4];
20 uint8_t b[4][16];
21 int n;
22} writes;
23
24static void rec(void *ctx, uint32_t off, const uint8_t *b, uint32_t len) {
25 writes *w = ctx;
26 w->off[w->n] = off, w->len[w->n] = len;
27 memcpy(w->b[w->n++], b, len);
28}
29
30static bool region_is(const uint8_t *b, uint32_t o, uint32_t n, uint8_t salt) {
31 for (uint32_t i = 0; i < n; i++)
32 if (b[i] != ((uint8_t)(o + i) ^ salt)) return false;
33 return true;
34}
35
36int main(void) {
37 mps_spec s = spec();
38 mpw_bytes st = mpc_read_state(&s, view, (void *)0);
39 CHECK_U(st.n, 12);
40 writes w = {0};
41 char *err = NULL;
42 CHECK(mpc_write_state(&s, st.b, st.n, rec, &w, &err));
43 CHECK(w.n == 2 && w.off[0] == 0 && w.len[0] == 8 && w.off[1] == 0x100 && region_is(w.b[1], 0x100, 4, 0));
44 CHECK(!mpc_write_state(&s, st.b + 1, st.n - 1, rec, &w, &err));
45 CHECK_S(err, "state of 11 bytes, the manifest declares 12");
46 free(err);
47 mpw_bytes d = mpc_gather(&s, 0xa, view, (void *)0);
48 CHECK_U(d.n, 2 * mps_part_bytes(&s));
49 CHECK(region_is(d.b, 0x1010, 16, 0));
50 uint8_t buf[0x80] = {0};
51 CHECK(mpc_scatter(&s, buf, sizeof buf, 0xa, d.b, d.n, &err));
52 CHECK(region_is(buf + 0x10, 0x1010, 16, 0) && region_is(buf + 0x70, 0x1430, 16, 0));
53 bool zero = true;
54 for (int i = 0; i < 0x10; i++) zero &= buf[i] == 0;
55 CHECK(zero);
56 CHECK(!mpc_scatter(&s, buf, sizeof buf, 0xe, d.b, d.n, &err));
57 CHECK_S(err, "frame data of 64 bytes, parts 0xe need 96");
58 free(err);
59 CHECK_U(mpc_sys_nibbles(0xa, 3), 0x3030);
60 mpw_bytes_free(&st), mpw_bytes_free(&d);
61
62 /* composer_matches_frames */
63 uint64_t t = 1000;
64 mpc_composer c = {0};
65 mpw_bytes p0 = mpc_gather(&s, 3, view, (void *)1), p2 = mpc_gather(&s, 4, view, (void *)2), p3 = mpc_gather(&s, 8, view, (void *)3);
66 mpc_whole wh;
67 CHECK(mpc_add(&c, &s, 5, 3, 0, p0.b, p0.n, t, &wh, &err) == 0);
68 CHECK(mpc_add(&c, &s, 6, 8, 2, p3.b, p3.n, t, &wh, &err) == 0);
69 CHECK(mpc_add(&c, &s, 6, 3, 0, p0.b, p0.n, t, &wh, &err) == 0);
70 CHECK(mpc_add(&c, &s, 6, 4, 1, p2.b, p2.n, t + 2000, &wh, &err) == 1);
71 CHECK(wh.frame == 6 && wh.sys == 0x2100 && wh.t0 == t);
72 CHECK(region_is(wh.buf, 0x1000, 16, 1) && region_is(wh.buf + 0x20, 0x1020, 16, 2) && region_is(wh.buf + 0x70, 0x1430, 16, 3));
73 free(wh.buf);
74 CHECK_U(c.n, 0);
75 CHECK(mpc_add(&c, &s, 5, 4, 1, p2.b, p2.n, t, &wh, &err) == 0);
76 CHECK(mpc_add(&c, &s, 5, 4, 1, p2.b, p2.n, t, &wh, &err) == -1);
77 CHECK_S(err, "frame 5: parts 0x4 arrived twice");
78 free(err);
79 for (uint32_t f = 10; f < 30; f++) mpc_add(&c, &s, f, 3, 0, p0.b, p0.n, t, &wh, &err);
80 CHECK_U(c.n, MPC_PENDING);
81 mpc_clear(&c);
82 mpw_bytes_free(&p0), mpw_bytes_free(&p2), mpw_bytes_free(&p3);
83 mps_free(&s);
84 return mesh_check_done();
85}