code wiki / _hdl_build / nx_nmz_pack.nx
nx_nmz_pack.nx source
↩ module page · 119 lines · 6044 B
1// nx_nmz_pack.nx -- pack a decoded book/media (reader/<slug>/) into the OMNI Nishi Media container <slug>.nmz, on
2// the EXISTING sovereign substrate (NXR1 canonical record + nx_uxf_cid multicodec CID -- NOT a new format, the
3// audit fix). @kind tags the media KIND (default "book" => the .nbk profile). EPUB + MOBI decoders both emit the
4// same reader/<slug>/ layout, so this is the convergence point. Usage: nx_nmz_pack <slug> [kind]. expect_exit:0
5import "nx_syscalls.nx"
6import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc)
7import "nx_canon_bin.nx"
8import "nx_uxf_cid.nx"
9const K_MAGIC_2048: i64 = 2048
10const K_MAGIC_1024: i64 = 1024
11const K_MAGIC_67108864: i64 = 67108864
12
13func pk_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
14func pk_p(s: *u8) -> i64 { sys_write(1, s, pk_slen(s)); return 0 }
15// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer
16// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the
17// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls).
18// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign.
19func pk_n(v: i64) -> i64 { nxi_out(v); return 0 }
20func ensure_dir(path: *u8) -> i64 { __syscall(258, 0-100, path, 0x1ed, 0, 0, 0); return 0 }
21func cat(dst: *u8, off: i64, s: *u8) -> i64 { var i: i64=0; while s[i]!=(0 as u8){dst[off+i]=s[i];i=i+1} return off+i }
22
23func jfrom(hay: *u8, hl: i64, start: i64, needle: *u8) -> i64 {
24 let nl: i64 = pk_slen(needle); if nl == 0 { return 0-1 }
25 var i: i64 = start; if i < 0 { i = 0 }
26 while i + nl <= hl { var k: i64=0; var hit: i64=1; while k<nl { if hay[i+k]!=needle[k]{hit=0;k=nl}else{k=k+1} } if hit==1 {return i} i=i+1 }
27 return 0-1
28}
29func jstr(hay: *u8, hl: i64, pos: i64, out: *u8, cap: i64) -> i64 {
30 var i: i64 = pos
31 if i < hl { if hay[i]==(0x22 as u8) { i=i+1 } }
32 var o: i64 = 0
33 while i < hl { let c: i64 = hay[i] as i64; if c == 0x22 { i = hl } else { if c == 0x5c { if i+1<hl { if o<cap-1 { out[o]=hay[i+1]; o=o+1 } i=i+2 } else { i=i+1 } } else { if o<cap-1 { out[o]=hay[i] as u8; o=o+1 } i=i+1 } } }
34 out[o] = 0 as u8
35 return o
36}
37
38const ECAP: i64 = 1024
39
40func add_file(dir: *u8, name: *u8, keys: *i64, vals: *i64, vlens: *i64, idx: i64) -> i64 {
41 let path: *u8 = sys_mmap(K_MAGIC_2048)
42 var o: i64 = cat(path, 0, dir); path[o]=0x2f as u8; o=o+1
43 var j: i64 = 0; while name[j]!=(0 as u8){ path[o]=name[j]; o=o+1; j=j+1 } path[o]=0 as u8
44 let lp: *i64 = sys_mmap(8) as *i64; lp[0]=0
45 let data: *u8 = sys_read_file(path, lp)
46 if (data as i64) == 0 { return 0 }
47 let nm: *u8 = sys_mmap(256); var k: i64=0; while name[k]!=(0 as u8){ nm[k]=name[k]; k=k+1 } nm[k]=0 as u8
48 keys[idx] = nm as i64; vals[idx] = data as i64; vlens[idx] = lp[0]
49 return 1
50}
51
52func main(argc: i64, argv: *i64) -> i64 {
53 var slug: *u8 = "nishi_fixture" as *u8
54 var kind: *u8 = "book" as *u8
55 if argc >= 2 { slug = argv[1] as *u8 }
56 if argc >= 3 { kind = argv[2] as *u8 }
57
58 let dir: *u8 = sys_mmap(K_MAGIC_1024)
59 var dl: i64 = cat(dir, 0, "knowledge/staging/media/reader/" as *u8); dl = cat(dir, dl, slug); dir[dl] = 0 as u8
60
61 // manifest = book.json (books) OR cbx.json (comics) -- both list entries as "file":"X", so one loop packs both
62 let bjp: *u8 = sys_mmap(K_MAGIC_1024)
63 var manifest: *u8 = "book.json" as *u8
64 var bl: i64 = cat(bjp, 0, dir); bl = cat(bjp, bl, "/book.json" as *u8); bjp[bl]=0 as u8
65 let lp: *i64 = sys_mmap(8) as *i64; lp[0]=0
66 var bj: *u8 = sys_read_file(bjp, lp)
67 if (bj as i64)==0 {
68 manifest = "cbx.json" as *u8
69 bl = cat(bjp, 0, dir); bl = cat(bjp, bl, "/cbx.json" as *u8); bjp[bl]=0 as u8
70 lp[0]=0
71 bj = sys_read_file(bjp, lp)
72 }
73 if (bj as i64)==0 {
74 manifest = "audio.json" as *u8
75 bl = cat(bjp, 0, dir); bl = cat(bjp, bl, "/audio.json" as *u8); bjp[bl]=0 as u8
76 lp[0]=0
77 bj = sys_read_file(bjp, lp)
78 }
79 if (bj as i64)==0 { pk_p("NMZ-PACK-FAIL no-manifest (book.json|cbx.json|audio.json) " as *u8); pk_p(bjp); pk_p("\n" as *u8); sys_exit(1); return 1 }
80 let bn: i64 = lp[0]
81
82 let keys: *i64 = sys_mmap(ECAP*8) as *i64
83 let vals: *i64 = sys_mmap(ECAP*8) as *i64
84 let vlens: *i64 = sys_mmap(ECAP*8) as *i64
85 // @kind field (the media kind; default book)
86 keys[0] = "@kind" as *u8 as i64; vals[0] = kind as i64; vlens[0] = pk_slen(kind)
87 // book.json manifest
88 keys[1] = manifest as i64; vals[1] = bj as i64; vlens[1] = bn
89 var count: i64 = 2
90
91 let nbuf: *u8 = sys_mmap(512)
92 var cur: i64 = 0
93 var go: i64 = 1
94 while go == 1 {
95 let fat: i64 = jfrom(bj, bn, cur, "\"file\":\"" as *u8)
96 if fat < 0 { go = 0 } else {
97 jstr(bj, bn, fat + 7, nbuf, 512)
98 if count < ECAP { if add_file(dir, nbuf, keys, vals, vlens, count) == 1 { count = count + 1 } }
99 cur = fat + 7
100 }
101 }
102 if count < ECAP { if add_file(dir, "xray.json" as *u8, keys, vals, vlens, count) == 1 { count = count + 1 } }
103
104 let out: *u8 = sys_mmap(K_MAGIC_67108864)
105 let nbytes: i64 = canon_encode_bin(keys, vals, vlens, count, out) // binary-safe canonical NXR1 (substrate sibling)
106 let cid: *u8 = sys_mmap(96)
107 uxf_cid_profiled(UXF_ARCHIVE, out, nbytes, cid)
108
109 ensure_dir("knowledge/staging/media/nmz" as *u8)
110 let outp: *u8 = sys_mmap(K_MAGIC_1024)
111 var ol: i64 = cat(outp, 0, "knowledge/staging/media/nmz/" as *u8); ol = cat(outp, ol, slug); ol = cat(outp, ol, ".nmz" as *u8); outp[ol]=0 as u8
112 let fd: i64 = sys_openat_wr(outp, 0x1a4)
113 if fd < 0 { pk_p("NMZ-PACK-FAIL open out\n" as *u8); sys_exit(1); return 1 }
114 sys_write(fd, out, nbytes); sys_close(fd)
115
116 pk_p("NMZ-PACK slug=" as *u8); pk_p(slug); pk_p(" kind=" as *u8); pk_p(kind); pk_p(" entries=" as *u8); pk_n(count)
117 pk_p(" bytes=" as *u8); pk_n(nbytes); pk_p(" cid=" as *u8); pk_p(cid); pk_p(" -> " as *u8); pk_p(outp); pk_p("\n" as *u8)
118 sys_exit(0); return 0
119}