code wiki / _hdl_build / nx_nmz.nx
nx_nmz.nx source
↩ module page · 89 lines · 4679 B
1// ⚠ SUPERSEDED 2026-06-22 -- nmz_emit/nmz_get here were extracted to the shared substrate sibling nx_canon_bin
2// (canon_encode_bin/canon_get_bin), so nx_nmz_pack + nx_nmz_gate now import nx_canon_bin directly (DRY). Nothing
3// imports nx_nmz anymore; kept as the .nmz FORMAT SPEC reference only. The .nmz format = a binary-safe NXR1 record
4// (nx_canon_bin) carrying @kind + entry bytes, content-addressed by nx_uxf_cid.uxf_cid_profiled(UXF_ARCHIVE).
5//
6// nx_nmz.nx -- the NISHI MEDIA container (.nmz): the OMNI media format, built ON the existing sovereign storage
7// substrate (NOT a new format -- audit 2026-06-22, operator: ".nbk is a BOOK format, the omni one would be like
8// .nmz"). A .nmz is a BINARY-SAFE nx_canon_cid NXR1 canonical record (magic "NXR1" | u32be nfields | per field,
9// KEY-SORTED: u32be klen | key | u32be vlen | value) carrying:
10// "@kind" -> book | comic | audio | video | album (the media KIND; codecs specialize, container unifies)
11// "<entry-name>" -> raw bytes (book.json, chap0.txt, cover.png, track.opus, ...)
12// Content address = nx_uxf_cid.uxf_cid_profiled(UXF_ARCHIVE, bytes) = "nxc1-05-"+sha256(codec||canon) (REUSED, the
13// sovereign substrate's sha256 multicodec CID -- NOT a new djb2). ".nbk" = a .nmz with @kind=book (an extension
14// alias, same format). The ONLY new code here is BINARY-SAFE NXR1 emit/get (canon_encode is strlen/string-only,
15// so it can't hold image/audio bytes); same format, candidate to fold back into nx_canon_cid as canon_encode_bin.
16// license_tier: ORIGINAL
17import "nx_syscalls.nx"
18import "nx_uxf_cid.nx" // uxf_cid_profiled / uxf_codec_of_cid / UXF_ARCHIVE / UXF_MEDIA
19
20func nmz_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
21func nmz_w32(p: *u8, o: i64, v: i64) -> i64 { p[o]=((v>>24)&0xff) as u8; p[o+1]=((v>>16)&0xff) as u8; p[o+2]=((v>>8)&0xff) as u8; p[o+3]=(v&0xff) as u8; return o+4 }
22func nmz_be32(b: *u8, o: i64) -> i64 { return ((b[o] as i64)<<24)|((b[o+1] as i64)<<16)|((b[o+2] as i64)<<8)|(b[o+3] as i64) }
23// byte-lexicographic compare of NUL-terminated keys (same rule as nx_canon_cid.cc_cmp): <0 / 0 / >0
24func nmz_cmp(a: *u8, b: *u8) -> i64 {
25 var i: i64 = 0
26 while 1 == 1 { let ca: i64 = a[i] as i64; let cb: i64 = b[i] as i64; if ca != cb { return ca - cb } if ca == 0 { return 0 } i = i + 1 }
27 return 0
28}
29
30// emit a BINARY-SAFE canonical NXR1 record from `count` fields (keys NUL-term, vals raw bytes + explicit vlens),
31// key-sorted so insertion order does NOT matter (1 logical record => 1 byte string => 1 CID). returns byte length.
32func nmz_emit(out: *u8, keys: *i64, vals: *i64, vlens: *i64, count: i64) -> i64 {
33 let idx: *i64 = sys_mmap(8 * (count + 2)) as *i64
34 var i: i64 = 0
35 while i < count { idx[i] = i; i = i + 1 }
36 i = 1
37 while i < count {
38 let cur: i64 = idx[i]
39 var j: i64 = i - 1
40 var go: i64 = 1
41 while go == 1 {
42 if j < 0 { go = 0 }
43 if go == 1 { if nmz_cmp(keys[idx[j]] as *u8, keys[cur] as *u8) > 0 { idx[j+1] = idx[j]; j = j - 1 } else { go = 0 } }
44 }
45 idx[j+1] = cur
46 i = i + 1
47 }
48 out[0]=78 as u8; out[1]=88 as u8; out[2]=82 as u8; out[3]=49 as u8 // "NXR1"
49 var o: i64 = nmz_w32(out, 4, count)
50 i = 0
51 while i < count {
52 let k: *u8 = keys[idx[i]] as *u8
53 let v: *u8 = vals[idx[i]] as *u8
54 let vl: i64 = vlens[idx[i]]
55 let kl: i64 = nmz_slen(k)
56 o = nmz_w32(out, o, kl)
57 var t: i64 = 0; while t < kl { out[o]=k[t]; o=o+1; t=t+1 }
58 o = nmz_w32(out, o, vl)
59 t = 0; while t < vl { out[o]=v[t]; o=o+1; t=t+1 }
60 i = i + 1
61 }
62 return o
63}
64
65// binary-safe extract: copy the value of field `key` into out (cap); returns vlen, or -1 if absent / not NXR1.
66func nmz_get(m: *u8, n: i64, key: *u8, out: *u8, cap: i64) -> i64 {
67 if n < 8 { return 0-1 }
68 if m[0]!=(78 as u8) { return 0-1 }
69 if m[1]!=(88 as u8) { return 0-1 }
70 if m[2]!=(82 as u8) { return 0-1 }
71 if m[3]!=(49 as u8) { return 0-1 }
72 let count: i64 = nmz_be32(m, 4)
73 let want: i64 = nmz_slen(key)
74 var p: i64 = 8
75 var e: i64 = 0
76 while e < count {
77 if p + 4 > n { return 0-1 }
78 let kl: i64 = nmz_be32(m, p); p = p + 4
79 var hit: i64 = 0
80 if kl == want { hit = 1; var t: i64=0; while t<kl { if m[p+t]!=key[t] { hit=0; t=kl } else { t=t+1 } } }
81 p = p + kl
82 if p + 4 > n { return 0-1 }
83 let vl: i64 = nmz_be32(m, p); p = p + 4
84 if hit == 1 { var w: i64=0; while w<vl { if w<cap { out[w]=m[p+w] } w=w+1 } return vl }
85 p = p + vl
86 e = e + 1
87 }
88 return 0-1
89}