core/encoding/cbor
encoding_cbor
Types
37Add
Add :: enum u8 {
False = 20,
True = 21,
Nil = 22,
Undefined = 23,
One_Byte = 24,
Two_Bytes = 25,
Four_Bytes = 26,
Eight_Bytes = 27,
Length_Unknown = 31,
Break = Length_Unknown,
}SourceThe lower 3 bits of the header which denotes additional information for the type of value.
Array
Array :: []ValueSourceAtom
Atom :: SimpleSourceBytes
Bytes :: []byteSourceDecode_Data_Error
Decode_Data_Error :: enum int {
None = 0,
Bad_Major = 1, // An invalid major type was encountered.
Bad_Argument = 2, // A general unexpected value (most likely invalid additional info in header).
Bad_Tag_Value = 3, // When the type of value for the given tag is not valid.
Nested_Indefinite_Length = 4, // When an streamed/indefinite length container nests another, this is not allowed.
Nested_Tag = 5, // When a tag's value is another tag, this is not allowed.
Length_Too_Big = 6, // When the length of a container (map, array, bytes, string) is more than `max(int)`.
Disallowed_Streaming = 7, // When the `.Disallow_Streaming` flag is set and a streaming header is encountered.
Break = 8, // When the `break` header was found without any stream to break off.
}SourceDecode_Error
Decode_Error :: union {
io.Error,
mem.Allocator_Error,
Decode_Data_Error,
}SourceDecoder
Decoder :: struct {
// The max amount of bytes allowed to pre-allocate when `.Trusted_Input` is not set on the
// flags.
max_pre_alloc: int,
flags: Decoder_Flags,
reader: io.Reader,
}SourceDecoder_Flag
Decoder_Flag :: enum int {
// Rejects (with an error `.Disallowed_Streaming`) when a streaming CBOR header is encountered.
Disallow_Streaming = 0,
// Pre-allocates buffers and containers with the size that was set in the CBOR header.
// This should only be enabled when you control both ends of the encoding, if you don't,
// attackers can craft input that causes massive (`max(u64)`) byte allocations for a few bytes of
// CBOR.
Trusted_Input = 1,
// Makes the decoder shrink of excess capacity from allocated buffers/containers before returning.
Shrink_Excess = 2,
}SourceDecoder_Flags
Decoder_Flags :: bit_set[Decoder_Flag; 0..2]SourceEncode_Data_Error
Encode_Data_Error :: enum int {
None = 0,
Invalid_Simple = 1, // When a simple is being encoded that is out of the range `0..=19` and `32..=max(u8)`.
Int_Too_Big = 2, // When an int is being encoded that is larger than `max(u64)` or smaller than `min(u64)`.
Bad_Tag_Value = 3, // When the type of value is not supported by the tag implementation.
}SourceEncode_Error
Encode_Error :: union {
io.Error,
mem.Allocator_Error,
Encode_Data_Error,
}SourceEncoder
Encoder :: struct {
flags: Encoder_Flags,
writer: io.Writer,
temp_allocator: runtime.Allocator,
}SourceEncoder_Flag
Encoder_Flag :: enum int {
// CBOR defines a tag header that also acts as a file/binary header,
// this way decoders can check the first header of the binary and see if it is CBOR.
Self_Described_CBOR = 0,
// Integers are stored in the smallest integer type it fits.
// This involves checking each int against the max of all its smaller types.
Deterministic_Int_Size = 1,
// Floats are stored in the smallest size float type without losing precision.
// This involves casting each float down to its smaller types and checking if it changed.
Deterministic_Float_Size = 2,
// Sort maps by their keys in bytewise lexicographic order of their deterministic encoding.
// NOTE: In order to do this, all keys of a map have to be pre-computed, sorted, and
// then written, this involves temporary allocations for the keys and a copy of the map itself.
Deterministic_Map_Sorting = 3,
}SourceEncoder_Flags
Encoder_Flags :: bit_set[Encoder_Flag; 0..3]SourceHeader
Header :: enum u8 {
U8 = (u8(Major.Unsigned) << 5) | u8(Add.One_Byte),
U16 = (u8(Major.Unsigned) << 5) | u8(Add.Two_Bytes),
U32 = (u8(Major.Unsigned) << 5) | u8(Add.Four_Bytes),
U64 = (u8(Major.Unsigned) << 5) | u8(Add.Eight_Bytes),
Neg_U8 = (u8(Major.Negative) << 5) | u8(Add.One_Byte),
Neg_U16 = (u8(Major.Negative) << 5) | u8(Add.Two_Bytes),
Neg_U32 = (u8(Major.Negative) << 5) | u8(Add.Four_Bytes),
Neg_U64 = (u8(Major.Negative) << 5) | u8(Add.Eight_Bytes),
False = (u8(Major.Other) << 5) | u8(Add.False),
True = (u8(Major.Other) << 5) | u8(Add.True),
Nil = (u8(Major.Other) << 5) | u8(Add.Nil),
Undefined = (u8(Major.Other) << 5) | u8(Add.Undefined),
Simple = (u8(Major.Other) << 5) | u8(Add.One_Byte),
F16 = (u8(Major.Other) << 5) | u8(Add.Two_Bytes),
F32 = (u8(Major.Other) << 5) | u8(Add.Four_Bytes),
F64 = (u8(Major.Other) << 5) | u8(Add.Eight_Bytes),
Break = (u8(Major.Other) << 5) | u8(Add.Break),
}SourceKnown/common headers are defined, undefined headers can still be valid. Higher 3 bits is for the major type and lower 5 bits for the additional information.
Major
Major :: enum u8 {
Unsigned = 0,
Negative = 1,
Bytes = 2,
Text = 3,
Array = 4,
Map = 5,
Tag = 6,
Other = 7,
}SourceThe higher 3 bits of the header which denotes what type of value it is.
Map
Map :: []Map_EntrySourceMap_Entry
Map_Entry :: struct {
key: Value,
value: Value,
}SourceMarshal_Data_Error
Marshal_Data_Error :: enum int {
None = 0,
Invalid_CBOR_Tag = 1, // When the struct tag `cbor_tag:""` is not a registered name or number.
}SourceMarshal_Error
Marshal_Error :: union {
io.Error,
mem.Allocator_Error,
Encode_Data_Error,
Marshal_Data_Error,
Maybe(Unsupported_Type_Error),
}SourceNegative_U16
Negative_U16 :: u16SourceNegative_U32
Negative_U32 :: u32SourceNegative_U64
Negative_U64 :: u64SourceNegative_U8
Negative_U8 :: u8SourceActual value is -1 - x (be careful of overflows).
Nil
Nil :: rawptrSourceSimple
Simple :: u8SourceA distinct atom-like number, range from 0..=19 and 32..=max(u8).
Tag
Tag :: struct {
number: Tag_Number,
value: Value,
}SourceTag_Implementation
Tag_Implementation :: struct {
data: rawptr,
unmarshal: Tag_Unmarshal_Proc,
marshal: Tag_Marshal_Proc,
}SourceA tag implementation that handles marshals and unmarshals for the tag it is registered on.
Tag_Marshal_Proc
Tag_Marshal_Proc :: proc(self: ^Tag_Implementation, e: Encoder, v: any) -> (Marshal_Error)SourceProcedure responsible for marshalling the tag in the given any into the given encoder.
Tag_Number
Tag_Number :: u64SourceTag_Unmarshal_Proc
Tag_Unmarshal_Proc :: proc(self: ^Tag_Implementation, d: Decoder, tag_nr: Tag_Number, v: any) -> (Unmarshal_Error)SourceProcedure responsible for umarshalling the tag out of the reader into the given any.
Text
Text :: stringSourceUndefined
Undefined :: rawptrSourceUnmarshal_Data_Error
Unmarshal_Data_Error :: enum int {
None = 0,
Invalid_Parameter = 1, // When the given `any` can not be unmarshalled into.
Non_Pointer_Parameter = 2, // When the given `any` is not a pointer.
}SourceUnmarshal_Error
Unmarshal_Error :: union {
io.Error,
mem.Allocator_Error,
Decode_Data_Error,
Unmarshal_Data_Error,
Maybe(Unsupported_Type_Error),
}SourceUnsupported_Type_Error
Unsupported_Type_Error :: struct {
id: typeid,
hdr: Header,
add: Add,
}SourceError that is returned when a type couldn't be marshalled into or out of, as much information as possible/available is added.
Value
Value :: union {
u8,
u16,
u32,
u64,
Negative_U8,
Negative_U16,
Negative_U32,
Negative_U64,
// Pointers so the size of the Value union stays small.
^Bytes,
^Text,
^Array,
^Map,
^Tag,
Simple,
f16,
f32,
f64,
bool,
Undefined,
Nil,
}SourceConstants
20DEFAULT_MAX_PRE_ALLOC
DEFAULT_MAX_PRE_ALLOC :: KilobyteSourceThe default maximum amount of bytes to allocate on a buffer/container at once to prevent malicious input from causing massive allocations.
ENCODE_FULLY_DETERMINISTIC
ENCODE_FULLY_DETERMINISTIC :: Encoder_Flags = Encoder_Flags{.Deterministic_Int_Size, .Deterministic_Float_Size, .Deterministic_Map_Sorting}SourceFlags for fully deterministic output (if you are not using streaming/indeterminate length).
ENCODE_SMALL
ENCODE_SMALL :: Encoder_Flags = Encoder_Flags{.Deterministic_Int_Size, .Deterministic_Float_Size}SourceFlags for the smallest encoding output.
INITIALIZE_DEFAULT_TAGS
INITIALIZE_DEFAULT_TAGS :: _ = #config(CBOR_INITIALIZE_DEFAULT_TAGS, !ODIN_DEFAULT_TO_PANIC_ALLOCATOR && !ODIN_DEFAULT_TO_NIL_ALLOCATOR)SourceControls initialization of default tag implementations.
INITIAL_STREAMED_BYTES_CAPACITY
INITIAL_STREAMED_BYTES_CAPACITY :: 16SourceIf we are decoding a stream of either text or bytes, the initial capacity will be this value.
INITIAL_STREAMED_CONTAINER_CAPACITY
INITIAL_STREAMED_CONTAINER_CAPACITY :: 8SourceIf we are decoding a stream of either a map or list, the initial capacity will be this value.
TAG_BASE64_ID
TAG_BASE64_ID :: "base64"SourceTAG_BASE64_NR
TAG_BASE64_NR :: 34SourceThe contents of this tag are base64 encoded during marshal and decoded during unmarshal. Use the struct tag cbor_tag:"34" or cbor_tag:"base64" to have your field string or bytes field en/decoded as base64.
TAG_CBOR_ID
TAG_CBOR_ID :: "cbor"SourceTAG_CBOR_NR
TAG_CBOR_NR :: 24SourceTAG_DECIMAL_FRACTION :: 4 // NOTE: We could probably implement this with math/fixed. Sometimes it is beneficial to carry an embedded CBOR data item that is not meant to be decoded immediately at the time the enclosing data item is being decoded. Tag number 24 (CBOR data item) can be used to tag the embedded byte string as a single data item encoded in CBOR format. Use the struct tag cbor_tag:"24" or cbor_tag:"cbor" to keep a non-decoded field (string or bytes) of raw CBOR.
TAG_EPOCH_TIME_ID
TAG_EPOCH_TIME_ID :: "epoch"SourceTAG_EPOCH_TIME_NR
TAG_EPOCH_TIME_NR :: 1SourceTags defined in RFC 7049 that we provide implementations for. UTC time in seconds, unmarshalled into a core:time time.Time or integer. Use the struct tag cbor_tag:"1" or cbor_tag:"epoch" to have your time.Time field en/decoded as epoch time.
TAG_NEGATIVE_BIG_NR
TAG_NEGATIVE_BIG_NR :: 3SourceUsing core:math/big, big integers are properly encoded and decoded during marshal and unmarshal. These fields use this tag by default, no struct tag required.
TAG_OBJECT_TYPE
TAG_OBJECT_TYPE :: 1010SourceA tag that is used to assign a textual type to the object following it. The tag's value must be an array of 2 items, where the first is text (describing the following type) and the second is any valid CBOR value.
See the registration: https://datatracker.ietf.org/doc/draft-rundgren-cotx/05/
We use this in Odin to marshal and unmarshal unions.
TAG_SELF_DESCRIBED_CBOR
TAG_SELF_DESCRIBED_CBOR :: 55799SourceA tag that is used to detect the contents of a binary buffer (like a file) are CBOR. This tag would wrap everything else, decoders can then check for this header and see if the given content is definitely CBOR. Added by the encoder if it has the flag .Self_Described_CBOR, decoded by default.
TAG_UNSIGNED_BIG_NR
TAG_UNSIGNED_BIG_NR :: 2SourceUsing core:math/big, big integers are properly encoded and decoded during marshal and unmarshal. These fields use this tag by default, no struct tag required.
decode
decode :: decode_fromSourceencode
encode :: encode_intoSourceencode_stream_array_item
encode_stream_array_item :: encodeSourcemarshal
marshal :: marshal_intoSourceVariables
3_tag_implementations_id
_tag_implementations_id :: map[string]Tag_ImplementationSourceSame as the number implementations but friendlier to use as a struct tag. Instead of cbor_tag:"34" you can use cbor_tag:"base64".
_tag_implementations_nr
_tag_implementations_nr :: map[Tag_Number]Tag_ImplementationSourceWhen encountering a tag in the CBOR being unmarshalled, the implementation is used to unmarshal it. When encountering a struct tag like cbor_tag:"Tag_Number", the implementation is used to marshal it.
_tag_implementations_type
_tag_implementations_type :: map[typeid]Tag_ImplementationSourceTag implementations that are always used by a type, if that type is encountered in marshal it will rely on the implementation to marshal it.
This is good for types that don't make sense or can't marshal in its default form.
Procedures
109_assign_bool
_assign_bool :: proc(val: any, b: bool) -> (bool)Source_assign_float
_assign_float :: proc(val: any, f: T) -> (bool)Source_assign_int
_assign_int :: proc(val: any, i: T) -> (bool)Source_decode_array
_decode_array :: proc(d: Decoder, add: Add, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (v: Array, err: Decode_Error)Source_decode_array_ptr
_decode_array_ptr :: proc(d: Decoder, add: Add, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (v: ^Array, err: Decode_Error)Source_decode_bytes
_decode_bytes :: proc(d: Decoder, add: Add, type: Major, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (v: Bytes, err: Decode_Error)Source_decode_bytes_ptr
_decode_bytes_ptr :: proc(d: Decoder, add: Add, type: Major, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (v: ^Bytes, err: Decode_Error)Source_decode_f16
_decode_f16 :: proc(r: io.Reader) -> (v: f16, err: io.Error)Source_decode_f32
_decode_f32 :: proc(r: io.Reader) -> (v: f32, err: io.Error)Source_decode_f64
_decode_f64 :: proc(r: io.Reader) -> (v: f64, err: io.Error)Source_decode_from_decoder
_decode_from_decoder :: proc(d: Decoder, hdr: Header, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (v: Value, err: Decode_Error)Source_decode_header
_decode_header :: proc(r: io.Reader) -> (hdr: Header, err: io.Error)Source_decode_len_container
_decode_len_container :: proc(d: Decoder, add: Add) -> (n: int, scap: int, err: Decode_Error)SourceFor Array and Map types: Decodes the number of items the header says follows. If the number is not specified -1 is returned and streaming should be initiated. A suitable starting capacity is also returned for a buffer that is allocated up the stack.
_decode_len_str
_decode_len_str :: proc(d: Decoder, add: Add) -> (n: int, scap: int, err: Decode_Error)SourceFor Bytes and Text strings: Decodes the number of items the header says follows. If the number is not specified -1 is returned and streaming should be initiated. A suitable starting capacity is also returned for a buffer that is allocated up the stack.
_decode_map
_decode_map :: proc(d: Decoder, add: Add, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (v: Map, err: Decode_Error)Source_decode_map_ptr
_decode_map_ptr :: proc(d: Decoder, add: Add, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (v: ^Map, err: Decode_Error)Source_decode_simple
_decode_simple :: proc(r: io.Reader) -> (v: Simple, err: io.Error)Source_decode_tag
_decode_tag :: proc(d: Decoder, add: Add, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (v: Maybe(Tag), err: Decode_Error)Source_decode_tag_ptr
_decode_tag_ptr :: proc(d: Decoder, add: Add, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (v: Value, err: Decode_Error)Source_decode_text
_decode_text :: proc(d: Decoder, add: Add, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (v: Text, err: Decode_Error)Source_decode_text_ptr
_decode_text_ptr :: proc(d: Decoder, add: Add, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (v: ^Text, err: Decode_Error)Source_decode_tiny_simple
_decode_tiny_simple :: proc(add: Add) -> (Decode_Data_Error, Simple)Source_decode_tiny_u8
_decode_tiny_u8 :: proc(additional: Add) -> (Decode_Data_Error, u8)Source_decode_u16
_decode_u16 :: proc(r: io.Reader) -> (v: u16, err: io.Error)Source_decode_u32
_decode_u32 :: proc(r: io.Reader) -> (v: u32, err: io.Error)Source_decode_u64
_decode_u64 :: proc(r: io.Reader) -> (v: u64, err: io.Error)Source_decode_u8
_decode_u8 :: proc(r: io.Reader) -> (v: u8, err: io.Error)Source_decode_uint_as_u64
_decode_uint_as_u64 :: proc(r: io.Reader, add: Add) -> (nr: u64, err: Decode_Error)Source_encode_array
_encode_array :: proc(e: Encoder, arr: Array) -> (Encode_Error)Source_encode_bool
_encode_bool :: proc(w: io.Writer, v: bool) -> (err: io.Error)Source_encode_bytes
_encode_bytes :: proc(e: Encoder, val: Bytes, major: Major) -> (err: Encode_Error)Source_encode_deterministic_f32
_encode_deterministic_f32 :: proc(w: io.Writer, v: f32) -> (io.Error)Source_encode_deterministic_f64
_encode_deterministic_f64 :: proc(w: io.Writer, v: f64) -> (io.Error)Source_encode_deterministic_negative
_encode_deterministic_negative :: proc(w: io.Writer, v: T) -> (Encode_Error)Source_encode_deterministic_u128
_encode_deterministic_u128 :: proc(w: io.Writer, v: u128, major: Major) -> (Encode_Error)Source_encode_deterministic_u16
_encode_deterministic_u16 :: proc(w: io.Writer, v: u16, major: Major) -> (Encode_Error)Source_encode_deterministic_u32
_encode_deterministic_u32 :: proc(w: io.Writer, v: u32, major: Major) -> (Encode_Error)Source_encode_deterministic_u64
_encode_deterministic_u64 :: proc(w: io.Writer, v: u64, major: Major) -> (Encode_Error)Source_encode_f16
_encode_f16 :: proc(w: io.Writer, v: f16) -> (err: io.Error)Source_encode_f32
_encode_f32 :: proc(e: Encoder, v: f32) -> (io.Error)Source_encode_f32_exact
_encode_f32_exact :: proc(w: io.Writer, v: f32) -> (err: io.Error)Source_encode_f64
_encode_f64 :: proc(e: Encoder, v: f64) -> (io.Error)Source_encode_f64_exact
_encode_f64_exact :: proc(w: io.Writer, v: f64) -> (err: io.Error)Source_encode_map
_encode_map :: proc(e: Encoder, m: Map) -> (err: Encode_Error)Source_encode_nil
_encode_nil :: proc(w: io.Writer) -> (io.Error)Source_encode_simple
_encode_simple :: proc(w: io.Writer, v: Simple) -> (err: Encode_Error)Source_encode_tag
_encode_tag :: proc(e: Encoder, val: Tag) -> (Encode_Error)Source_encode_text
_encode_text :: proc(e: Encoder, val: Text) -> (Encode_Error)Source_encode_u16
_encode_u16 :: proc(e: Encoder, v: u16, major: Major) -> (Encode_Error)Source_encode_u16_exact
_encode_u16_exact :: proc(w: io.Writer, v: u16, major: Major) -> (err: io.Error)Source_encode_u32
_encode_u32 :: proc(e: Encoder, v: u32, major: Major) -> (Encode_Error)Source_encode_u32_exact
_encode_u32_exact :: proc(w: io.Writer, v: u32, major: Major) -> (err: io.Error)Source_encode_u64
_encode_u64 :: proc(e: Encoder, v: u64, major: Major) -> (Encode_Error)Source_encode_u64_exact
_encode_u64_exact :: proc(w: io.Writer, v: u64, major: Major) -> (err: io.Error)Source_encode_u8
_encode_u8 :: proc(w: io.Writer, v: u8, major: Major) -> (err: io.Error)Source_encode_undefined
_encode_undefined :: proc(w: io.Writer) -> (io.Error)Source_header_split
_header_split :: proc(hdr: Header) -> (Add, Major)Source_i128_to_uint
_i128_to_uint :: proc(v: i128) -> (u: u64, m: Major, err: Encode_Data_Error)Source_i16_to_uint
_i16_to_uint :: proc(v: i16) -> (u: u16, m: Major)Source_i32_to_uint
_i32_to_uint :: proc(v: i32) -> (u: u32, m: Major)Source_i64_to_uint
_i64_to_uint :: proc(v: i64) -> (u: u64, m: Major)Source_i8_to_uint
_i8_to_uint :: proc(v: i8) -> (u: u8, m: Major)Source_marshal_into_encoder
_marshal_into_encoder :: proc(e: Encoder, v: any, ti: ^runtime.Type_Info) -> (err: Marshal_Error)Source_u128_to_u64
_u128_to_u64 :: proc(v: u128) -> (Encode_Data_Error, u64)Source_unmarshal_any_ptr
_unmarshal_any_ptr :: proc(
d: Decoder,
v: any,
hdr: Maybe(Header),
allocator: mem.Allocator = context.allocator,
temp_allocator: _ = context.temp_allocator,
loc: _ = #caller_location,
) -> (Unmarshal_Error)Source_unmarshal_array
_unmarshal_array :: proc(
d: Decoder,
v: any,
ti: ^reflect.Type_Info,
hdr: Header,
add: Add,
allocator: mem.Allocator = context.allocator,
loc: _ = #caller_location,
) -> (err: Unmarshal_Error)Source_unmarshal_bytes
_unmarshal_bytes :: proc(
d: Decoder,
v: any,
ti: ^reflect.Type_Info,
hdr: Header,
add: Add,
allocator: mem.Allocator = context.allocator,
loc: _ = #caller_location,
) -> (err: Unmarshal_Error)Source_unmarshal_map
_unmarshal_map :: proc(
d: Decoder,
v: any,
ti: ^reflect.Type_Info,
hdr: Header,
add: Add,
allocator: mem.Allocator = context.allocator,
loc: _ = #caller_location,
) -> (err: Unmarshal_Error)Source_unmarshal_string
_unmarshal_string :: proc(
d: Decoder,
v: any,
ti: ^reflect.Type_Info,
hdr: Header,
add: Add,
allocator: mem.Allocator = context.allocator,
temp_allocator: _ = context.temp_allocator,
loc: _ = #caller_location,
) -> (err: Unmarshal_Error)Source_unmarshal_union
_unmarshal_union :: proc(d: Decoder, v: any, ti: ^reflect.Type_Info, hdr: Header, loc = #caller_location) -> (err: Unmarshal_Error)SourceUnmarshal into a union, based on the TAG_OBJECT_TYPE tag of the spec, it denotes a tag which contains an array of exactly two elements, the first is a textual representation of the following CBOR value's type.
_unmarshal_value
_unmarshal_value :: proc(
d: Decoder,
v: any,
hdr: Header,
allocator: mem.Allocator = context.allocator,
temp_allocator: _ = context.temp_allocator,
loc: _ = #caller_location,
) -> (err: Unmarshal_Error)Source_unsupported
_unsupported :: proc(v: any, hdr: Header, add: Add) -> (Maybe(Unsupported_Type_Error))Sourcedecode_from_decoder
decode_from_decoder :: proc(d: Decoder, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (v: Value, err: Decode_Error)SourceReads a CBOR value from the given decoder. See docs on the proc group decode for more information.
decode_from_reader
decode_from_reader :: proc(r: io.Reader, flags: Decoder_Flags, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (v: Value, err: Decode_Error)SourceReads a CBOR value from the given reader. See docs on the proc group decode for more information.
decode_from_string
decode_from_string :: proc(s: string, flags: Decoder_Flags, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (v: Value, err: Decode_Error)SourceDecodes the given string as CBOR. See docs on the proc group decode for more information.
decode_to_unmarshal_err
decode_to_unmarshal_err :: proc(err: Decode_Error) -> (Unmarshal_Error)Sourcedecode_to_unmarshal_err_p
decode_to_unmarshal_err_p :: proc(v: T, err: Decode_Error) -> (Unmarshal_Error, T)Sourcedecode_to_unmarshal_err_p2
decode_to_unmarshal_err_p2 :: proc(v: T, v2: T2, err: Decode_Error) -> (Unmarshal_Error, T, T2)Sourcedestroy
destroy :: proc(val: Value, allocator: mem.Allocator = context.allocator)SourceRecursively frees all memory allocated when decoding the passed value.
encode_into_builder
encode_into_builder :: proc(b: ^strings.Builder, v: Value, flags = ENCODE_SMALL, temp_allocator = context.temp_allocator, loc = #caller_location) -> (Encode_Error)SourceEncodes the CBOR value into binary CBOR written to the given builder. See the docs on the proc group encode_into for more info.
encode_into_bytes
encode_into_bytes :: proc(v: Value, flags = ENCODE_SMALL, allocator: mem.Allocator = context.allocator, temp_allocator = context.temp_allocator, loc = #caller_location) -> (data: []u8, err: Encode_Error)SourceEncodes the CBOR value into binary CBOR allocated on the given allocator. See the docs on the proc group encode_into for more info.
encode_into_encoder
encode_into_encoder :: proc(e: Encoder, v: Value, loc = #caller_location) -> (Encode_Error)SourceEncodes the CBOR value into binary CBOR written to the given encoder. See the docs on the proc group encode_into for more info.
encode_into_writer
encode_into_writer :: proc(w: io.Writer, v: Value, flags = ENCODE_SMALL, temp_allocator = context.temp_allocator, loc = #caller_location) -> (Encode_Error)SourceEncodes the CBOR value into binary CBOR written to the given writer. See the docs on the proc group encode_into for more info.
encode_stream_begin
encode_stream_begin :: proc(w: io.Writer, major: Major) -> (err: io.Error)SourceStreaming
encode_stream_bytes
encode_stream_bytes :: proc(e: Encoder, val: Bytes, major: Major) -> (err: Encode_Error)Sourceencode_stream_end
encode_stream_end :: proc(w: io.Writer) -> (io.Error)Sourceencode_stream_map_entry
encode_stream_map_entry :: proc(e: Encoder, key: Value, val: Value) -> (Encode_Error)Sourceencode_stream_text
encode_stream_text :: proc(e: Encoder, val: Text) -> (Encode_Error)Sourceencode_to_marshal_err
encode_to_marshal_err :: proc(err: Encode_Error) -> (Marshal_Error)Sourceencode_to_marshal_err_p2
encode_to_marshal_err_p2 :: proc(v: T, v2: T2, err: Encode_Error) -> (Marshal_Error, T, T2)Sourcefrom_json
from_json :: proc(val: json.Value, allocator: mem.Allocator = context.allocator) -> (mem.Allocator_Error, Value)SourceConverts from JSON to CBOR.
Everything is copied to the given allocator, the passed in JSON value can be deleted after.
marshal_into_builder
marshal_into_builder :: proc(b: ^strings.Builder, v: any, flags = ENCODE_SMALL, temp_allocator = context.temp_allocator) -> (Marshal_Error)SourceMarshals the given value into a CBOR byte stream written to the given builder. See docs on the marshal_into proc group for more info.
marshal_into_bytes
marshal_into_bytes :: proc(v: any, flags = ENCODE_SMALL, allocator: mem.Allocator = context.allocator, temp_allocator = context.temp_allocator, loc = #caller_location) -> (bytes: []u8, err: Marshal_Error)SourceMarshals the given value into a CBOR byte stream (allocated using the given allocator). See docs on the marshal_into proc group for more info.
marshal_into_encoder
marshal_into_encoder :: proc(e: Encoder, v: any) -> (err: Marshal_Error)SourceMarshals the given value into a CBOR byte stream written to the given encoder. See docs on the marshal_into proc group for more info.
marshal_into_writer
marshal_into_writer :: proc(w: io.Writer, v: any, flags = ENCODE_SMALL, temp_allocator = context.temp_allocator) -> (Marshal_Error)SourceMarshals the given value into a CBOR byte stream written to the given writer. See docs on the marshal_into proc group for more info.
negative_u16_to_int
negative_u16_to_int :: proc(u: Negative_U16) -> (i32)Sourcenegative_u32_to_int
negative_u32_to_int :: proc(u: Negative_U32) -> (i64)Sourcenegative_u64_to_int
negative_u64_to_int :: proc(u: Negative_U64) -> (i128)Sourcenegative_u8_to_int
negative_u8_to_int :: proc(u: Negative_U8) -> (i16)Sourcetag_register_number
tag_register_number :: proc(impl: Tag_Implementation, nr: Tag_Number, id: string)SourceRegister a custom tag implementation to be used when marshalling that tag number or marshalling a field with the struct tag cbor_tag:"nr".
tag_register_type
tag_register_type :: proc(impl: Tag_Implementation, nr: Tag_Number, type: typeid)SourceRegister a custom tag implementation to be used when marshalling that type and unmarshalling that tag number.
tags_register_defaults
tags_register_defaults :: proc()SourceRegisters tags that have implementations provided by this package. This is done by default and can be controlled with the CBOR_INITIALIZE_DEFAULT_TAGS define.
to_diagnostic_format_string
to_diagnostic_format_string :: proc(val: Value, padding: untyped integer = 0, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (mem.Allocator_Error, string)SourceTurns the given CBOR value into a human-readable string. See docs on the proc group diagnose for more info.
to_diagnostic_format_writer
to_diagnostic_format_writer :: proc(w: io.Writer, val: Value, padding: untyped integer = 0) -> (io.Error)SourceWrites the given CBOR value into the writer as human-readable text. See docs on the proc group diagnose for more info.
to_json
to_json :: proc(val: Value, allocator: mem.Allocator = context.allocator) -> (json.Value, mem.Allocator_Error)SourceConverts from CBOR to JSON.
NOTE: overflow on integers or floats is not handled.
Everything is copied to the given allocator, the passed in CBOR value can be destroy'ed after.
If a CBOR map with non-string keys is encountered it is turned into an array of tuples.
unmarshal_from_bytes
unmarshal_from_bytes :: proc(
bytes: []u8,
ptr: ^T,
flags: Decoder_Flags = Decoder_Flags{},
allocator: mem.Allocator = context.allocator,
temp_allocator: _ = context.temp_allocator,
loc: _ = #caller_location,
) -> (err: Unmarshal_Error)SourceUnmarshals from a slice of bytes, see docs on the proc group Unmarshal for more info.
unmarshal_from_decoder
unmarshal_from_decoder :: proc(d: Decoder, ptr: ^T, allocator: mem.Allocator = context.allocator, temp_allocator = context.temp_allocator, loc = #caller_location) -> (err: Unmarshal_Error)Sourceunmarshal_from_reader
unmarshal_from_reader :: proc(
r: io.Reader,
ptr: ^T,
flags: Decoder_Flags = Decoder_Flags{},
allocator: mem.Allocator = context.allocator,
temp_allocator: _ = context.temp_allocator,
loc: _ = #caller_location,
) -> (err: Unmarshal_Error)Sourceunmarshal_from_string
unmarshal_from_string :: proc(
s: string,
ptr: ^T,
flags: Decoder_Flags = Decoder_Flags{},
allocator: mem.Allocator = context.allocator,
temp_allocator: _ = context.temp_allocator,
loc: _ = #caller_location,
) -> (err: Unmarshal_Error)SourceUnmarshals from a string, see docs on the proc group Unmarshal for more info.
Procedure Groups
11_encode_deterministic_float
_encode_deterministic_float :: proc{_encode_f16, _encode_deterministic_f32, _encode_deterministic_f64}SourceA Deterministic float is a float in the smallest type that stays the same after down casting.
_encode_deterministic_uint
_encode_deterministic_uint :: proc{_encode_u8, _encode_deterministic_u16, _encode_deterministic_u32, _encode_deterministic_u64, _encode_deterministic_u128}SourceDeterministic encoding is (among other things) encoding all values into their smallest possible representation. See section 4 of RFC 8949.
_encode_uint
_encode_uint :: proc{_encode_u8, _encode_u16, _encode_u32, _encode_u64}Source_int_to_uint
_int_to_uint :: proc{_i8_to_uint, _i16_to_uint, _i32_to_uint, _i64_to_uint, _i128_to_uint}Sourcedecode_from
decode_from :: proc{decode_from_string, decode_from_reader, decode_from_decoder}SourceDecodes both deterministic and non-deterministic CBOR into a Value variant.
Text and Bytes can safely be cast to cstrings because of an added 0 byte.
Allocations are done using the given allocator, no allocations are done on the context.temp_allocator.
A value can be (fully and recursively) deallocated using the destroy proc in this package.
Disable streaming/indeterminate lengths with the .Disallow_Streaming flag.
Shrink excess bytes in buffers and containers with the .Shrink_Excess flag.
Mark the input as trusted input with the .Trusted_Input flag, this turns off the safety feature of not pre-allocating more than max_pre_alloc bytes before reading into the bytes. You should only do this when you own both sides of the encoding and are sure there can't be malicious bytes used as an input.
encode_into
encode_into :: proc{encode_into_bytes, encode_into_builder, encode_into_writer, encode_into_encoder}SourceEncodes the CBOR value into a binary CBOR.
Flags can be used to control the output (mainly determinism, which coincidently affects size).
The default flags ENCODE_SMALL (.Deterministic_Int_Size, .Deterministic_Float_Size) will try to put ints and floats into their smallest possible byte size without losing equality.
Adding the .Self_Described_CBOR flag will wrap the value in a tag that lets generic decoders know the contents are CBOR from just reading the first byte.
Adding the .Deterministic_Map_Sorting flag will sort the encoded maps by the byte content of the encoded key. This flag has a cost on performance and memory efficiency because all keys in a map have to be precomputed, sorted and only then written to the output.
Empty flags will do nothing extra to the value.
The allocations for the .Deterministic_Map_Sorting flag are done using the given temp_allocator. but are followed by the necessary delete and free calls if the allocator supports them. This is helpful when the CBOR size is so big that you don't want to collect all the temporary allocations until the end.
err_conv
err_conv :: proc{encode_to_marshal_err, encode_to_marshal_err_p2, decode_to_unmarshal_err, decode_to_unmarshal_err_p, decode_to_unmarshal_err_p2}SourceUtility for converting between the different errors when they are subsets of the other.
marshal_into
marshal_into :: proc{marshal_into_bytes, marshal_into_builder, marshal_into_writer, marshal_into_encoder}SourceMarshal a value into binary CBOR.
Flags can be used to control the output (mainly determinism, which coincidently affects size).
The default flags ENCODE_SMALL (.Deterministic_Int_Size, .Deterministic_Float_Size) will try to put ints and floats into their smallest possible byte size without losing equality.
Adding the .Self_Described_CBOR flag will wrap the value in a tag that lets generic decoders know the contents are CBOR from just reading the first byte.
Adding the .Deterministic_Map_Sorting flag will sort the encoded maps by the byte content of the encoded key. This flag has a cost on performance and memory efficiency because all keys in a map have to be precomputed, sorted and only then written to the output.
Empty flags will do nothing extra to the value.
The allocations for the .Deterministic_Map_Sorting flag are done using the given temp_allocator. but are followed by the necessary delete and free calls if the allocator supports them. This is helpful when the CBOR size is so big that you don't want to collect all the temporary allocations until the end.
negative_to_int
negative_to_int :: proc{negative_u8_to_int, negative_u16_to_int, negative_u32_to_int, negative_u64_to_int}SourceTurns the CBOR negative unsigned int type into a signed integer type.
to_diagnostic_format
to_diagnostic_format :: proc{to_diagnostic_format_string, to_diagnostic_format_writer}Sourceto_diagnostic_format either writes or returns a human-readable representation of the value, optionally formatted, defined as the diagnostic format in RFC 8949 Section 8.
Incidentally, if the CBOR does not contain any of the additional types defined on top of JSON this will also be valid JSON.
unmarshal
unmarshal :: proc{unmarshal_from_reader, unmarshal_from_string, unmarshal_from_bytes}SourceUnmarshals the given CBOR into the given pointer using reflection. Types that require allocation are allocated using the given allocator.
Some temporary allocations are done on the given temp_allocator, but, if you want to, this can be set to a "normal" allocator, because the necessary delete and free calls are still made. This is helpful when the CBOR size is so big that you don't want to collect all the temporary allocations until the end.
Disable streaming/indeterminate lengths with the .Disallow_Streaming flag.
Shrink excess bytes in buffers and containers with the .Shrink_Excess flag.
Mark the input as trusted input with the .Trusted_Input flag, this turns off the safety feature of not pre-allocating more than max_pre_alloc bytes before reading into the bytes. You should only do this when you own both sides of the encoding and are sure there can't be malicious bytes used as an input.