Wiki
Download
Manual
Eggs
API
Tests
Bugs
show
edit
You can edit this page using
wiki syntax
for markup.
Article contents:
[[tags: egg]] [[toc:]] == cbor Concise Binary Object Representation (CBOR) for CHICKEN 6. CBOR ([[https://www.rfc-editor.org/rfc/rfc8949|RFC 8949]]) is a compact binary data format with a JSON-like data model. The {{cbor}} library provides routines to read and write CBOR data on binary ports. It maps Scheme values to CBOR data items and back, and it writes SRFI-4 numeric vectors as typed arrays ([[https://www.rfc-editor.org/rfc/rfc8746|RFC 8746]]): one block of raw bytes, with no per-element conversion. The design follows the Haskell [[https://github.com/well-typed/cborg|cborg]] library: a low-level token layer, a generic term tree, and a mapping for native values on top. === Modules ; {{cbor}} : Scheme values to and from CBOR. Most programs need only this module. ; {{cbor-core}} : Low-level encoding and decoding of individual tokens. ; {{cbor-term}} : A generic tree that mirrors a CBOR data item exactly, and diagnostic notation. ; {{cbor-token}} : CBOR as a flat list of tokens, for testing and inspection. ; {{cbor-deflate}} : Compressed data items, using the bundled [[https://github.com/richgel999/miniz|miniz]]. === Module cbor ==== Reading and writing <procedure>(write-cbor OBJ [PORT])</procedure> Writes {{OBJ}} to {{PORT}} as one CBOR data item. {{PORT}} must accept binary output. <procedure>(read-cbor [PORT])</procedure> Reads one data item from {{PORT}}. Returns an eof object if {{PORT}} is already at its end. <procedure>(cbor->bytevector OBJ)</procedure> <procedure>(bytevector->cbor BYTEVECTOR)</procedure> Encode to, and decode from, a bytevector. {{bytevector->cbor}} signals an error if the bytevector holds anything after the first data item. <procedure>(write-cbor-file PATH OBJ)</procedure> <procedure>(read-cbor-file PATH)</procedure> Write and read a file holding one data item. The file starts with the self-describe tag 55799 (the bytes {{d9 d9 f7}}), which marks it as CBOR. <procedure>(call-with-cbor-output-file PATH PROC)</procedure> <procedure>(call-with-cbor-input-file PATH PROC)</procedure> Open {{PATH}} as a binary port and call {{PROC}} with the port. The output version writes the self-describe tag first; {{PROC}} should then write exactly one data item. <procedure>(write-cbor-sequence LIST [PORT])</procedure> <procedure>(read-cbor-sequence [PORT])</procedure> Write each element of {{LIST}} as a separate data item, and read all items up to the end of input, as a CBOR sequence ([[https://www.rfc-editor.org/rfc/rfc8742|RFC 8742]]). <procedure>(encode-value OBJ PORT)</procedure> <procedure>(decode-value DECODER)</procedure> The same mapping as {{write-cbor}} and {{read-cbor}}, for use together with the token-level procedures of {{cbor-core}}. <parameter>cbor-preferred-floats</parameter> When true, flonums are written in the shortest float width that holds them exactly (half, single or double). The default, {{#f}}, always writes doubles. ==== The mapping || Scheme || CBOR || | exact integer | major type 0 or 1; beyond 64 bits, bignum tags 2 and 3 | | flonum | double (or shortest exact width, see above) | | exact rational | tag 30, {{[numerator, denominator]}} | | {{#t}}, {{#f}} | true, false | | the void value | undefined | | {{cbor-null}} | null | | string | text string | | symbol | tag 39 (identifier) with a text string | | proper list | array | | improper list or pair | tag {{tag-scheme-pair}}, {{[items..., tail]}} | | vector | tag {{tag-scheme-vector}} with an array | | bytevector (also blob, u8vector) | byte string | | s8, u16, s16, u32, s32, u64, s64, f32 and f64 vectors | RFC 8746 typed array, in host byte order | | character | tag {{tag-scheme-char}} with its code point | | keyword | tag {{tag-scheme-keyword}} with a text string | | SRFI-69 hash table | map (read back with {{equal?}} hashing) | | {{cbor-tagged}} record | the given tag and value | | {{cbor-simple}} record | the given simple value | When reading, maps become SRFI-69 hash tables, typed arrays in either byte order become SRFI-4 vectors (half-precision arrays become f32vectors), the self-describe tag is skipped, and tags without a codec become {{cbor-tagged}} records. Circular lists and cyclic vectors cannot be written. The private tags {{tag-scheme-pair}}, {{tag-scheme-vector}}, {{tag-scheme-char}} and {{tag-scheme-keyword}} lie in the first-come-first-served range of the IANA tag registry. <constant>cbor-null</constant> <procedure>(cbor-null? OBJ)</procedure> The CBOR null value. <procedure>(make-cbor-tagged TAG VALUE)</procedure> <procedure>(cbor-tagged? OBJ)</procedure> <procedure>(cbor-tagged-tag TAGGED)</procedure> <procedure>(cbor-tagged-value TAGGED)</procedure> A tagged item whose tag has no codec. <procedure>(make-cbor-simple N)</procedure> <procedure>(cbor-simple? OBJ)</procedure> <procedure>(cbor-simple-value SIMPLE)</procedure> A simple value other than false, true, null and undefined. ==== Codecs A codec adds a Scheme type, tied to a CBOR tag. <procedure>(make-cbor-codec TAG PREDICATE ENCODER DECODER)</procedure> {{PREDICATE}} recognizes values of the type. {{ENCODER}} is called with three arguments: the value, a procedure that writes a nested Scheme value, and the output port (for writing tokens directly with {{cbor-core}}). It must write exactly one data item, the content of the tag; the tag itself is written before it. {{DECODER}} is called with the decoded content and returns the value. <procedure>(register-cbor-codec! CODEC)</procedure> Adds {{CODEC}} to the global registry, ahead of earlier codecs. <parameter>cbor-codecs</parameter> A list of codecs that take priority over the global registry, for use with {{parameterize}}. Built-in types are always handled first. <enscript highlight="scheme"> (define-record-type point (make-point x y) point? (x point-x) (y point-y)) (register-cbor-codec! (make-cbor-codec 1000001 point? (lambda (p emit port) (emit (list (point-x p) (point-y p)))) (lambda (content) (apply make-point content)))) </enscript> ==== Limits and errors <parameter>cbor-max-depth</parameter> Deepest nesting of arrays, maps and tags accepted when reading, and written when encoding (default 1024). <parameter>cbor-max-length</parameter> Largest string (in bytes) or array or map (in items) accepted when reading, or {{#f}} for no limit (the default). Very long byte strings are read in two steps, so a forged length in a small input cannot force a large allocation. Decoding errors signal a condition of kinds {{exn}} and {{cbor}}. The {{cbor}} part has the properties {{reason}} (one of {{eof}}, {{malformed}}, {{type}}, {{limit}}, {{utf8}}) and {{offset}} (the byte position in the input). === Module cbor-core Encoders take the value first and an optional output port: {{encode-head}}, {{encode-uint}}, {{encode-nint}}, {{encode-int}}, {{encode-bytes}} (with optional start and end), {{encode-bytes-begin}}, {{encode-string}}, {{encode-string-begin}}, {{encode-list-len}}, {{encode-list-begin}}, {{encode-map-len}}, {{encode-map-begin}}, {{encode-tag}}, {{encode-bool}}, {{encode-null}}, {{encode-undefined}}, {{encode-simple}}, {{encode-float16}}, {{encode-float32}}, {{encode-float64}}, {{encode-float}} (shortest exact width), {{encode-break}} and {{encode-encoded}} (pre-encoded bytes). Decoders take a decoder, made with {{(make-decoder [PORT])}}: {{peek-token-type}}, {{decode-uint}}, {{decode-nint}}, {{decode-int}}, {{decode-integer}} (also bignums), {{decode-bytes}}, {{decode-string}}, {{decode-bytes-indef}}, {{decode-string-indef}}, {{decode-list-len}}, {{decode-list-len-indef}}, {{decode-list-len-or-indef}}, {{decode-map-len}}, {{decode-map-len-indef}}, {{decode-map-len-or-indef}}, {{decode-tag}}, {{decode-bool}}, {{decode-null}}, {{decode-undefined}}, {{decode-simple}}, {{decode-float}}, {{decode-float-token}}, {{decode-break}}, {{decode-break-or}} and {{decode-skip}}. {{peek-token-type}} returns one of the symbols {{uint}}, {{nint}}, {{bytes}}, {{bytes-indef}}, {{string}}, {{string-indef}}, {{list-len}}, {{list-len-indef}}, {{map-len}}, {{map-len-indef}}, {{tag}}, {{bool}}, {{null}}, {{undefined}}, {{simple}}, {{float16}}, {{float32}}, {{float64}}, {{break}}, {{invalid}} or {{eof}}. Byte and text strings are decoded whole, whether definite or indefinite. Decoders that build nested items call {{decoder-enter!}} and {{decoder-leave!}} around each level so that {{cbor-max-depth}} applies. === Module cbor-term <procedure>(decode-term DECODER)</procedure> <procedure>(encode-term TERM [PORT])</procedure> Terms are a {{datatype}} with the variants {{term-int}}, {{term-bytes}}, {{term-bytes-indef}}, {{term-string}}, {{term-string-indef}}, {{term-list}}, {{term-list-indef}}, {{term-map}}, {{term-map-indef}} (pairs as {{(key . value)}}), {{term-tagged}}, {{term-bool}}, {{term-null}}, {{term-undefined}}, {{term-simple}}, {{term-half}}, {{term-float}} and {{term-double}}. Terms keep float widths and indefinite lengths, so re-encoding a decoded term gives back the original bytes whenever they were in preferred form. <procedure>(term->diagnostic TERM)</procedure> Returns the diagnostic notation of RFC 8949 section 8, for example {{"[1, [2, 3]]"}}. <procedure>(term=? TERM1 TERM2)</procedure> Structural equality that treats NaN as equal to itself. === Module cbor-token A {{datatype}} of tokens ({{tk-uint}}, {{tk-nint}}, {{tk-bytes}}, {{tk-bytes-begin}}, {{tk-string}}, {{tk-string-begin}}, {{tk-list-len}}, {{tk-list-begin}}, {{tk-map-len}}, {{tk-map-begin}}, {{tk-tag}}, {{tk-bool}}, {{tk-null}}, {{tk-undefined}}, {{tk-simple}}, {{tk-float16}}, {{tk-float32}}, {{tk-float64}}, {{tk-break}}), with {{write-token}}, {{write-tokens}}, {{read-token}}, {{read-tokens}} and {{token->list}}. === Module cbor-deflate Loading this module registers a compressed-item tag, {{tag-compressed}}. Its content is the array {{[1, length, data]}}: 1 names zlib (RFC 1950), {{length}} is the size of the uncompressed encoding, and {{data}} is a byte string holding the compressed encoding of one data item. Writers emit the data as an indefinite-length byte string of 1 MB chunks, so compression runs in bounded memory. {{read-cbor}} expands compressed items transparently. <procedure>(cbor-deflated OBJ)</procedure> Wraps {{OBJ}} so that it is written compressed. The wrapper may appear anywhere inside a larger value. <procedure>(write-cbor/compressed OBJ [PORT])</procedure> Writes {{OBJ}} as one compressed data item. <parameter>cbor-deflate-level</parameter> Compression level from 0 to 10 (default 6; 1 is fastest). <procedure>(deflate-bytevector BYTEVECTOR)</procedure> <procedure>(inflate-bytevector BYTEVECTOR LENGTH)</procedure> Compress to, and decompress from, a zlib stream. === Examples <enscript highlight="scheme"> (import cbor (srfi 4)) (write-cbor-file "weights.cbor" `((name . "layer1") (shape 256 784) (data . ,(make-f32vector (* 256 784) 0.5)))) (define checkpoint (read-cbor-file "weights.cbor")) (cdr (assq 'shape checkpoint)) ; => (256 784) </enscript> Python can read the same file with {{cbor2}}; the typed array comes back as a tagged byte string that {{numpy.frombuffer}} turns into an array. === Author [[/users/ivan-raikov|Ivan Raikov]] === License MIT === Version history ; 1.0 : Initial release
Description of your changes:
I would like to authenticate
Authentication
Username:
Password:
Spam control
What do you get when you subtract 22 from 3?