fxamacker / cbor

CBOR codec (RFC 8949) with CBOR tags, Go struct tags (toarray, keyasint, omitempty), float64/32/16, big.Int, and fuzz tested billions of execs.
MIT License
715 stars 59 forks source link

CBOR CWT and SenML decoding examples using "keyasint", "toarray" struct tags #37

Closed x448 closed 4 years ago

x448 commented 4 years ago

Add this to Usage section today? Last code-related commit has been fuzzing nonstop for days without single crash and speed is fast with this feature!

How to Decode SenML with fxamacker/cbor v1.3

// RFC 8428 says, "The data is structured as a single array that 
// contains a series of SenML Records that can each contain fields"

// fxamacker/cbor v1.3 has "keyasint" struct tag (ideal for SenML)
type SenMLRecord struct {
    BaseName    string  `cbor:"-2,keyasint,omitempty"`
    BaseTime    float64 `cbor:"-3,keyasint,omitempty"`
    BaseUnit    string  `cbor:"-4,keyasint,omitempty"`
    BaseValue   float64 `cbor:"-5,keyasint,omitempty"`
    BaseSum     float64 `cbor:"-6,keyasint,omitempty"`
    BaseVersion int     `cbor:"-1,keyasint,omitempty"`
    Name        string  `cbor:"0,keyasint,omitempty"`
    Unit        string  `cbor:"1,keyasint,omitempty"`
    Value       float64 `cbor:"2,keyasint,omitempty"`
    ValueS      string  `cbor:"3,keyasint,omitempty"`
    ValueB      bool    `cbor:"4,keyasint,omitempty"`
    ValueD      []byte  `cbor:"8,keyasint,omitempty"`
    Sum         float64 `cbor:"5,keyasint,omitempty"`
    Time        int     `cbor:"6,keyasint,omitempty"`
    UpdateTime  float64 `cbor:"7,keyasint,omitempty"`
}

// When cborData is a []byte containing SenML, 
// it can easily be decoded into a []SenMLRecord.

var v []SenMLRecord
if err := cbor.Unmarshal(cborData, &v); err != nil {
    t.Fatal("Unmarshal:", err)
}

// That's it!  Decoding speed is fast and v contains easy to use SenML Records.
x448 commented 4 years ago

Example decoding CWT (CBOR Web Token) using keyasint and toarray struct tags.

// Example from RFC 8392 A.3. Example Signed CWT

// Partial COSE header definition
type coseHeader struct {
  Alg int    `cbor:"1,keyasint"`
    Kid []byte `cbor:"4,keyasint"`
    IV  []byte `cbor:"5,keyasint"`
}

// fxamacker/cbor v1.3 has "toarray" struct tag
type signedCWT struct {
  _           struct{} `cbor:",toarray"`
    Protected   []byte
    Unprotected coseHeader
    Payload     []byte
    Signature   []byte
}

// When cborData is []byte containing a signed CWT
// it can be decoded into signedCTW struct easily

var v signedCWT
if err := cbor.Unmarshal(cborData, &v); err != nil {
  t.Fatal("Unmarshal:", err)
}

// That's it!  You get fast decoding and easy-to-use struct.

Both SenML and CWT decoding examples are in pull request. Added to Usage section.