inspect.tri (3035B)
1 !import prelude * 2 !import native_math as N 3 !import arboricx as A 4 !import arboricx_common as C 5 !import arboricx_manifest as M 6 !import arboricx_nodes as Nodes 7 !export inspectBundle 8 !export renderSummary 9 !export describeError 10 11 -- Validate the complete in-memory bundle without reconstructing or applying 12 -- exported trees. Result success is (stored-node-count, export-records). 13 -- Each export record is (UTF-8 name bytes, (u32 root bytes, (kind bytes, ABI bytes))). 14 -- The decoder's remainder is an internal section cursor, NOT unconsumed input; 15 -- success deliberately returns an empty remainder. Failure remainders retain 16 -- opaque diagnostic context, not an incremental parsing continuation. 17 inspectBundle bytes = (bindResult (A.readArboricxDecoded bytes) 18 (decoded _ : ok 19 (pair (C.u64BEBytesToNat (Nodes.nodesSectionCount (snd decoded))) 20 (M.manifestExports (fst (fst decoded)))) t)) 21 22 hexDigit n = (lazyBool (_ : N.add 48 n) (_ : N.add 55 n) (N.lt n 10)) 23 24 -- Byte-wise percent escaping makes TSV fields unambiguous and terminal-safe. 25 -- Only printable ASCII other than '%' passes through, including for UTF-8 names. 26 escapeField [] = [] 27 escapeField [37 | rest] = append "%25" (escapeField rest) 28 escapeField [byte | rest] = (lazyBool 29 (_ : pair byte (escapeField rest)) 30 (_ : let pieces = N.divMod byte 16 in 31 pair 37 (pair (hexDigit (fst pieces)) (pair (hexDigit (snd pieces)) (escapeField rest)))) 32 (N.inRange byte 32 126)) 33 escapeField _ = [] 34 35 renderExports [] = "" 36 renderExports [(name, (root, (kind, abi))) | rest] = (append "export\t" 37 (append (escapeField name) (append "\t" (append (showNumber (C.u32BEBytesToNat root)) 38 (append "\t" (append (escapeField kind) (append "\t" (append (escapeField abi) 39 (append "\n" (renderExports rest)))))))))) 40 renderExports _ = "" 41 42 -- Accepts a successful inspectBundle summary, not an arbitrary unvalidated tree. 43 -- Count stored records, never unfold logical occurrences of shared branches. 44 renderSummary summary = (append "stored-nodes\t" (append (showNumber (fst summary)) 45 (append "\n" (renderExports (snd summary))))) 46 47 -- Stable human-facing categories alongside the numeric codec diagnostic. 48 describeError 1 = "Unexpected end of input" 49 describeError 2 = "Unexpected bytes or invalid bundle magic" 50 describeError 3 = "Unexpected byte" 51 describeError 4 = "Missing required section" 52 describeError 5 = "Unsupported bundle version or header" 53 describeError 6 = "Duplicate section" 54 describeError 7 = "Duplicate node record" 55 describeError 8 = "Invalid node payload" 56 describeError 9 = "Invalid node reference or export root" 57 describeError 10 = "Invalid manifest magic" 58 describeError 11 = "Unsupported manifest version" 59 describeError 12 = "Trailing manifest bytes" 60 describeError 13 = "Invalid manifest, export interface or metadata" 61 describeError 15 = "Invalid binary input" 62 describeError 16 = "Invalid binary count" 63 describeError 17 = "Unsupported section" 64 describeError 18 = "Invalid section range or truncated container" 65 describeError _ = "Unrecognized bundle diagnostic"