cbor.bend checks
raw source on the hub · import 0x728e6e26db44a143290d5b9563297a19/cbor.bend as Cbor
CBOR (RFC 8949) values encoded and decoded over Bytes. Source: https://github.com/paymog/bend-kit/tree/main/cbor
2 imports
import Base import 0x49814d83de8f70993a43e1002be29ecd/bytes.bend as Bytes
Types
type W64 source · line 6 · raw
Data
Raw words preserve CBOR integer and floating-point bit patterns.
W64@hi:U32 -> @lo:U32 -> W64
type Float source · line 9 · raw
Data
Half@bits:U32 -> Float
Single@bits:U32 -> Float
Double@bits:W64 -> Float
type Simple source · line 14 · raw
Data
SFalseSimple
STrueSimple
SNullSimple
SUndefinedSimple
Other@value:U32 -> Simple
type Val source · line 21 · raw
Type
UInt@value:W64 -> Val
NInt@value:W64 -> Val
BStr@value:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Val
TStr@value:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Val
Arr@items:List<&1, Val> -> Val
Obj@items:List<&1, Pair(Val, Val)> -> Val
Tag@number:W64 -> @value:Val -> Val
Sim@value:Simple -> Val
Flt@value:Float -> Val
type W source · line 32 · raw
Type
W@buf:Array<U32> -> @cap:U32 -> @n:U32 -> @word:U32 -> W
type Cp source · line 127 · raw
Data
RFC 3629 §4 validity, as in json: overlong forms, surrogates, and code points past U+10FFFF have width 0.
Cp@c:U32 -> @w:U32 -> Cp
type Item source · line 225 · raw
Type
IGuard aborts the encoding when a value has no CBOR form; IText carries a text string and its UTF-8 check.
IVal@value:Val -> Item
IArr@items:List<&1, Val> -> Item
IMap@items:List<&1, Pair(Val, Val)> -> Item
IArrLen@value:Pair(List<&1, Val>, Nat) -> Item
IMapLen@value:Pair(List<&1, Pair(Val, Val)>, Nat) -> Item
IGuard@ok:Bool -> Item
IText@value:Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, Bool) -> Item
type Hd source · line 452 · raw
Data
A head: major type, additional info, argument, and the index after it.
Hd@major:U32 -> @ai:U32 -> @arg:W64 -> @next:U32 -> Hd
type Frame source · line 542 · raw
Type
An open container. Items are reversed; left counts the definite items (or pairs) still due, this one included.
FArr@left:U32 -> @xs:List<&1, Val> -> Frame
FArrI@xs:List<&1, Val> -> Frame
FMap@left:U32 -> @kvs:List<&1, Pair(Val, Val)> -> Frame
FKey@left:U32 -> @kvs:List<&1, Pair(Val, Val)> -> @key:Val -> Frame
FMapI@kvs:List<&1, Pair(Val, Val)> -> Frame
FKeyI@kvs:List<&1, Pair(Val, Val)> -> @key:Val -> Frame
FTag@number:W64 -> Frame
type St source · line 552 · raw
Type
SHead reads an item at i; SChunk reads the next chunk of an indefinite string; SDone hands v to the open frame.
SHead@i:U32 -> @stack:List<&1, Frame> -> St
SChunk@i:U32 -> @text:Bool -> @chunks:List<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> @stack:List<&1, Frame> -> St
SDone@v:Val -> @i:U32 -> @stack:List<&1, Frame> -> St
SOk@v:Val -> St
SFailSt
Definitions
def grow.if source · line 34 · raw
@grow:Bool -> @buf:Array<U32> -> @+k:U32 -> Array<U32>
def put source · line 42 · raw
@full:Bool -> @buf:Array<U32> -> @+cap:U32 -> @+n:U32 -> @+word:U32 -> W
def finish.buf source · line 51 · raw
@full:Bool -> @cap:U32 -> @buf:Array<U32> -> @+k:U32 -> @+r:U32 -> @+word:U32 -> Array<U32>
def byte source · line 60 · raw
@o:W -> @+b:U32 -> W
def finish source · line 65 · raw
@o:W -> 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes
def empty source · line 71 · raw
W
def head.small source · line 74 · raw
@+major:U32 -> @+v:U32 -> @o:W -> W
def head.u32.sixteen source · line 77 · raw
@fits:Bool -> @+major:U32 -> @+v:U32 -> @o:W -> W
def head.u32.eight source · line 84 · raw
@fits:Bool -> @+major:U32 -> @+v:U32 -> @o:W -> W
def head.u32.small source · line 91 · raw
@small:Bool -> @+major:U32 -> @+v:U32 -> @o:W -> W
def head.u32 source · line 97 · raw
@+major:U32 -> @+v:U32 -> @o:W -> W
def raw.u32 source · line 100 · raw
@o:W -> @+v:U32 -> W
def uint.bytes.small source · line 103 · raw
@small:Bool -> @+major:U32 -> @+hi:U32 -> @+lo:U32 -> @o:W -> W
def uint.bytes source · line 110 · raw
@+major:U32 -> @v:W64 -> @o:W -> W
def raw.bytes.go source · line 114 · raw
@n:Nat -> @r:Pair(Array<U32>, U32) -> @+i:U32 -> @o:W -> W
def raw.bytes source · line 122 · raw
@b:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @o:W -> W
def pk.if source · line 130 · raw
@ok:Bool -> @a:Array<U32> -> @+i:U32 -> Pair(Array<U32>, U32)
def pk source · line 138 · raw
@a:Array<U32> -> @+end:U32 -> @+i:U32 -> Pair(Array<U32>, U32)
Byte i, or 256 at end, which no rule accepts.
def cont source · line 141 · raw
@+b:U32 -> Bool
def utf8.n source · line 144 · raw
@+b0:U32 -> @+b1:U32 -> @+b2:U32 -> @+b3:U32 -> Cp
def utf8.b3 source · line 156 · raw
@+b0:U32 -> @+b1:U32 -> @+b2:U32 -> @r:Pair(Array<U32>, U32) -> Pair(Array<U32>, Cp)
def utf8.b2 source · line 160 · raw
@+end:U32 -> @+i:U32 -> @+b0:U32 -> @+b1:U32 -> @r:Pair(Array<U32>, U32) -> Pair(Array<U32>, Cp)
def utf8.b1 source · line 164 · raw
@+end:U32 -> @+i:U32 -> @+b0:U32 -> @r:Pair(Array<U32>, U32) -> Pair(Array<U32>, Cp)
def utf8.cp source · line 168 · raw
@+i:U32 -> @r:Pair(Array<U32>, Cp) -> Pair(Array<U32>, Pair(U32, Bool))
def utf8.byte source · line 173 · raw
@ascii:Bool -> @a:Array<U32> -> @+end:U32 -> @+i:U32 -> @+b:U32 -> Pair(Array<U32>, Pair(U32, Bool))
def utf8.lead source · line 180 · raw
@+end:U32 -> @+i:U32 -> @r:Pair(Array<U32>, U32) -> Pair(Array<U32>, Pair(U32, Bool))
def utf8.more source · line 184 · raw
@go:Bool -> @a:Array<U32> -> @+end:U32 -> @+i:U32 -> Pair(Array<U32>, Pair(U32, Bool))
def utf8.step source · line 191 · raw
@ok:Bool -> @a:Array<U32> -> @+end:U32 -> @+i:U32 -> Pair(Array<U32>, Pair(U32, Bool))
def utf8.go source · line 199 · raw
@n:Nat -> @r:Pair(Array<U32>, Pair(U32, Bool)) -> @+end:U32 -> Pair(Array<U32>, Bool)
Each step eats a whole code point, so end - i steps reach end.
def utf8.check source · line 209 · raw
@a:Array<U32> -> @+i:U32 -> @+end:U32 -> Pair(Array<U32>, Bool)
Are bytes i until end well-formed UTF-8?
def text.fin source · line 212 · raw
@+len:U32 -> @r:Pair(Array<U32>, Bool) -> Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, Bool)
def text.check source · line 216 · raw
@b:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, Bool)
def simple.ok source · line 221 · raw
@+v:U32 -> Bool
Simple values 20..23 have their own constructors, 24..31 are reserved (RFC 8949 §3.3).
def vals.length.put source · line 233 · raw
@h:Val -> @r:Pair(List<&1, Val>, Nat) -> Pair(List<&1, Val>, Nat)
def pairs.length.put source · line 237 · raw
@h:Pair(Val, Val) -> @r:Pair(List<&1, Pair(Val, Val)>, Nat) -> Pair(List<&1, Pair(Val, Val)>, Nat)
def vals.length source · line 241 · raw
@xs:List<&1, Val> -> Pair(List<&1, Val>, Nat)
def pairs.length source · line 248 · raw
@xs:List<&1, Pair(Val, Val)> -> Pair(List<&1, Pair(Val, Val)>, Nat)
def size.arr source · line 255 · raw
@h:Val -> @r:Pair(Val, Nat) -> Pair(Val, Nat)
def size.obj source · line 263 · raw
@k:Val -> @v:Val -> @r:Pair(Val, Nat) -> Pair(Val, Nat)
def size.cons source · line 271 · raw
@hr:Pair(Val, Nat) -> @r:Pair(Val, Nat) -> Pair(Val, Nat)
def size.pair source · line 276 · raw
@kr:Pair(Val, Nat) -> @vr:Pair(Val, Nat) -> @r:Pair(Val, Nat) -> Pair(Val, Nat)
def size.tag source · line 282 · raw
@+number:W64 -> @r:Pair(Val, Nat) -> Pair(Val, Nat)
def size source · line 287 · raw
@v:Val -> Pair(Val, Nat)
v, and at least the number of encode.go steps it takes.
def encode.go source · line 317 · raw
@fuel:Nat -> @items:List<&1, Item> -> @o:W -> Maybe<&1, W>
fuel bounds the steps; size(v) gives enough, so the 0n arm is never reached.
def encode.done source · line 392 · raw
@r:Maybe<&1, W> -> Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes>
def encode.sized source · line 399 · raw
@r:Pair(Val, Nat) -> Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes>
def encode source · line 405 · raw
@v:Val -> Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes>
Definite lengths and the shortest head for every length, integer, and tag; floats keep their width. None when a TStr is not UTF-8, a Half has more than 16 bits, or Other is not a simple value 0..19 or 32..255.
def decode.other source · line 408 · raw
@ok:Bool -> @+value:U32 -> Maybe<&1, Val>
def decode.simple source · line 415 · raw
@+ai:U32 -> Maybe<&1, Val>
def decode.major7.arg source · line 428 · raw
@+ai:U32 -> @+arg:W64 -> Maybe<&1, Val>
def decode.major7 source · line 444 · raw
@small:Bool -> @+ai:U32 -> @+arg:W64 -> Maybe<&1, Val>
def hd.words source · line 456 · raw
@n:Nat -> @r:Pair(Array<U32>, U32) -> @+j:U32 -> @+hi:U32 -> @+lo:U32 -> @+major:U32 -> @+ai:U32 -> Pair(Array<U32>, Maybe<&2, Hd>)
n argument bytes from j, most significant first.
def hd.wide source · line 465 · raw
@ok:Bool -> @n:Nat -> @a:Array<U32> -> @+i:U32 -> @+major:U32 -> @+ai:U32 -> Pair(Array<U32>, Maybe<&2, Hd>)
def hd.arg source · line 473 · raw
@+ai:U32 -> @a:Array<U32> -> @+len:U32 -> @+i:U32 -> @+major:U32 -> Pair(Array<U32>, Maybe<&2, Hd>)
ai 24..27 take 1, 2, 4 or 8 more bytes; 28..30 are reserved; 31 is indefinite or break.
def hd.of source · line 492 · raw
@+len:U32 -> @+i:U32 -> @r:Pair(Array<U32>, U32) -> Pair(Array<U32>, Maybe<&2, Hd>)
def hd.read source · line 496 · raw
@ok:Bool -> @a:Array<U32> -> @+len:U32 -> @+i:U32 -> Pair(Array<U32>, Maybe<&2, Hd>)
def bstr.some source · line 503 · raw
@+n:U32 -> @r:Pair(Array<U32>, Array<U32>) -> Pair(Array<U32>, Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes>)
def bstr.copy source · line 507 · raw
@+n:U32 -> @+i:U32 -> @r:Pair(Array<U32>, Bool) -> Pair(Array<U32>, Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes>)
def bstr.valid source · line 515 · raw
@text:Bool -> @a:Array<U32> -> @+i:U32 -> @+end:U32 -> Pair(Array<U32>, Bool)
def bstr.fit source · line 522 · raw
@ok:Bool -> @+text:Bool -> @a:Array<U32> -> @+n:U32 -> @+i:U32 -> Pair(Array<U32>, Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes>)
def bstr.read source · line 530 · raw
@+text:Bool -> @+arg:W64 -> @a:Array<U32> -> @+len:U32 -> @+i:U32 -> Pair(Array<U32>, Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes>)
A definite string of arg bytes from i. None when it runs past len, or when text is not UTF-8.
def wrap source · line 534 · raw
@text:Bool -> @b:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Val
def item.str source · line 559 · raw
@+text:Bool -> @+i:U32 -> @stack:List<&1, Frame> -> @r:Pair(Array<U32>, Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes>) -> Pair(Array<U32>, St)
def item.empty source · line 568 · raw
@map:Bool -> @+i:U32 -> @stack:List<&1, Frame> -> St
def item.push source · line 575 · raw
@map:Bool -> @+n:U32 -> @+i:U32 -> @stack:List<&1, Frame> -> St
def item.open source · line 582 · raw
@empty:Bool -> @+map:Bool -> @+n:U32 -> @+i:U32 -> @stack:List<&1, Frame> -> St
def item.count source · line 589 · raw
@ok:Bool -> @+map:Bool -> @+n:U32 -> @+i:U32 -> @stack:List<&1, Frame> -> St
def item.len source · line 597 · raw
@+map:Bool -> @+arg:W64 -> @+len:U32 -> @+i:U32 -> @stack:List<&1, Frame> -> St
Every item takes a byte, so a count past the bytes left is malformed; this also keeps it in a U32.
def item.simple source · line 601 · raw
@m:Maybe<&1, Val> -> @+i:U32 -> @stack:List<&1, Frame> -> St
def item.def source · line 608 · raw
@+major:U32 -> @+ai:U32 -> @+arg:W64 -> @+i:U32 -> @a:Array<U32> -> @+len:U32 -> @stack:List<&1, Frame> -> Pair(Array<U32>, St)
def brk.fr source · line 628 · raw
@fr:Frame -> @+i:U32 -> @rest:List<&1, Frame> -> St
A break closes the innermost indefinite array, or map with no key pending; anywhere else it is malformed.
def brk source · line 645 · raw
@stack:List<&1, Frame> -> @+i:U32 -> St
def item.indef source · line 653 · raw
@+major:U32 -> @+i:U32 -> @stack:List<&1, Frame> -> St
ai 31: indefinite string, array, or map, or (major 7) a break. Majors 0, 1 and 6 have no indefinite form.
def item.hd source · line 668 · raw
@indef:Bool -> @+major:U32 -> @+ai:U32 -> @+arg:W64 -> @+i:U32 -> @a:Array<U32> -> @+len:U32 -> @stack:List<&1, Frame> -> Pair(Array<U32>, St)
def step.head source · line 675 · raw
@stack:List<&1, Frame> -> @+len:U32 -> @r:Pair(Array<U32>, Maybe<&2, Hd>) -> Pair(Array<U32>, St)
def chunk.str source · line 683 · raw
@+text:Bool -> @chunks:List<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> @+i:U32 -> @stack:List<&1, Frame> -> @r:Pair(Array<U32>, Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes>) -> Pair(Array<U32>, St)
def chunk.more source · line 692 · raw
@ok:Bool -> @+text:Bool -> @chunks:List<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> @+arg:W64 -> @+i:U32 -> @a:Array<U32> -> @+len:U32 -> @stack:List<&1, Frame> -> Pair(Array<U32>, St)
def chunk.end source · line 700 · raw
@stop:Bool -> @ok:Bool -> @+text:Bool -> @chunks:List<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> @+arg:W64 -> @+i:U32 -> @a:Array<U32> -> @+len:U32 -> @stack:List<&1, Frame> -> Pair(Array<U32>, St)
Each chunk is a definite string of the same major type, UTF-8 by itself for text (RFC 8949 §3.2.3).
def step.chunk source · line 707 · raw
@+text:Bool -> @chunks:List<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> @stack:List<&1, Frame> -> @+len:U32 -> @r:Pair(Array<U32>, Maybe<&2, Hd>) -> Pair(Array<U32>, St)
def done.arr source · line 715 · raw
@last:Bool -> @+left:U32 -> @xs:List<&1, Val> -> @+i:U32 -> @rest:List<&1, Frame> -> St
def done.map source · line 722 · raw
@last:Bool -> @+left:U32 -> @kvs:List<&1, Pair(Val, Val)> -> @+i:U32 -> @rest:List<&1, Frame> -> St
def done.fr source · line 729 · raw
@fr:Frame -> @v:Val -> @+i:U32 -> @rest:List<&1, Frame> -> St
def done.top source · line 746 · raw
@end:Bool -> @v:Val -> St
def done source · line 754 · raw
@stack:List<&1, Frame> -> @v:Val -> @+i:U32 -> @+len:U32 -> St
A finished top-level item must end the input.
def run source · line 761 · raw
@fuel:Nat -> @r:Pair(Array<U32>, St) -> @+len:U32 -> Maybe<&1, Val>
def decode source · line 783 · raw
@b:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Maybe<&1, Val>
One well-formed data item (RFC 8949 §3, Appendix C) filling b. Indefinite strings, arrays and maps come back definite, with chunks joined. None for truncation, reserved ai 28..30, a misplaced break or indefinite form, a simple value 0..31 in two bytes, text that is not UTF-8, or trailing bytes. fuel: a head or chunk eats a byte, and each SDone step follows one, so 2 * len + 2 steps are enough.