tar.bend checks
raw source on the hub · import 0xf134d14ef1244d08994eac130bd22b62/tar.bend as Tar
tar archives (POSIX ustar with PAX path and size records) of regular files and directories over Bytes. Source: https://github.com/paymog/bend-kit/tree/main/tar
2 imports
import Base import bend-kit-bytes@0.3.2.0/bytes.bend as Bytes
Types
type Entry source · line 8 · raw
Type
An archive is a list of entries in order. Names are raw bytes (UTF-8 by convention), kept byte for byte; a directory keeps whatever trailing '/' its name has. Nothing here touches the filesystem. import ./tar/tar.bend as Tar
File@name:0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes -> @data:0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes -> Entry
Dir@name:0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes -> Entry
type Dec source · line 72 · raw
Data
Dec@v:U32 -> @digits:U32 -> @stop:U32 -> @ended:Bool -> @ok:Bool -> Dec
type DByte source · line 75 · raw
Data
DByte@byte:U32 -> @digit:Bool -> DByte
type Pax source · line 150 · raw
Type
Records from an 'x' header that apply to the next entry.
Pax@path:Maybe<&1, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes> -> @size:Maybe<&2, U32> -> Pax
type Pst source · line 153 · raw
Type
PGo@pax:Pax -> Pst
PEnd@pax:Pax -> Pst
PBadPst
type PKey source · line 158 · raw
Data
PPathPKey
PSizePKey
POtherPKey
type St source · line 317 · raw
Type
SHead@pax:Pax -> @acc:List<&1, Entry> -> St
SOk@entries:List<&1, Entry> -> St
SFailSt
type Hdr source · line 323 · raw
Data
Header metadata is Data so a checked read can advance without copying the header.
Hdr@sum:U32 -> @ok:Bool -> @size:U32 -> @size_ok:Bool -> @kind:U32 -> Hdr
Definitions
def pad source · line 14 · raw
@+n:U32 -> U32
n rounded up to a whole 512-byte block; 0 when that would pass U32.
def wsum source · line 18 · raw
@+w:U32 -> U32
The sum of w's four bytes.
def bsum.go source · line 21 · raw
@n:Nat -> @r:Pair(Array<U32>, U32) -> @+k:U32 -> @+acc:U32 -> Pair(Array<U32>, U32)
def bsum source · line 31 · raw
@a:Array<U32> -> @+k:U32 -> Pair(Array<U32>, U32)
The sum of the 512 bytes from word k: 0 only for a zero block.
def oct.go source · line 35 · raw
@n:Nat -> @r:Pair(Array<U32>, U32) -> @+j:U32 -> @+ph:U32 -> @+acc:U32 -> @+ok:Bool -> Pair(Array<U32>, Pair(U32, Bool))
Octal digits after leading spaces, ended by NUL, space, or the field's end. ph: 0 leading, 1 digits, 2 done.
def oct source · line 51 · raw
@a:Array<U32> -> @+j:U32 -> @+w:U32 -> Pair(Array<U32>, Pair(U32, Bool))
The octal field of w bytes at j, and whether it is well formed and fits a U32.
def cstr.go source · line 54 · raw
@n:Nat -> @r:Pair(Array<U32>, U32) -> @+j:U32 -> @+k:U32 -> @+done:Bool -> Pair(Array<U32>, U32)
def cstr source · line 69 · raw
@a:Array<U32> -> @+j:U32 -> @+w:U32 -> Pair(Array<U32>, U32)
The count of bytes before the first NUL in the w bytes from j.
def dec.byte.of source · line 78 · raw
@+len:U32 -> @r:Pair(Array<U32>, U32) -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes, Maybe<&2, DByte>)
def dec.byte source · line 82 · raw
@b:0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes -> @+i:U32 -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes, Maybe<&2, DByte>)
def dec.go source · line 87 · raw
@n:Nat -> @r:Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Maybe<&2, DByte>) -> @+acc:U32 -> @+digits:U32 -> @+ok:Bool -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Dec)
Consume decimal digits and, when present, their first non-digit delimiter.
def dec.start source · line 106 · raw
@r:Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, U32) -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Dec)
def dec source · line 110 · raw
@c:0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Dec)
def name.fin source · line 116 · raw
@+total:U32 -> @r:Pair(Array<U32>, Array<U32>) -> Pair(Array<U32>, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes)
Header i's name: prefix "/" name when the magic is POSIX ustar and the prefix is not empty.
def name.join source · line 120 · raw
@+i:U32 -> @+n:U32 -> @+pl:U32 -> @r:Pair(Array<U32>, Array<U32>) -> Pair(Array<U32>, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes)
def name.pre source · line 126 · raw
@+i:U32 -> @+n:U32 -> @r:Pair(Array<U32>, U32) -> Pair(Array<U32>, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes)
def pfx.len source · line 131 · raw
@ustar:Bool -> @a:Array<U32> -> @+i:U32 -> Pair(Array<U32>, U32)
def name.magic source · line 138 · raw
@+i:U32 -> @+n:U32 -> @r:Pair(Array<U32>, Bool) -> Pair(Array<U32>, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes)
def name.len source · line 142 · raw
@+i:U32 -> @r:Pair(Array<U32>, U32) -> Pair(Array<U32>, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes)
def header.name source · line 146 · raw
@a:Array<U32> -> @+i:U32 -> Pair(Array<U32>, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes)
def pr.key.size source · line 163 · raw
@hit:Bool -> @+len:U32 -> @a:Array<U32> -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes, Maybe<&2, PKey>)
def pr.key.sized source · line 170 · raw
@+len:U32 -> @r:Pair(Array<U32>, Bool) -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes, Maybe<&2, PKey>)
def pr.key.path source · line 174 · raw
@+i:U32 -> @+len:U32 -> @r:Pair(Array<U32>, Bool) -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes, Maybe<&2, PKey>)
def pr.key source · line 183 · raw
@b:0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes -> @+i:U32 -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes, Maybe<&2, PKey>)
The cursor bounds both fixed keyword probes; short or unknown bodies are skipped.
def pr.opt source · line 187 · raw
@has:Bool -> @b:0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes -> Maybe<&1, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes>
def pr.path.done source · line 195 · raw
@+start:U32 -> @+end:U32 -> @+n:U32 -> @pax:Pax -> @r:Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes) -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Pst)
An empty value unsets the keyword, so the header's own name applies.
def pr.path source · line 200 · raw
@c:0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor -> @pax:Pax -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Pst)
def pr.size.valid source · line 204 · raw
@ok:Bool -> @c:0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor -> @+v:U32 -> @path:Maybe<&1, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes> -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Pst)
def pr.size.done source · line 211 · raw
@pax:Pax -> @r:Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Dec) -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Pst)
def pr.checked source · line 217 · raw
@r:Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Bool) -> @pax:Pax -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Pst)
def pr.skip source · line 225 · raw
@c:0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor -> @pax:Pax -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Pst)
def pr.value source · line 229 · raw
@pax:Pax -> @r:Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Maybe<&2, PKey>) -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Pst)
def pr.nl source · line 243 · raw
@pax:Pax -> @r:Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Maybe<&2, U32>) -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Pst)
def pr.close source · line 251 · raw
@limit:0x185ae03c75e3e75be1171471f68b43cb/bytes.CursorLimit -> @r:Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Pst) -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Pst)
def pr.body source · line 261 · raw
@pax:Pax -> @r:Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Maybe<&1, 0x185ae03c75e3e75be1171471f68b43cb/bytes.CursorLimit>) -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Pst)
def pr.len.valid source · line 269 · raw
@ok:Bool -> @c:0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor -> @+body:U32 -> @pax:Pax -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Pst)
def pr.len source · line 277 · raw
@+available:U32 -> @pax:Pax -> @r:Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Dec) -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Pst)
Length includes its digits, the space, the bounded body and its final newline.
def pr.more.if source · line 282 · raw
@done:Bool -> @c:0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor -> @+n:U32 -> @pax:Pax -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Pst)
def pr.more source · line 289 · raw
@pax:Pax -> @r:Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, U32) -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Pst)
def pr.run source · line 294 · raw
@fuel:Nat -> @r:Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Pst) -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Maybe<&1, Pax>)
Each record consumes at least three bytes; leave fuel for the end transition.
def pr.start source · line 309 · raw
@pax:Pax -> @r:Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, U32) -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Maybe<&1, Pax>)
def pr.parse source · line 314 · raw
@c:0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor -> @pax:Pax -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Maybe<&1, Pax>)
c is already bounded to exactly the PAX payload, without block padding.
def hdr.kind source · line 326 · raw
@+len:U32 -> @+sum:U32 -> @+ok:Bool -> @+size:U32 -> @+size_ok:Bool -> @r:Pair(Array<U32>, U32) -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes, Maybe<&2, Hdr>)
def hdr.size source · line 330 · raw
@+len:U32 -> @+i:U32 -> @+sum:U32 -> @+ok:Bool -> @r:Pair(Array<U32>, Pair(U32, Bool)) -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes, Maybe<&2, Hdr>)
def hdr.valid source · line 334 · raw
@ok:Bool -> @+len:U32 -> @+i:U32 -> @+sum:U32 -> @a:Array<U32> -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes, Maybe<&2, Hdr>)
def hdr.ck3 source · line 342 · raw
@+len:U32 -> @+i:U32 -> @+sum:U32 -> @+ck:U32 -> @+ok:Bool -> @+x:U32 -> @r:Pair(Array<U32>, U32) -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes, Maybe<&2, Hdr>)
The checksum's eight bytes count as spaces.
def hdr.ck2 source · line 346 · raw
@+len:U32 -> @+i:U32 -> @+sum:U32 -> @+ck:U32 -> @+ok:Bool -> @r:Pair(Array<U32>, U32) -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes, Maybe<&2, Hdr>)
def hdr.check source · line 350 · raw
@+len:U32 -> @+i:U32 -> @+sum:U32 -> @r:Pair(Array<U32>, Pair(U32, Bool)) -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes, Maybe<&2, Hdr>)
def hdr.zero source · line 354 · raw
@zero:Bool -> @+len:U32 -> @+i:U32 -> @+sum:U32 -> @a:Array<U32> -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes, Maybe<&2, Hdr>)
def hdr.sum source · line 361 · raw
@+len:U32 -> @+i:U32 -> @r:Pair(Array<U32>, U32) -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes, Maybe<&2, Hdr>)
def hdr.read source · line 366 · raw
@b:0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes -> @+i:U32 -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes, Maybe<&2, Hdr>)
Cursor.read establishes that all fixed offsets below belong to a complete block.
def zero.sum source · line 370 · raw
@+len:U32 -> @r:Pair(Array<U32>, U32) -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes, Maybe<&2, U32>)
def zero.read source · line 374 · raw
@b:0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes -> @+i:U32 -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes, Maybe<&2, U32>)
def name.of source · line 378 · raw
@path:Maybe<&1, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes> -> @a:Array<U32> -> @+i:U32 -> Pair(Array<U32>, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes)
def entry.named source · line 385 · raw
@+len:U32 -> @+pos:U32 -> @start:U32 -> @end:U32 -> @r:Pair(Array<U32>, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes) -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes)
def entry.name source · line 390 · raw
@c:0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor -> @path:Maybe<&1, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes> -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes)
The header begins one block before the payload cursor; no separate header index survives.
def file.data source · line 394 · raw
@+len:U32 -> @pos:U32 -> @start:U32 -> @end:U32 -> @+size:U32 -> @name:0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes -> @acc:List<&1, Entry> -> @r:Pair(Array<U32>, Array<U32>) -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, St)
def file.name source · line 398 · raw
@+size:U32 -> @acc:List<&1, Entry> -> @r:Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes) -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, St)
def entry.file source · line 403 · raw
@c:0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor -> @+size:U32 -> @pax:Pax -> @acc:List<&1, Entry> -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, St)
def dir.name source · line 407 · raw
@acc:List<&1, Entry> -> @r:Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes) -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, St)
def entry.dir source · line 412 · raw
@c:0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor -> @pax:Pax -> @acc:List<&1, Entry> -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, St)
Leaving the payload region skips a directory's data, as it does global PAX records.
def step.pax source · line 416 · raw
@acc:List<&1, Entry> -> @r:Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Maybe<&1, Pax>) -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, St)
def step.type source · line 426 · raw
@+t:U32 -> @c:0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor -> @+size:U32 -> @pax:Pax -> @acc:List<&1, Entry> -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, St)
'0'/NUL are files, '5' directories, 'x' local PAX and 'g' ignored global PAX. Links, devices, FIFOs, GNU extensions and all other types fail.
def frame.padded source · line 441 · raw
@outer:0x185ae03c75e3e75be1171471f68b43cb/bytes.CursorLimit -> @st:St -> @r:Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Bool) -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, St)
def frame.body source · line 449 · raw
@inner:0x185ae03c75e3e75be1171471f68b43cb/bytes.CursorLimit -> @outer:0x185ae03c75e3e75be1171471f68b43cb/bytes.CursorLimit -> @+padding:U32 -> @r:Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, St) -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, St)
def frame.payload source · line 453 · raw
@+t:U32 -> @+size:U32 -> @+padding:U32 -> @outer:0x185ae03c75e3e75be1171471f68b43cb/bytes.CursorLimit -> @pax:Pax -> @acc:List<&1, Entry> -> @r:Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Maybe<&1, 0x185ae03c75e3e75be1171471f68b43cb/bytes.CursorLimit>) -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, St)
def frame.region source · line 463 · raw
@+t:U32 -> @+size:U32 -> @+pd:U32 -> @pax:Pax -> @acc:List<&1, Entry> -> @r:Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Maybe<&1, 0x185ae03c75e3e75be1171471f68b43cb/bytes.CursorLimit>) -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, St)
First bound the complete padded body, then restrict PAX to the exact payload. Limits are left in reverse order; neither region slices or copies the backing buffer.
def step.fit source · line 471 · raw
@ok:Bool -> @+t:U32 -> @c:0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor -> @+size:U32 -> @+pd:U32 -> @pax:Pax -> @acc:List<&1, Entry> -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, St)
def step.pad source · line 478 · raw
@+t:U32 -> @c:0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor -> @+size:U32 -> @+ok:Bool -> @pax:Pax -> @acc:List<&1, Entry> -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, St)
def step.size source · line 483 · raw
@+t:U32 -> @c:0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor -> @+v:U32 -> @+ok:Bool -> @pax:Pax -> @acc:List<&1, Entry> -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, St)
A pending PAX size overrides the header field for every type, even when that field is malformed.
def step.hdr source · line 487 · raw
@ok:Bool -> @+t:U32 -> @c:0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor -> @+size:U32 -> @+size_ok:Bool -> @pax:Pax -> @acc:List<&1, Entry> -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, St)
def end.pax source · line 495 · raw
@pax:Pax -> @acc:List<&1, Entry> -> St
Two zero blocks are required and no local PAX records may remain pending.
def end.of source · line 503 · raw
@ok:Bool -> @pax:Pax -> @acc:List<&1, Entry> -> St
def end.sum source · line 510 · raw
@pax:Pax -> @acc:List<&1, Entry> -> @r:Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Maybe<&2, U32>) -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, St)
def step.zero source · line 518 · raw
@zero:Bool -> @+ok:Bool -> @+size:U32 -> @+size_ok:Bool -> @+t:U32 -> @c:0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor -> @pax:Pax -> @acc:List<&1, Entry> -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, St)
def step.read source · line 525 · raw
@pax:Pax -> @acc:List<&1, Entry> -> @r:Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, Maybe<&2, Hdr>) -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, St)
def step source · line 533 · raw
@c:0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor -> @pax:Pax -> @acc:List<&1, Entry> -> Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, St)
def run source · line 536 · raw
@fuel:Nat -> @r:Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Cursor, St) -> Maybe<&1, List<&1, Entry>>
def decode source · line 554 · raw
@archive:0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes -> Maybe<&1, List<&1, Entry>>
The entries in archive order. None for a bad header checksum, a malformed size or PAX record, an entry or its padding cut short, a missing end (two zero blocks), or any type but file, directory, and PAX records. Bytes after the end are ignored. fuel: each header step eats a block, so len / 512 + 2 steps are enough.
def put.str source · line 560 · raw
@s:String -> @a:Array<U32> -> @+j:U32 -> Array<U32>
def oct.put source · line 568 · raw
@n:Nat -> @a:Array<U32> -> @+j:U32 -> @+v:U32 -> Array<U32>
n octal digits of v ending at j, written back to front.
def dec.put source · line 576 · raw
@n:Nat -> @a:Array<U32> -> @+j:U32 -> @+v:U32 -> Array<U32>
n decimal digits of v ending at j, written back to front.
def digits.go source · line 583 · raw
@n:Nat -> @+v:U32 -> @+c:U32 -> U32
def digits source · line 591 · raw
@+v:U32 -> U32
The count of decimal digits in v.
def hdr.fields source · line 595 · raw
@+mode:U32 -> @+size:U32 -> @+t:U32 -> @a:Array<U32> -> Array<U32>
mode, uid 0, gid 0, size, mtime 0, the checksum as spaces, type, and the POSIX ustar magic.
def hdr.ck source · line 600 · raw
@r:Pair(Array<U32>, U32) -> Array<U32>
Six octal digits, NUL, space: the last space stays from the fields.
def hdr.of source · line 604 · raw
@+mode:U32 -> @+size:U32 -> @+t:U32 -> @r:Pair(Array<U32>, Array<U32>) -> Pair(Array<U32>, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes)
def hdr source · line 609 · raw
@src:Array<U32> -> @+n:U32 -> @+mode:U32 -> @+size:U32 -> @+t:U32 -> Pair(Array<U32>, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes)
A header block named by the first n bytes of src, handing src back.
def blk source · line 613 · raw
@b:0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes -> 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes
b with zero bytes up to the next whole block. Bytes past len are already 0, so only len and room grow.
def zeros source · line 618 · raw
@b:0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes -> @+n:U32 -> 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes
def rec.fin source · line 622 · raw
@+l:U32 -> @r:Pair(Array<U32>, Array<U32>) -> Pair(Array<U32>, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes)
def rec.len source · line 627 · raw
@+nl:U32 -> U32
A PAX path record's length: nl + 7 plus its own digits, found as in POSIX pax.
def pr.record source · line 632 · raw
@nb:Array<U32> -> @+nl:U32 -> Pair(Array<U32>, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes)
"<len> path=<name>\n".
def hdr.snd source · line 638 · raw
@r:Pair(Array<U32>, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes) -> 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes
def xhdr.of source · line 642 · raw
@+rl:U32 -> @b:0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes -> 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes
def enc.paxout source · line 646 · raw
@out:0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes -> @rec:0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes -> 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes
def enc.pax source · line 650 · raw
@out:0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes -> @r:Pair(Array<U32>, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes) -> Pair(Array<U32>, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes)
def enc.hdr source · line 654 · raw
@+dl:U32 -> @db:Array<U32> -> @out:0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes -> @r:Pair(Array<U32>, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes) -> 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes
def enc.main source · line 659 · raw
@+nl:U32 -> @+t:U32 -> @+mode:U32 -> @+dl:U32 -> @db:Array<U32> -> @r:Pair(Array<U32>, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes) -> 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes
The header keeps the name's first 100 bytes; a longer name rides in the PAX record before it.
def enc.long source · line 663 · raw
@long:Bool -> @nb:Array<U32> -> @+nl:U32 -> @out:0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes -> @+t:U32 -> @+mode:U32 -> @+dl:U32 -> @db:Array<U32> -> 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes
def enc.ok source · line 670 · raw
@ok:Bool -> @nb:Array<U32> -> @+nl:U32 -> @out:0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes -> @+t:U32 -> @+mode:U32 -> @+dl:U32 -> @db:Array<U32> -> Maybe<&1, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes>
def enc.room source · line 678 · raw
@+ol:U32 -> @+dl:U32 -> @+nl:U32 -> @+long:Bool -> Bool
Does an entry fit what is left of the U32 length, with room for the end blocks? Every step checks before it subtracts.
def enc.check source · line 689 · raw
@+t:U32 -> @+mode:U32 -> @+dl:U32 -> @db:Array<U32> -> @out:0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes -> @r:Pair(0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes, Maybe<&2, U32>) -> Maybe<&1, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes>
A name must be non-empty and hold no NUL, which the header's name field could not keep.
def enc source · line 696 · raw
@e:Entry -> @out:0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes -> Maybe<&1, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes>
def enc.end source · line 704 · raw
@m:Maybe<&1, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes> -> Maybe<&1, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes>
def enc.go source · line 711 · raw
@xs:List<&1, Entry> -> @m:Maybe<&1, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes> -> Maybe<&1, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes>
def encode source · line 726 · raw
@entries:List<&1, Entry> -> Maybe<&1, 0x185ae03c75e3e75be1171471f68b43cb/bytes.Bytes>
A POSIX ustar archive of the entries in order, ended by two zero blocks. Files are mode 0644 and directories 0755, with uid, gid, and mtime 0. A name over 100 bytes goes in a PAX path record. None when a name is empty or holds a NUL byte, or when the archive would pass 4 GiB (U32 lengths). ustar's 8 GiB size field holds any U32 length, so encode never needs a PAX size.