code wiki / _hdl_build / nx_sovgit_unpack_gate.nx
nx_sovgit_unpack_gate.nx source
↩ module page · 94 lines · 5257 B
1// nx_sovgit_unpack_gate.nx -- ★SOVGIT rung X1d: PACK PARSER. Reads a git packfile (ours OR git-generated), extracts
2// each object (varint type+size header, then inflate the per-object zlib stream), reframes "<type> <size>\0<content>",
3// SHA-256s it + writes it loose. This is the INVERSE of X1b (pack gen) and the CORE of git-receive-pack (push =
4// unpack the client's pack). Pure reuse of X0: nx_zlib_inflate (per-object stream, bytes_consumed advances to the next
5// object) + sha256 + sg_write_loose. license_tier: ORIGINAL expect_exit: 0
6import "nx_sovgit_obj.nx"
7
8func hw(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
9func pn(v: i64) -> i64 { let b: *u8 = sys_mmap(32); var x: i64 = v; var i: i64 = 31; if x == 0 { b[i] = 48 as u8; i = i - 1 } while x > 0 { b[i] = (48 + x % 10) as u8; x = x / 10; i = i - 1 } sys_write(1, (b as i64 + i + 1) as *u8, 31 - i); return 0 }
10func show64(g: *u8) -> i64 { var i: i64 = 0; while i < 64 { sys_write(1, (g as i64 + i) as *u8, 1); i = i + 1 } return 0 }
11func hexhas(list: *u8, n: i64, want: *u8) -> i64 {
12 var i: i64 = 0
13 while i < n {
14 var k: i64 = 0
15 while k < 64 { if list[i * 64 + k] != want[k] { k = 99 } else { k = k + 1 } }
16 if k == 64 { return 1 }
17 i = i + 1
18 }
19 return 0
20}
21func type_str(t: i64) -> *u8 {
22 if t == 1 { return "commit" as *u8 }
23 if t == 2 { return "tree" as *u8 }
24 if t == 3 { return "blob" as *u8 }
25 if t == 4 { return "tag" as *u8 }
26 return "?" as *u8
27}
28func be32r(b: *u8, at: i64) -> i64 { return ((b[at] as i64) << 24) | ((b[at + 1] as i64) << 16) | ((b[at + 2] as i64) << 8) | (b[at + 3] as i64) }
29
30func main(argc: i64, argv: *i64) -> i64 {
31 hw("=== nx_sovgit_unpack_gate -- X1d: parse a git packfile, extract + reframe + sha256 each object ===\n" as *u8)
32 var path: *u8 = "knowledge/sovgit.pack" as *u8
33 if argc >= 2 { path = argv[1] as *u8 }
34 hw("pack: " as *u8); hw(path); hw("\n" as *u8)
35 let szp: *i64 = sys_mmap(16) as *i64
36 let pack: *u8 = sys_read_file(path, szp)
37 if (pack as i64) == 0 { hw("FAIL pack not found\n" as *u8); sys_exit(1); return 1 }
38 let plen: i64 = szp[0]
39 var fails: i64 = 0
40 if pack[0] != (80 as u8) { fails = fails + 1 }
41 if pack[1] != (65 as u8) { fails = fails + 1 }
42 if pack[2] != (67 as u8) { fails = fails + 1 }
43 if pack[3] != (75 as u8) { fails = fails + 1 }
44 if fails != 0 { hw("FAIL not a PACK\n" as *u8); sys_exit(1); return 1 }
45 let ver: i64 = be32r(pack, 4)
46 let count: i64 = be32r(pack, 8)
47 hw("PACK v" as *u8); pn(ver); hw(" objects=" as *u8); pn(count); hw("\n" as *u8)
48
49 sys_mkdir("knowledge/_sovgit_unpacked" as *u8, 0x1ed)
50 let objroot: *u8 = "knowledge/_sovgit_unpacked/objects" as *u8
51 let hexes: *u8 = sys_mmap(count * 64 + 64)
52
53 var pos: i64 = 12
54 var i: i64 = 0
55 var stop: i64 = 0
56 while i < count {
57 if stop == 0 {
58 var byte: i64 = pack[pos] as i64; pos = pos + 1
59 let typ: i64 = (byte >> 4) & 7
60 var size: i64 = byte & 15
61 var shift: i64 = 4
62 while (byte & 128) != 0 {
63 byte = pack[pos] as i64; pos = pos + 1
64 size = size | ((byte & 127) << shift)
65 shift = shift + 7
66 }
67 let r: *NxZlibResult = nx_zlib_inflate((pack as i64 + pos) as *u8, plen - pos, 1 << 20)
68 if r.error_code != 0 { hw(" obj " as *u8); pn(i); hw(" INFLATE-FAIL err=" as *u8); pn(r.error_code); hw("\n" as *u8); fails = fails + 1; stop = 1 } else {
69 let content: *u8 = r.output_data
70 let clen: i64 = r.output_size
71 pos = pos + r.bytes_consumed
72 if clen != size { hw(" obj " as *u8); pn(i); hw(" SIZE-MISMATCH hdr=" as *u8); pn(size); hw(" inflated=" as *u8); pn(clen); hw("\n" as *u8); fails = fails + 1 }
73 let hex: *u8 = (hexes as i64 + i * 64) as *u8
74 let wh: *u8 = sys_mmap(80)
75 sg_write_loose(objroot, type_str(typ), content, clen, wh)
76 var c2: i64 = 0
77 while c2 < 64 { hex[c2] = wh[c2]; c2 = c2 + 1 }
78 hw(" obj " as *u8); pn(i); hw(": " as *u8); hw(type_str(typ)); hw(" size=" as *u8); pn(clen); hw(" sha=" as *u8); show64(hex); hw("\n" as *u8)
79 i = i + 1
80 }
81 } else { i = count }
82 }
83
84 // verify the 3 known objects extracted (works for our X1b pack + any git pack of the same repo)
85 if hexhas(hexes, count, "8aec4e4876f854f688d0ebfc8f37598f38e5fd6903cccc850ca36591175aeb60" as *u8) != 1 { hw(" MISS blob\n" as *u8); fails = fails + 1 }
86 if hexhas(hexes, count, "06d48a30caf6b4263876dbc71cec3bedfa08df79a4a59d55fbb9ea106a1ecc9c" as *u8) != 1 { hw(" MISS tree\n" as *u8); fails = fails + 1 }
87 if hexhas(hexes, count, "02acc3e80a9f6c427e5013d38a788218a59adaba62eaa221ee570a4df963407e" as *u8) != 1 { hw(" MISS commit\n" as *u8); fails = fails + 1 }
88
89 hw("\n" as *u8)
90 if fails == 0 { hw("SOVGIT-X1d GREEN -- pack parsed; all objects extracted + reframed + sha-verified byte-exact -> loose\n" as *u8); sys_exit(0); return 0 }
91 hw("SOVGIT-X1d RED fails=" as *u8); pn(fails); hw("\n" as *u8)
92 sys_exit(1)
93 return 1
94}