code wiki / (root) / nx_le.nx

nx_le.nx source

↩ module page · 246 lines · 7576 B

1// nx_le.nx -- canonical little-endian / big-endian fixed-width 2// binary read + write primitives. 3// 4// DRY consolidation per the shared-libraries cardinal. Three 5// existing callers inlined their own LE-read helpers: 6// 7// nx_bmp_header.bmp_read_u32 (BMP image parsing) 8// nx_cbor_decode (byte count reads) (CBOR length parsing) 9// nx_wav.nx (WAV audio parsing) 10// 11// Plus the queued GGUF (model weight) + safetensors + ELF / PE 12// header readers. Per the "rule of three" + no-reinventing 13// cardinals: this is the canonical primitive. 14// 15// ===== LE byte order ============================================= 16// 17// Little-endian: least-significant byte at lowest address. Used by 18// x86, AArch64 (default), RISC-V, ppc64LE, MIPS-LE, GGUF, ELF on LE 19// platforms, BMP, WAV, safetensors, most binary AI formats. 20// 21// ===== BE byte order ============================================= 22// 23// Big-endian: most-significant byte at lowest address. Used by 24// network protocols (TCP/IP headers, DNS, HTTP/2 frames), s390x 25// (big-endian platform), Java class files, PNG, MP3 ID3, MIDI. 26// 27// ===== API ======================================================= 28// 29// All readers take (buf: *u8, off: i64) and return the value as i64 30// (sign-extended for signed forms). Caller is responsible for 31// bounds-checking off + width <= buf_len. 32// 33// All writers take (buf: *u8, off: i64, val: i64). 34// 35// Per the bounded-loop cardinal: no loops needed (fixed-width 36// extracts are unrolled). 37// 38// genealogy_id: ietf_rfc_8949_cbor + ieee_754_byte_order + 39// wikipedia_endianness 40// lineage_id: substrate_le_be_v1 41 42// nx_safety_envelope: 43// intended_use: AUTO_APPLIED -- primitive-specific tuning queued 44// sil_target: SIL1 45// evidence: [bulk_applied_2026-05-16, see-file-comment-for-detail] 46// verdict: NOT_YET_EVALUATED 47 48import "nx_syscalls.nx" 49import "nx_tier.nx" 50const NX_MAGIC_32768: i64 = 32768 51const NX_MAGIC_65536: i64 = 65536 52const NX_MAGIC_2147483648: i64 = 2147483648 53const NX_MAGIC_4294967296: i64 = 4294967296 54 55// ===== Sealed-enum: LeVerdict ===================================== 56 57const NX_LE_OK: nx_int = 0 58const NX_LE_ERR_OOB: nx_int = 1 59const NX_LE_N_VERDICTS: nx_int = 2 60 61func nx_le_verdict_is_valid(v: nx_int) -> nx_int { 62 if v < 0 { return 0 } 63 if v >= NX_LE_N_VERDICTS { return 0 } 64 return 1 65} 66 67// ===== LE readers ================================================ 68 69func nx_le_read_u8(buf: *u8, off: i64) -> i64 { 70 return buf[off] 71} 72 73func nx_le_read_u16(buf: *u8, off: i64) -> i64 { 74 let b0: i64 = buf[off] 75 let b1: i64 = buf[off + 1] 76 return b0 + (b1 << 8) 77} 78 79func nx_le_read_u32(buf: *u8, off: i64) -> i64 { 80 let b0: i64 = buf[off] 81 let b1: i64 = buf[off + 1] 82 let b2: i64 = buf[off + 2] 83 let b3: i64 = buf[off + 3] 84 return b0 + (b1 << 8) + (b2 << 16) + (b3 << 24) 85} 86 87func nx_le_read_u64(buf: *u8, off: i64) -> i64 { 88 let lo: i64 = nx_le_read_u32(buf, off) 89 let hi: i64 = nx_le_read_u32(buf, off + 4) 90 return lo + (hi << 32) 91} 92 93// Signed: extract via the unsigned reader, then sign-extend. 94// For u32 -> i32: if top bit set (>= 0x80000000), subtract 2^32. 95 96func nx_le_read_i16(buf: *u8, off: i64) -> i64 { 97 let u: i64 = nx_le_read_u16(buf, off) 98 if u >= NX_MAGIC_32768 { return u - NX_MAGIC_65536 } 99 return u 100} 101 102func nx_le_read_i32(buf: *u8, off: i64) -> i64 { 103 let u: i64 = nx_le_read_u32(buf, off) 104 if u >= NX_MAGIC_2147483648 { return u - NX_MAGIC_4294967296 } 105 return u 106} 107 108// i64 is the native width -- no sign extension needed (u64 IS i64 109// in the substrate's i64 representation; caller chooses signedness). 110func nx_le_read_i64(buf: *u8, off: i64) -> i64 { 111 return nx_le_read_u64(buf, off) 112} 113 114// ===== LE writers ================================================ 115 116func nx_le_write_u8(buf: *u8, off: i64, val: i64) -> i64 { 117 buf[off] = val 118 return 1 119} 120 121func nx_le_write_u16(buf: *u8, off: i64, val: i64) -> i64 { 122 buf[off] = val 123 buf[off + 1] = val >> 8 124 return 2 125} 126 127func nx_le_write_u32(buf: *u8, off: i64, val: i64) -> i64 { 128 buf[off] = val 129 buf[off + 1] = val >> 8 130 buf[off + 2] = val >> 16 131 buf[off + 3] = val >> 24 132 return 4 133} 134 135func nx_le_write_u64(buf: *u8, off: i64, val: i64) -> i64 { 136 nx_le_write_u32(buf, off, val) 137 nx_le_write_u32(buf, off + 4, val >> 32) 138 return 8 139} 140 141// ===== BE readers ================================================ 142 143func nx_be_read_u16(buf: *u8, off: i64) -> i64 { 144 let b0: i64 = buf[off] 145 let b1: i64 = buf[off + 1] 146 return (b0 << 8) + b1 147} 148 149func nx_be_read_u32(buf: *u8, off: i64) -> i64 { 150 let b0: i64 = buf[off] 151 let b1: i64 = buf[off + 1] 152 let b2: i64 = buf[off + 2] 153 let b3: i64 = buf[off + 3] 154 return (b0 << 24) + (b1 << 16) + (b2 << 8) + b3 155} 156 157func nx_be_read_u64(buf: *u8, off: i64) -> i64 { 158 let hi: i64 = nx_be_read_u32(buf, off) 159 let lo: i64 = nx_be_read_u32(buf, off + 4) 160 return (hi << 32) + lo 161} 162 163// ===== BE writers ================================================ 164 165func nx_be_write_u16(buf: *u8, off: i64, val: i64) -> i64 { 166 buf[off] = val >> 8 167 buf[off + 1] = val 168 return 2 169} 170 171func nx_be_write_u32(buf: *u8, off: i64, val: i64) -> i64 { 172 buf[off] = val >> 24 173 buf[off + 1] = val >> 16 174 buf[off + 2] = val >> 8 175 buf[off + 3] = val 176 return 4 177} 178 179func nx_be_write_u64(buf: *u8, off: i64, val: i64) -> i64 { 180 nx_be_write_u32(buf, off, val >> 32) 181 nx_be_write_u32(buf, off + 4, val) 182 return 8 183} 184 185// ===== Self-test ================================================== 186// 187// Closed-form invariants: 188// (a) LE u32 of (0x78 0x56 0x34 0x12) == 0x12345678 189// (b) BE u32 of (0x12 0x34 0x56 0x78) == 0x12345678 190// (c) Round-trip: write_u64(x) then read_u64() = x 191// (d) i32 sign extension: 0xFFFFFFFF -> -1 192// (e) LE / BE u16, u32, u64 all consistent 193 194func main() -> i64 { 195 let buf: *u8 = sys_mmap(64) 196 197 // --- (a) LE u32 --- 198 buf[0] = 0x78; buf[1] = 0x56; buf[2] = 0x34; buf[3] = 0x12 199 let le32: i64 = nx_le_read_u32(buf, 0) 200 if le32 != 0x12345678 { return 10 } 201 202 // --- (b) BE u32 --- 203 buf[4] = 0x12; buf[5] = 0x34; buf[6] = 0x56; buf[7] = 0x78 204 let be32: i64 = nx_be_read_u32(buf, 4) 205 if be32 != 0x12345678 { return 20 } 206 207 // --- (c) Round-trip u64 LE --- 208 nx_le_write_u64(buf, 8, 0x0123456789abcdef) 209 let rt_le: i64 = nx_le_read_u64(buf, 8) 210 if rt_le != 0x0123456789abcdef { return 30 } 211 212 // --- (c) Round-trip u64 BE --- 213 nx_be_write_u64(buf, 16, 0x0123456789abcdef) 214 let rt_be: i64 = nx_be_read_u64(buf, 16) 215 if rt_be != 0x0123456789abcdef { return 31 } 216 217 // --- (d) i32 sign extension --- 218 buf[24] = 0xFF; buf[25] = 0xFF; buf[26] = 0xFF; buf[27] = 0xFF 219 let neg1: i64 = nx_le_read_i32(buf, 24) 220 if neg1 != -1 { return 40 } 221 222 // i16 sign extension on 0xFFFE -> -2 223 buf[28] = 0xFE; buf[29] = 0xFF 224 let neg2: i64 = nx_le_read_i16(buf, 28) 225 if neg2 != -2 { return 41 } 226 227 // --- (e) u16 LE/BE consistency --- 228 buf[30] = 0xAB; buf[31] = 0xCD 229 let le16: i64 = nx_le_read_u16(buf, 30) 230 let be16: i64 = nx_be_read_u16(buf, 30) 231 if le16 != 0xCDAB { return 50 } 232 if be16 != 0xABCD { return 51 } 233 234 // --- (f) u8 round-trip --- 235 nx_le_write_u8(buf, 32, 0x42) 236 if nx_le_read_u8(buf, 32) != 0x42 { return 60 } 237 238 // --- (g) Verdict gate --- 239 var vi: nx_int = 0 240 while vi < NX_LE_N_VERDICTS { 241 if nx_le_verdict_is_valid(vi) != 1 { return 70 + vi } 242 vi = vi + 1 243 } 244 245 return 0 246}