CBOR::Simple
NAME
CBOR::Simple - Simple codec for the CBOR serialization format
SYNOPSIS
use CBOR::Simple;
# Encode a Raku value to CBOR, or vice-versa
my $cbor = cbor-encode($value);
my $val1 = cbor-decode($cbor); # Fails if more data past first decoded value
my $val2 = cbor-decode($cbor, my $pos = 0); # Updates $pos after decoding first value
# By default, cbor-decode() marks partially corrupt parsed structures with
# Failure nodes at the point of corruption
my $bad = cbor-decode(buf8.new(0x81 xx 3)); # [[[Failure]]]
# Callers can instead force throwing exceptions on any error
my $*CBOR_SIMPLE_FATAL_ERRORS = True;
my $bad = cbor-decode(buf8.new(0x81 xx 3)); # BOOM!
# Decode CBOR into diagnostic text, used for checking encodings and complex structures
my $diag = cbor-diagnostic($cbor);
# Force the encoder to tag a value with a particular tag number
my $tagged = CBOR::Simple::Tagged.new(:$tag-number, :$value);
my $cbor = cbor-encode($tagged);DESCRIPTION
CBOR::Simple is an easy-to-use implementation of the core functionality of the CBOR serialization format, implementing the standard as of RFC 8949, plus a collection of common tag extensions as described below in TAG IMPLEMENTATION STATUS.
PERFORMANCE
CBOR::Simple is one of the fastest data structure serialization codecs available for Raku. It is comparable in round-trip speed to JSON::Fast for data structures that are the most JSON-friendly. For all other cases tested, CBOR::Simple produces smaller, higher fidelity encodings, faster. For more detail, and comparison with other Raku serialization codecs, see serializer-perf.
NYI
Currently known NOT to work:
Any tag marked 'β' (valid but not yet supported) or 'D' (deprecated spec) in the ENCODE or DECODE column of the Tag Status Details table below, or any tag not explicitly listed therein, will be treated as an opaque tagged value rather than treated as a native type.
Packed arrays of 128-bit floats (num128); these are not supported in Rakudo yet.
Encoding finite 16-bit floats (num16); encoding 16-bit NaN and Β±Inf, as well as decoding any num16 all work. This is a performance tradeoff rather than a technical limitation; detecting whether a finite num32 can be shrunk to 16 bits without losing information is costly and rarely results in space savings except in trivial cases (e.g. Nums containing only small integers).
TAG CONTENT STRICTNESS
When encoding, CBOR::Simple makes every attempt to encode tagged content strictly within the tag standards as written, always producing spec-compliant encoded values.
When decoding, CBOR::Simple will often slightly relax the allowed content types in tagged content, especially when later tag proposals made no change other than to extend the allowed content types and allocate a new tag number for that. In the extension case CBOR::Simple is likely to allow both the old and new tag to accept the same content domain when decoding.
For example, when encoding CBOR::Simple will always encode Instant or DateTime as a CBOR epoch-based date/time (tag 1), using standard integer or floating point content data. But when decoding, CBOR::Simple will accept any content that decodes properly as a Raku Real value -- and in particular will handle a CBOR Rational (tag 30) as another valid content type.
DATE, DATETIME, INSTANT
Raku's builtin time handling is richer than the default CBOR data model (though certain tag extensions improve this), so the following mappings apply:
Encoding
InstantandDateTimeare both written as tag 1 (epoch-based date/time) with integer (if lossless) or floating point content.Other
Dateishare written as tag 100 (RFC 8943 days since 1970-01-01).
Decoding
Tag 0 (date/time string) is parsed as a
DateTime.Tag 1 (epoch-based date/time) is parsed via
Instant.from-posix(), and handles any Real type in the tag content.Tag 100 (days since 1970-01-01) is parsed via
Date.new-from-daycount().Tag 1004 (date string) is parsed as a
Date.
UNDEFINED VALUES
CBOR's
nullis translated asAnyin Raku.CBOR's
undefinedis translated asMuin Raku.A real
Nilin an array (which must be bound, not assigned) is encoded as a CBOR Absent tag (31). Absent values will be recognized on decode as well, but since array contents are assigned into their parent array during decoding, aNilin an array will be translated toAnyby Raku's array assignment semantics.
OTHER SPECIAL CASES
To mark a substructure for lazy decoding (treating it as an opaque
Blobuntil explicitly decoded), use the tagged value idiom in the SYNOPSIS with:tag-number(24)(encoded CBOR value) or:tag-number(63)(encoded CBOR Sequence).CBOR strings claiming to be longer than
2βΆΒ³-1are treated as malformed.Bigfloats and decimal fractions (tags 4, 5, 264, 265) with very large exponents may result in numeric overflow when decoded.
Keys for Associative types are sorted using Raku's internal
sortmethod rather than the RFC 8949 default sort, because the latter is much slower.cbor-diagnostic()always adds encoding indicators for float values.
TAG IMPLEMENTATION STATUS
Note that unrecognized tags will decode to their contents wrapped with a CBOR::Simple::Tagged object that records its tag-number; check marks in the details table indicate conversion to/from an appropriate native Raku type rather than this default behavior.
AUTHOR
Geoffrey Broadwell [email protected]
COPYRIGHT AND LICENSE
Copyright 2021,2025 Geoffrey Broadwell
This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.