Documentation
¶
Overview ¶
Package cbor is the deterministic CBOR that committed records are written in.
The codec is the subset of RFC 8949 a record needs, with the core deterministic encoding rules of §4.2.1 enforced on BOTH sides. The encoder only ever writes canonical bytes; the decoder refuses anything that is not canonical or is outside the subset, so a record that decodes is byte for byte the record its encoder produced, and a hostile publisher cannot hand a host two different byte strings for one value.
Supported: unsigned integers (major type 0), negative integers (1), byte strings (2), text strings (3, valid UTF-8), arrays (4), maps (5, keys in bytewise lexicographic order of their encodings, no duplicates), and the simple values false, true and null (7). Refused: indefinite lengths, tags, floats, undefined, every other simple value, and nesting deeper than MaxDepth. Nothing here allocates from a declared length before the bytes are known to be present.
Index ¶
Examples ¶
Constants ¶
const MaxDepth = 16
MaxDepth bounds nesting. A committed record is two levels deep (a map whose body is a map); sixteen leaves room for a body that nests without letting a hostile item recurse without limit.
Variables ¶
var ( ErrNotCanonical = errors.New("cbor: not canonical") ErrUnsupported = errors.New("cbor: unsupported item") ErrTruncated = errors.New("cbor: truncated") ErrTrailing = errors.New("cbor: trailing bytes") ErrDepth = errors.New("cbor: nesting too deep") ErrDuplicateKey = errors.New("cbor: duplicate map key") ErrKeyOrder = errors.New("cbor: map keys out of order") ErrUTF8 = errors.New("cbor: invalid UTF-8") )
Functions ¶
func Encode ¶
Encode writes v in core deterministic encoding.
Example ¶
Encode sorts a map's keys into canonical order (bytewise order of their encodings), whatever order the Map lists them in, and writes every head in its shortest form. Decoding gives the pairs back in wire order.
package main
import (
"fmt"
"github.com/lightwebinc/bcommon/cbor"
)
func main() {
record := cbor.Map{
{Key: "name", Val: "example"},
{Key: uint64(2), Val: []byte{0xca, 0xfe}},
{Key: uint64(1), Val: int64(-1)},
{Key: "tags", Val: []cbor.Value{"a", true, nil}},
}
b, err := cbor.Encode(record)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("%x\n", b)
v, err := cbor.DecodeValue(b)
if err != nil {
fmt.Println(err)
return
}
for _, p := range v.(cbor.Map) {
fmt.Printf("%v => %v\n", p.Key, p.Val)
}
name, _ := v.(cbor.Map).Get("name")
fmt.Println("name:", name)
}
Output: a401200242cafe646e616d65676578616d706c656474616773836161f5f6 1 => -1 2 => [202 254] name => example tags => [a true <nil>] name: example
Types ¶
type Map ¶
type Map []Pair
Map is a CBOR map. It is a slice, not a Go map, so keys of any supported type can be carried and unknown keys keep their wire position.
type Pair ¶
Pair is one map entry. Map keeps entries in the order given; Encode sorts them, Decode returns them in the (already canonical) wire order.
type Value ¶
type Value any
Value is one decoded item: uint64, int64 (negative values only; a decoder never produces a non-negative int64), []byte, string, []Value, Map, bool, or nil. Encoders additionally accept int, uint and uint8 for convenience.
func DecodeValue ¶
DecodeValue parses exactly one canonical item and refuses trailing bytes.
Example (Refusals) ¶
The decoder refuses every encoding the encoder would not have written, so a value has exactly one byte string a reader accepts.
package main
import (
"fmt"
"github.com/lightwebinc/bcommon/cbor"
)
func main() {
for _, c := range []struct {
what string
b []byte
}{
{"23 in two bytes", []byte{0x18, 0x17}},
{"map keys out of order", []byte{0xa2, 0x02, 0x00, 0x01, 0x00}},
{"duplicate map key", []byte{0xa2, 0x01, 0x00, 0x01, 0x00}},
{"indefinite-length array", []byte{0x9f, 0x01, 0xff}},
{"a float", []byte{0xf9, 0x3c, 0x00}},
{"trailing bytes", []byte{0x01, 0x02}},
{"truncated string", []byte{0x43, 0x01}},
} {
_, err := cbor.DecodeValue(c.b)
fmt.Printf("%s: %v\n", c.what, err)
}
}
Output: 23 in two bytes: cbor: not canonical map keys out of order: cbor: map keys out of order duplicate map key: cbor: duplicate map key indefinite-length array: cbor: unsupported item a float: cbor: unsupported item trailing bytes: cbor: trailing bytes truncated string: cbor: truncated