ipld-eth-server/vendor/github.com/whyrusleeping/cbor/go/cbor.go

1626 lines
38 KiB
Go

// Should be roughly like encoding/gob
// encoding/json has an inferior interface that only works on whole messages to/from whole blobs at once. Reader/Writer based interfaces are better.
package cbor
import (
"bytes"
"errors"
"fmt"
"io"
"log"
"math"
"math/big"
"reflect"
"sort"
"strings"
)
var typeMask byte = 0xE0
var infoBits byte = 0x1F
const (
MajorTypeUint byte = 0
MajorTypeNegInt byte = iota
MajorTypeBytes
MajorTypeText
MajorTypeArray
MajorTypeMap
MajorTypeTag
MajorTypeSimple
MajorTypeFloat byte = MajorTypeSimple
)
const (
SimpleValueFalse byte = 20
SimpleValueTrue byte = iota
SimpleValueNull
SimpleValueUndefined
)
const (
OpcodeBreak byte = 0x1F
)
/* type values */
var cborUint byte = 0x00
var cborNegint byte = 0x20
var cborBytes byte = 0x40
var cborText byte = 0x60
var cborArray byte = 0x80
var cborMap byte = 0xA0
var cborTag byte = 0xC0
var cbor7 byte = 0xE0
/* cbor7 values */
const (
cborFalse byte = 20
cborTrue byte = 21
cborNull byte = 22
)
/* info bits */
var int8Follows byte = 24
var int16Follows byte = 25
var int32Follows byte = 26
var int64Follows byte = 27
var varFollows byte = 31
/* tag values */
var tagBignum uint64 = 2
var tagNegBignum uint64 = 3
var tagDecimal uint64 = 4
var tagBigfloat uint64 = 5
/* batch sizes */
var byteBatch = 1 << 20
var arrayBatch = 1 << 14 //16k
// TODO: honor encoding.BinaryMarshaler interface and encapsulate blob returned from that.
// Load one object into v
func Loads(blob []byte, v interface{}) error {
dec := NewDecoder(bytes.NewReader(blob))
return dec.Decode(v)
}
type TagDecoder interface {
// Handle things which match this.
//
// Setup like this:
// var dec Decoder
// var myTagDec TagDecoder
// dec.TagDecoders[myTagDec.GetTag()] = myTagDec
GetTag() uint64
// Sub-object will be decoded onto the returned object.
DecodeTarget() interface{}
// Run after decode onto DecodeTarget has happened.
// The return value from this is returned in place of the
// raw decoded object.
PostDecode(interface{}) (interface{}, error)
}
type Decoder struct {
reader io.Reader
// tag byte
tag []byte
// many values fit within the next 8 bytes
b8 []byte
// Extra processing for CBOR TAG objects.
TagDecoders map[uint64]TagDecoder
}
func NewDecoder(r io.Reader) *Decoder {
return &Decoder{
reader: r,
tag: make([]byte, 1),
b8: make([]byte, 8),
TagDecoders: make(map[uint64]TagDecoder),
}
}
func (dec *Decoder) Decode(v interface{}) error {
rv := reflect.ValueOf(v)
return dec.DecodeAny(newReflectValue(rv))
}
type DecodeValue interface {
// Before decoding, check if there is no error
Prepare() error
// Got binary string
SetBytes(buf []byte) error
// Got a number (different formats)
SetBignum(x *big.Int) error
SetUint(u uint64) error
SetInt(i int64) error
SetFloat32(f float32) error
SetFloat64(d float64) error
// Got null
SetNil() error
// Got boolean
SetBool(b bool) error
// Got text string
SetString(s string) error
// Got a Map (beginning)
CreateMap() (DecodeValueMap, error)
// Got an array (beginning)
CreateArray(makeLength int) (DecodeValueArray, error)
// Got a tag
CreateTag(aux uint64, decoder TagDecoder) (DecodeValue, interface{}, error)
// Got the tag value (maybe transformed by TagDecoder.PostDecode)
SetTag(aux uint64, v DecodeValue, decoder TagDecoder, i interface{}) error
}
type DecodeValueMap interface {
// Got a map key
CreateMapKey() (DecodeValue, error)
// Got a map value
CreateMapValue(key DecodeValue) (DecodeValue, error)
// Got a key / value pair
SetMap(key, val DecodeValue) error
// The map is at the end
EndMap() error
}
type DecodeValueArray interface {
// Got an array item
GetArrayValue(index uint64) (DecodeValue, error)
// After the array item is decoded
AppendArray(value DecodeValue) error
// The array is at the end
EndArray() error
}
type reflectValue struct {
v reflect.Value
}
type MemoryValue struct {
reflectValue
Value interface{}
}
func NewMemoryValue(value interface{}) *MemoryValue {
res := &MemoryValue{
reflectValue{reflect.ValueOf(nil)},
value,
}
res.v = reflect.ValueOf(&res.Value)
return res
}
func (mv *MemoryValue) ReflectValue() reflect.Value {
return mv.v
}
func newReflectValue(rv reflect.Value) *reflectValue {
return &reflectValue{rv}
}
func (r *reflectValue) Prepare() error {
rv := r.v
if (!rv.CanSet()) && (rv.Kind() != reflect.Ptr || rv.IsNil()) {
return &InvalidUnmarshalError{rv.Type()}
}
return nil
}
func (dec *Decoder) DecodeAny(v DecodeValue) error {
var err error
_, err = io.ReadFull(dec.reader, dec.tag)
if err != nil {
return err
}
if err := v.Prepare(); err != nil {
return err
}
return dec.innerDecodeC(v, dec.tag[0])
}
func (dec *Decoder) handleInfoBits(cborInfo byte) (uint64, error) {
var aux uint64
if cborInfo <= 23 {
aux = uint64(cborInfo)
return aux, nil
} else if cborInfo == int8Follows {
didread, err := io.ReadFull(dec.reader, dec.b8[:1])
if didread == 1 {
aux = uint64(dec.b8[0])
}
return aux, err
} else if cborInfo == int16Follows {
didread, err := io.ReadFull(dec.reader, dec.b8[:2])
if didread == 2 {
aux = (uint64(dec.b8[0]) << 8) | uint64(dec.b8[1])
}
return aux, err
} else if cborInfo == int32Follows {
didread, err := io.ReadFull(dec.reader, dec.b8[:4])
if didread == 4 {
aux = (uint64(dec.b8[0]) << 24) |
(uint64(dec.b8[1]) << 16) |
(uint64(dec.b8[2]) << 8) |
uint64(dec.b8[3])
}
return aux, err
} else if cborInfo == int64Follows {
didread, err := io.ReadFull(dec.reader, dec.b8)
if didread == 8 {
var shift uint = 56
i := 0
aux = uint64(dec.b8[i]) << shift
for i < 7 {
i += 1
shift -= 8
aux |= uint64(dec.b8[i]) << shift
}
}
return aux, err
}
return 0, nil
}
func (dec *Decoder) innerDecodeC(rv DecodeValue, c byte) error {
cborType := c & typeMask
cborInfo := c & infoBits
aux, err := dec.handleInfoBits(cborInfo)
if err != nil {
log.Printf("error in handleInfoBits: %v", err)
return err
}
//log.Printf("cborType %x cborInfo %d aux %x", cborType, cborInfo, aux)
if cborType == cborUint {
return rv.SetUint(aux)
} else if cborType == cborNegint {
if aux > 0x7fffffffffffffff {
//return errors.New(fmt.Sprintf("cannot represent -%d", aux))
bigU := &big.Int{}
bigU.SetUint64(aux)
minusOne := big.NewInt(-1)
bn := &big.Int{}
bn.Sub(minusOne, bigU)
//log.Printf("built big negint: %v", bn)
return rv.SetBignum(bn)
}
return rv.SetInt(-1 - int64(aux))
} else if cborType == cborBytes {
//log.Printf("cborType %x bytes cborInfo %d aux %x", cborType, cborInfo, aux)
if cborInfo == varFollows {
parts := make([][]byte, 0, 1)
allsize := 0
subc := []byte{0}
for true {
_, err = io.ReadFull(dec.reader, subc)
if err != nil {
log.Printf("error reading next byte for bar bytes")
return err
}
if subc[0] == 0xff {
// done
var out []byte = nil
if len(parts) == 0 {
out = make([]byte, 0)
} else {
pos := 0
out = make([]byte, allsize)
for _, p := range parts {
pos += copy(out[pos:], p)
}
}
return rv.SetBytes(out)
} else {
var subb []byte = nil
if (subc[0] & typeMask) != cborBytes {
return fmt.Errorf("sub of var bytes is type %x, wanted %x", subc[0], cborBytes)
}
err = dec.innerDecodeC(newReflectValue(reflect.ValueOf(&subb)), subc[0])
if err != nil {
log.Printf("error decoding sub bytes")
return err
}
allsize += len(subb)
parts = append(parts, subb)
}
}
} else {
val, err := dec.readBytes(aux)
if err != nil {
return err
}
return rv.SetBytes(val)
}
} else if cborType == cborText {
return dec.decodeText(rv, cborInfo, aux)
} else if cborType == cborArray {
return dec.decodeArray(rv, cborInfo, aux)
} else if cborType == cborMap {
return dec.decodeMap(rv, cborInfo, aux)
} else if cborType == cborTag {
/*var innerOb interface{}*/
ic := []byte{0}
_, err = io.ReadFull(dec.reader, ic)
if err != nil {
return err
}
if aux == tagBignum {
bn, err := dec.decodeBignum(ic[0])
if err != nil {
return err
}
return rv.SetBignum(bn)
} else if aux == tagNegBignum {
bn, err := dec.decodeBignum(ic[0])
if err != nil {
return err
}
minusOne := big.NewInt(-1)
bnOut := &big.Int{}
bnOut.Sub(minusOne, bn)
return rv.SetBignum(bnOut)
} else if aux == tagDecimal {
log.Printf("TODO: directly read bytes into decimal")
} else if aux == tagBigfloat {
log.Printf("TODO: directly read bytes into bigfloat")
} else {
decoder := dec.TagDecoders[aux]
var target interface{}
var trv DecodeValue
var err error
trv, target, err = rv.CreateTag(aux, decoder)
if err != nil {
return err
}
err = dec.innerDecodeC(trv, ic[0])
if err != nil {
return err
}
return rv.SetTag(aux, trv, decoder, target)
}
return nil
} else if cborType == cbor7 {
if cborInfo == int16Follows {
exp := (aux >> 10) & 0x01f
mant := aux & 0x03ff
var val float64
if exp == 0 {
val = math.Ldexp(float64(mant), -24)
} else if exp != 31 {
val = math.Ldexp(float64(mant+1024), int(exp-25))
} else if mant == 0 {
val = math.Inf(1)
} else {
val = math.NaN()
}
if (aux & 0x08000) != 0 {
val = -val
}
return rv.SetFloat64(val)
} else if cborInfo == int32Follows {
f := math.Float32frombits(uint32(aux))
return rv.SetFloat32(f)
} else if cborInfo == int64Follows {
d := math.Float64frombits(aux)
return rv.SetFloat64(d)
} else if cborInfo == cborFalse {
return rv.SetBool(false)
} else if cborInfo == cborTrue {
return rv.SetBool(true)
} else if cborInfo == cborNull {
return rv.SetNil()
}
}
return err
}
func (dec *Decoder) decodeText(rv DecodeValue, cborInfo byte, aux uint64) error {
var err error
if cborInfo == varFollows {
parts := make([]string, 0, 1)
subc := []byte{0}
for true {
_, err = io.ReadFull(dec.reader, subc)
if err != nil {
log.Printf("error reading next byte for var text")
return err
}
if subc[0] == 0xff {
// done
joined := strings.Join(parts, "")
return rv.SetString(joined)
} else {
var subtext interface{}
err = dec.innerDecodeC(newReflectValue(reflect.ValueOf(&subtext)), subc[0])
if err != nil {
log.Printf("error decoding subtext")
return err
}
st, ok := subtext.(string)
if ok {
parts = append(parts, st)
} else {
return fmt.Errorf("var text sub element not text but %T", subtext)
}
}
}
} else {
raw, err := dec.readBytes(aux)
if err != nil {
return err
}
xs := string(raw)
return rv.SetString(xs)
}
return errors.New("internal error in decodeText, shouldn't get here")
}
func (dec *Decoder) readBytes(n uint64) ([]byte, error) {
buf := new(bytes.Buffer)
r, err := buf.ReadFrom(&io.LimitedReader{R: dec.reader, N: int64(n)})
if err != nil {
return nil, err
}
if r != int64(n) {
return nil, io.ErrUnexpectedEOF
}
return buf.Bytes(), nil
}
type mapAssignable interface {
ReflectValueForKey(key interface{}) (*reflect.Value, bool)
SetReflectValueForKey(key interface{}, value reflect.Value) error
}
type mapReflectValue struct {
reflect.Value
}
func (irv *mapReflectValue) ReflectValueForKey(key interface{}) (*reflect.Value, bool) {
//var x interface{}
//rv := reflect.ValueOf(&x)
rv := reflect.New(irv.Type().Elem())
return &rv, true
}
func (irv *mapReflectValue) SetReflectValueForKey(key interface{}, value reflect.Value) error {
//log.Printf("k T %T v%#v, v T %s v %#v", key, key, value.Type().String(), value.Interface())
krv := reflect.Indirect(reflect.ValueOf(key))
vrv := reflect.Indirect(value)
//log.Printf("irv T %s v %#v", irv.Type().String(), irv.Interface())
//log.Printf("k T %s v %#v, v T %s v %#v", krv.Type().String(), krv.Interface(), vrv.Type().String(), vrv.Interface())
if krv.Kind() == reflect.Interface {
krv = krv.Elem()
//log.Printf("ke T %s v %#v", krv.Type().String(), krv.Interface())
}
if (krv.Kind() == reflect.Slice) || (krv.Kind() == reflect.Array) {
//log.Printf("key is slice or array")
if krv.Type().Elem().Kind() == reflect.Uint8 {
//log.Printf("key is []uint8")
ks := string(krv.Bytes())
krv = reflect.ValueOf(ks)
}
}
irv.SetMapIndex(krv, vrv)
return nil
}
type structAssigner struct {
Srv reflect.Value
//keyType reflect.Type
}
func (sa *structAssigner) ReflectValueForKey(key interface{}) (*reflect.Value, bool) {
var skey string
switch tkey := key.(type) {
case string:
skey = tkey
case *string:
skey = *tkey
default:
log.Printf("rvfk key is not string, got %T", key)
return nil, false
}
ft := sa.Srv.Type()
numFields := ft.NumField()
for i := 0; i < numFields; i++ {
sf := ft.Field(i)
fieldname, ok := fieldname(sf)
if !ok {
continue
}
if (fieldname == skey) || strings.EqualFold(fieldname, skey) {
fieldVal := sa.Srv.FieldByName(sf.Name)
if !fieldVal.CanSet() {
log.Printf("cannot set field %s for key %s", sf.Name, skey)
return nil, false
}
return &fieldVal, true
}
}
return nil, false
}
func (sa *structAssigner) SetReflectValueForKey(key interface{}, value reflect.Value) error {
return nil
}
func (dec *Decoder) setMapKV(dvm DecodeValueMap, krv DecodeValue) error {
var err error
val, err := dvm.CreateMapValue(krv)
if err != nil {
var throwaway interface{}
err = dec.Decode(&throwaway)
if err != nil {
return err
}
return nil
}
err = dec.DecodeAny(val)
if err != nil {
log.Printf("error decoding map val: T %T v %#v", val, val)
return err
}
err = dvm.SetMap(krv, val)
if err != nil {
log.Printf("error setting value")
return err
}
return nil
}
func (r *reflectValue) CreateMap() (DecodeValueMap, error) {
rv := r.v
var drv reflect.Value
if rv.Kind() == reflect.Ptr {
drv = reflect.Indirect(rv)
} else {
drv = rv
}
//log.Print("decode map into d ", drv.Type().String())
// inner reflect value
var irv reflect.Value
var ma mapAssignable
var keyType reflect.Type
switch drv.Kind() {
case reflect.Interface:
//log.Print("decode map into interface ", drv.Type().String())
// TODO: maybe I should make this map[string]interface{}
nob := make(map[interface{}]interface{})
irv = reflect.ValueOf(nob)
ma = &mapReflectValue{irv}
keyType = irv.Type().Key()
case reflect.Struct:
//log.Print("decode map into struct ", drv.Type().String())
ma = &structAssigner{drv}
keyType = reflect.TypeOf("")
case reflect.Map:
//log.Print("decode map into map ", drv.Type().String())
if drv.IsNil() {
if drv.CanSet() {
drv.Set(reflect.MakeMap(drv.Type()))
} else {
return nil, fmt.Errorf("target map is nil and not settable")
}
}
keyType = drv.Type().Key()
ma = &mapReflectValue{drv}
default:
return nil, fmt.Errorf("can't read map into %s", rv.Type().String())
}
return &reflectValueMap{drv, irv, ma, keyType}, nil
}
type reflectValueMap struct {
drv reflect.Value
irv reflect.Value
ma mapAssignable
keyType reflect.Type
}
func (r *reflectValueMap) CreateMapKey() (DecodeValue, error) {
return newReflectValue(reflect.New(r.keyType)), nil
}
func (r *reflectValueMap) CreateMapValue(key DecodeValue) (DecodeValue, error) {
var err error
v, ok := r.ma.ReflectValueForKey(key.(*reflectValue).v.Interface())
if !ok {
err = fmt.Errorf("Could not reflect value for key")
}
return newReflectValue(*v), err
}
func (r *reflectValueMap) SetMap(key, val DecodeValue) error {
return r.ma.SetReflectValueForKey(key.(*reflectValue).v.Interface(), val.(*reflectValue).v)
}
func (r *reflectValueMap) EndMap() error {
if r.drv.Kind() == reflect.Interface {
r.drv.Set(r.irv)
}
return nil
}
func (dec *Decoder) decodeMap(rv DecodeValue, cborInfo byte, aux uint64) error {
//log.Print("decode map into ", rv.Type().String())
// dereferenced reflect value
var dvm DecodeValueMap
var err error
dvm, err = rv.CreateMap()
if err != nil {
return err
}
if cborInfo == varFollows {
subc := []byte{0}
for true {
_, err = io.ReadFull(dec.reader, subc)
if err != nil {
log.Printf("error reading next byte for var text")
return err
}
if subc[0] == 0xff {
// Done
break
} else {
//var key interface{}
krv, err := dvm.CreateMapKey()
if err != nil {
return err
}
//var val interface{}
err = dec.innerDecodeC(krv, subc[0])
if err != nil {
log.Printf("error decoding map key V, %s", err)
return err
}
err = dec.setMapKV(dvm, krv)
if err != nil {
return err
}
}
}
} else {
var i uint64
for i = 0; i < aux; i++ {
//var key interface{}
krv, err := dvm.CreateMapKey()
if err != nil {
return err
}
//var val interface{}
//err = dec.Decode(&key)
err = dec.DecodeAny(krv)
if err != nil {
log.Printf("error decoding map key #, %s", err)
return err
}
err = dec.setMapKV(dvm, krv)
if err != nil {
return err
}
}
}
return dvm.EndMap()
}
func (r *reflectValue) CreateArray(makeLength int) (DecodeValueArray, error) {
var rv reflect.Value = r.v
if rv.Kind() == reflect.Ptr {
rv = reflect.Indirect(rv)
}
// inner reflect value
var irv reflect.Value
var elemType reflect.Type
switch rv.Kind() {
case reflect.Interface:
// make a slice
nob := make([]interface{}, 0, makeLength)
irv = reflect.ValueOf(nob)
elemType = irv.Type().Elem()
case reflect.Slice:
// we have a slice
irv = rv
elemType = irv.Type().Elem()
case reflect.Array:
// no irv, no elemType
default:
return nil, fmt.Errorf("can't read array into %s", rv.Type().String())
}
return &reflectValueArray{rv, makeLength, irv, elemType, 0}, nil
}
type reflectValueArray struct {
rv reflect.Value
makeLength int
irv reflect.Value
elemType reflect.Type
arrayPos int
}
func (r *reflectValueArray) GetArrayValue(index uint64) (DecodeValue, error) {
if r.rv.Kind() == reflect.Array {
return &reflectValue{r.rv.Index(r.arrayPos)}, nil
} else {
return &reflectValue{reflect.New(r.elemType)}, nil
}
}
func (r *reflectValueArray) AppendArray(subrv DecodeValue) error {
if r.rv.Kind() == reflect.Array {
r.arrayPos++
} else {
r.irv = reflect.Append(r.irv, reflect.Indirect(subrv.(*reflectValue).v))
}
return nil
}
func (r *reflectValueArray) EndArray() error {
if r.rv.Kind() != reflect.Array {
r.rv.Set(r.irv)
}
return nil
}
func (dec *Decoder) decodeArray(rv DecodeValue, cborInfo byte, aux uint64) error {
var err error
var dva DecodeValueArray
var makeLength int = 0
if cborInfo == varFollows {
// no special capacity to allocate the slice to
} else {
makeLength = int(aux)
}
dva, err = rv.CreateArray(int(min(uint64(makeLength), uint64(arrayBatch))))
if err != nil {
return err
}
if cborInfo == varFollows {
//log.Printf("var array")
subc := []byte{0}
var idx uint64 = 0
for true {
_, err = io.ReadFull(dec.reader, subc)
if err != nil {
log.Printf("error reading next byte for var text")
return err
}
if subc[0] == 0xff {
// Done
break
}
subrv, err := dva.GetArrayValue(idx)
if err != nil {
return err
}
err = dec.innerDecodeC(subrv, subc[0])
if err != nil {
log.Printf("error decoding array subob")
return err
}
err = dva.AppendArray(subrv)
if err != nil {
return err
}
idx++
}
} else {
var i uint64
for i = 0; i < aux; i++ {
subrv, err := dva.GetArrayValue(i)
if err != nil {
return err
}
err = dec.DecodeAny(subrv)
if err != nil {
log.Printf("error decoding array subob")
return err
}
err = dva.AppendArray(subrv)
if err != nil {
return err
}
}
}
return dva.EndArray()
}
func (dec *Decoder) decodeBignum(c byte) (*big.Int, error) {
cborType := c & typeMask
cborInfo := c & infoBits
aux, err := dec.handleInfoBits(cborInfo)
if err != nil {
log.Printf("error in bignum handleInfoBits: %v", err)
return nil, err
}
//log.Printf("bignum cborType %x cborInfo %d aux %x", cborType, cborInfo, aux)
if cborType != cborBytes {
return nil, fmt.Errorf("attempting to decode bignum but sub object is not bytes but type %x", cborType)
}
rawbytes, err := dec.readBytes(aux)
if err != nil {
return nil, err
}
bn := big.NewInt(0)
littleBig := &big.Int{}
d := &big.Int{}
for _, bv := range rawbytes {
d.Lsh(bn, 8)
littleBig.SetUint64(uint64(bv))
bn.Or(d, littleBig)
}
return bn, nil
}
func (r *reflectValue) SetBignum(x *big.Int) error {
rv := r.v
switch rv.Kind() {
case reflect.Ptr:
return newReflectValue(reflect.Indirect(rv)).SetBignum(x)
case reflect.Interface:
rv.Set(reflect.ValueOf(*x))
return nil
case reflect.Int32:
if x.BitLen() < 32 {
rv.SetInt(x.Int64())
return nil
} else {
return fmt.Errorf("int too big for int32 target")
}
case reflect.Int, reflect.Int64:
if x.BitLen() < 64 {
rv.SetInt(x.Int64())
return nil
} else {
return fmt.Errorf("int too big for int64 target")
}
default:
return fmt.Errorf("cannot assign bignum into Kind=%s Type=%s %#v", rv.Kind().String(), rv.Type().String(), rv)
}
}
func (r *reflectValue) SetBytes(buf []byte) error {
rv := r.v
switch rv.Kind() {
case reflect.Ptr:
return newReflectValue(reflect.Indirect(rv)).SetBytes(buf)
case reflect.Interface:
rv.Set(reflect.ValueOf(buf))
return nil
case reflect.Slice:
if rv.Type().Elem().Kind() == reflect.Uint8 {
rv.SetBytes(buf)
return nil
} else {
return fmt.Errorf("cannot write []byte to k=%s %s", rv.Kind().String(), rv.Type().String())
}
case reflect.String:
rv.Set(reflect.ValueOf(string(buf)))
return nil
default:
return fmt.Errorf("cannot assign []byte into Kind=%s Type=%s %#v", rv.Kind().String(), "" /*rv.Type().String()*/, rv)
}
}
func (r *reflectValue) SetUint(u uint64) error {
rv := r.v
switch rv.Kind() {
case reflect.Ptr:
if rv.IsNil() {
if rv.CanSet() {
rv.Set(reflect.New(rv.Type().Elem()))
// fall through to set indirect below
} else {
return fmt.Errorf("trying to put uint into unsettable nil ptr")
}
}
return newReflectValue(reflect.Indirect(rv)).SetUint(u)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
if rv.OverflowUint(u) {
return fmt.Errorf("value %d does not fit into target of type %s", u, rv.Kind().String())
}
rv.SetUint(u)
return nil
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
if (u == 0xffffffffffffffff) || rv.OverflowInt(int64(u)) {
return fmt.Errorf("value %d does not fit into target of type %s", u, rv.Kind().String())
}
rv.SetInt(int64(u))
return nil
case reflect.Interface:
rv.Set(reflect.ValueOf(u))
return nil
default:
return fmt.Errorf("cannot assign uint into Kind=%s Type=%#v %#v", rv.Kind().String(), rv.Type(), rv)
}
}
func (r *reflectValue) SetInt(i int64) error {
rv := r.v
switch rv.Kind() {
case reflect.Ptr:
return newReflectValue(reflect.Indirect(rv)).SetInt(i)
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
if rv.OverflowInt(i) {
return fmt.Errorf("value %d does not fit into target of type %s", i, rv.Kind().String())
}
rv.SetInt(i)
return nil
case reflect.Interface:
rv.Set(reflect.ValueOf(i))
return nil
default:
return fmt.Errorf("cannot assign int into Kind=%s Type=%#v %#v", rv.Kind().String(), rv.Type(), rv)
}
}
func (r *reflectValue) SetFloat32(f float32) error {
rv := r.v
switch rv.Kind() {
case reflect.Ptr:
return newReflectValue(reflect.Indirect(rv)).SetFloat32(f)
case reflect.Float32, reflect.Float64:
rv.SetFloat(float64(f))
return nil
case reflect.Interface:
rv.Set(reflect.ValueOf(f))
return nil
default:
return fmt.Errorf("cannot assign float32 into Kind=%s Type=%#v %#v", rv.Kind().String(), rv.Type(), rv)
}
}
func (r *reflectValue) SetFloat64(d float64) error {
rv := r.v
switch rv.Kind() {
case reflect.Ptr:
return newReflectValue(reflect.Indirect(rv)).SetFloat64(d)
case reflect.Float32, reflect.Float64:
rv.SetFloat(d)
return nil
case reflect.Interface:
rv.Set(reflect.ValueOf(d))
return nil
default:
return fmt.Errorf("cannot assign float64 into Kind=%s Type=%#v %#v", rv.Kind().String(), rv.Type(), rv)
}
}
func (r *reflectValue) SetNil() error {
rv := r.v
switch rv.Kind() {
case reflect.Ptr:
//return setNil(reflect.Indirect(rv))
rv.Elem().Set(reflect.Zero(rv.Elem().Type()))
case reflect.Interface:
if rv.IsNil() {
// already nil, okay!
return nil
}
rv.Set(reflect.Zero(rv.Type()))
default:
log.Printf("setNil wat %s", rv.Type())
rv.Set(reflect.Zero(rv.Type()))
}
return nil
}
func (r *reflectValue) SetBool(b bool) error {
rv := r.v
reflect.Indirect(rv).Set(reflect.ValueOf(b))
return nil
}
func (r *reflectValue) SetString(xs string) error {
rv := r.v
// handle either concrete string or string* to nil
deref := reflect.Indirect(rv)
if !deref.CanSet() {
rv.Set(reflect.ValueOf(&xs))
} else {
deref.Set(reflect.ValueOf(xs))
}
//reflect.Indirect(rv).Set(reflect.ValueOf(joined))
return nil
}
func (r *reflectValue) CreateTag(aux uint64, decoder TagDecoder) (DecodeValue, interface{}, error) {
if decoder != nil {
target := decoder.DecodeTarget()
return newReflectValue(reflect.ValueOf(target)), target, nil
} else {
target := &CBORTag{}
target.Tag = aux
return newReflectValue(reflect.ValueOf(&target.WrappedObject)), target, nil
}
}
func (r *reflectValue) SetTag(code uint64, val DecodeValue, decoder TagDecoder, target interface{}) error {
rv := r.v
var err error
if decoder != nil {
target, err = decoder.PostDecode(target)
if err != nil {
return err
}
}
reflect.Indirect(rv).Set(reflect.ValueOf(target))
return nil
}
// copied from encoding/json/decode.go
// An InvalidUnmarshalError describes an invalid argument passed to Unmarshal.
// (The argument to Unmarshal must be a non-nil pointer.)
type InvalidUnmarshalError struct {
Type reflect.Type
}
func (e *InvalidUnmarshalError) Error() string {
if e.Type == nil {
return "json: Unmarshal(nil)"
}
if e.Type.Kind() != reflect.Ptr {
return "json: Unmarshal(non-pointer " + e.Type.String() + ")"
}
return "json: Unmarshal(nil " + e.Type.String() + ")"
}
type CBORTag struct {
Tag uint64
WrappedObject interface{}
}
func (t *CBORTag) ToCBOR(w io.Writer, enc *Encoder) error {
_, err := w.Write(EncodeInt(MajorTypeTag, t.Tag, nil))
if err != nil {
return err
}
return enc.Encode(t.WrappedObject)
}
type Encoder struct {
out io.Writer
filter func(v interface{}) interface{}
scratch []byte
}
// parse StructField.Tag.Get("json" or "cbor")
func fieldTagName(xinfo string) (string, bool) {
if len(xinfo) != 0 {
// e.g. `json:"field_name,omitempty"`, or same for cbor
// TODO: honor 'omitempty' option
jiparts := strings.Split(xinfo, ",")
if len(jiparts) > 0 {
fieldName := jiparts[0]
if len(fieldName) > 0 {
return fieldName, true
}
}
}
return "", false
}
// Return fieldname, bool; if bool is false, don't use this field
func fieldname(fieldinfo reflect.StructField) (string, bool) {
if fieldinfo.PkgPath != "" {
// has path to private package. don't export
return "", false
}
fieldname, ok := fieldTagName(fieldinfo.Tag.Get("cbor"))
if !ok {
fieldname, ok = fieldTagName(fieldinfo.Tag.Get("json"))
}
if ok {
if fieldname == "" {
return fieldinfo.Name, true
}
if fieldname == "-" {
return "", false
}
return fieldname, true
}
return fieldinfo.Name, true
}
// Write out an object to an io.Writer
func Encode(out io.Writer, ob interface{}) error {
return NewEncoder(out).Encode(ob)
}
// Write out an object to a new byte slice
func Dumps(ob interface{}) ([]byte, error) {
writeTarget := &bytes.Buffer{}
writeTarget.Grow(20000)
err := Encode(writeTarget, ob)
if err != nil {
return nil, err
}
return writeTarget.Bytes(), nil
}
type MarshallValue interface {
// Convert the value to CBOR. Specific CBOR data (such as tags) can be written
// on the io.Writer and more complex datatype can be written using the
// Encoder.
//
// To Write a Tag value, a possible implementation would be:
//
// w.Write(cbor.EncodeTag(6, tag_value))
// enc.Encode(tagged_value)
//
ToCBOR(w io.Writer, enc *Encoder) error
}
type SimpleMarshallValue interface {
// Convert the value to CBOR. The object is responsible to convert to CBOR
// in the correct format.
ToCBOR(w io.Writer) error
}
type CBORValue []byte
func (v CBORValue) ToCBOR(w io.Writer) error {
_, err := w.Write(v)
return err
}
// Return new Encoder object for writing to supplied io.Writer.
//
// TODO: set options on Encoder object.
func NewEncoder(out io.Writer) *Encoder {
return &Encoder{out, nil, make([]byte, 9)}
}
func (enc *Encoder) SetFilter(filter func(v interface{}) interface{}) {
enc.filter = filter
}
func (enc *Encoder) Encode(ob interface{}) error {
if enc.filter != nil {
ob = enc.filter(ob)
}
if v, ok := ob.(MarshallValue); ok {
return v.ToCBOR(enc.out, enc)
} else if v, ok := ob.(SimpleMarshallValue); ok {
return v.ToCBOR(enc.out)
}
switch x := ob.(type) {
case int:
return enc.writeInt(int64(x))
case int8:
return enc.writeInt(int64(x))
case int16:
return enc.writeInt(int64(x))
case int32:
return enc.writeInt(int64(x))
case int64:
return enc.writeInt(x)
case uint:
return enc.tagAuxOut(cborUint, uint64(x))
case uint8: /* aka byte */
return enc.tagAuxOut(cborUint, uint64(x))
case uint16:
return enc.tagAuxOut(cborUint, uint64(x))
case uint32:
return enc.tagAuxOut(cborUint, uint64(x))
case uint64:
return enc.tagAuxOut(cborUint, x)
case float32:
return enc.writeFloat(float64(x))
case float64:
return enc.writeFloat(x)
case string:
return enc.writeText(x)
case []byte:
return enc.writeBytes(x)
case bool:
return enc.writeBool(x)
case nil:
return enc.tagAuxOut(cbor7, uint64(cborNull))
case big.Int:
return fmt.Errorf("TODO: encode big.Int")
}
// If none of the simple types work, try reflection
return enc.writeReflection(reflect.ValueOf(ob))
}
func (enc *Encoder) writeReflection(rv reflect.Value) error {
if enc.filter != nil {
rv = reflect.ValueOf(enc.filter(rv.Interface()))
}
if !rv.IsValid() {
return enc.tagAuxOut(cbor7, uint64(cborNull))
}
if v, ok := rv.Interface().(MarshallValue); ok {
return v.ToCBOR(enc.out, enc)
} else if v, ok := rv.Interface().(SimpleMarshallValue); ok {
return v.ToCBOR(enc.out)
}
var err error
switch rv.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return enc.writeInt(rv.Int())
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return enc.tagAuxOut(cborUint, rv.Uint())
case reflect.Float32, reflect.Float64:
return enc.writeFloat(rv.Float())
case reflect.Bool:
return enc.writeBool(rv.Bool())
case reflect.String:
return enc.writeText(rv.String())
case reflect.Slice, reflect.Array:
elemType := rv.Type().Elem()
if elemType.Kind() == reflect.Uint8 {
// special case, write out []byte
return enc.writeBytes(rv.Bytes())
}
alen := rv.Len()
err = enc.tagAuxOut(cborArray, uint64(alen))
for i := 0; i < alen; i++ {
err = enc.writeReflection(rv.Index(i))
if err != nil {
log.Printf("error at array elem %d", i)
return err
}
}
return nil
case reflect.Map:
err = enc.tagAuxOut(cborMap, uint64(rv.Len()))
if err != nil {
return err
}
dup := func(b []byte) []byte {
out := make([]byte, len(b))
copy(out, b)
return out
}
keys := rv.MapKeys()
buf := new(bytes.Buffer)
encKeys := make([]cborKeyEntry, 0, len(keys))
for _, krv := range keys {
tempEnc := NewEncoder(buf)
err := tempEnc.writeReflection(krv)
if err != nil {
log.Println("error encoding map key", err)
return err
}
kval := dup(buf.Bytes())
encKeys = append(encKeys, cborKeyEntry{
val: kval,
key: krv,
})
buf.Reset()
}
sort.Sort(cborKeySorter(encKeys))
for _, ek := range encKeys {
vrv := rv.MapIndex(ek.key)
_, err := enc.out.Write(ek.val)
if err != nil {
log.Printf("error writing map key")
return err
}
err = enc.writeReflection(vrv)
if err != nil {
log.Printf("error encoding map val")
return err
}
}
return nil
case reflect.Struct:
// TODO: check for big.Int ?
numfields := rv.NumField()
structType := rv.Type()
usableFields := 0
for i := 0; i < numfields; i++ {
fieldinfo := structType.Field(i)
_, ok := fieldname(fieldinfo)
if !ok {
continue
}
usableFields++
}
err = enc.tagAuxOut(cborMap, uint64(usableFields))
if err != nil {
return err
}
for i := 0; i < numfields; i++ {
fieldinfo := structType.Field(i)
fieldname, ok := fieldname(fieldinfo)
if !ok {
continue
}
err = enc.writeText(fieldname)
if err != nil {
return err
}
err = enc.writeReflection(rv.Field(i))
if err != nil {
return err
}
}
return nil
case reflect.Interface:
//return fmt.Errorf("TODO: serialize interface{} k=%s T=%s", rv.Kind().String(), rv.Type().String())
return enc.Encode(rv.Interface())
case reflect.Ptr:
if rv.IsNil() {
return enc.tagAuxOut(cbor7, uint64(cborNull))
}
return enc.writeReflection(reflect.Indirect(rv))
}
return fmt.Errorf("don't know how to CBOR serialize k=%s t=%s", rv.Kind().String(), rv.Type().String())
}
type cborKeySorter []cborKeyEntry
type cborKeyEntry struct {
val []byte
key reflect.Value
}
func (cks cborKeySorter) Len() int { return len(cks) }
func (cks cborKeySorter) Swap(i, j int) {
cks[i], cks[j] = cks[j], cks[i]
}
func (cks cborKeySorter) Less(i, j int) bool {
a := keyBytesFromEncoded(cks[i].val)
b := keyBytesFromEncoded(cks[j].val)
switch {
case len(a) < len(b):
return true
case len(a) > len(b):
return false
default:
if bytes.Compare(a, b) < 0 {
return true
}
return false
}
}
func keyBytesFromEncoded(data []byte) []byte {
cborInfo := data[0] & infoBits
if cborInfo <= 23 {
return data[1:]
} else if cborInfo == int8Follows {
return data[2:]
} else if cborInfo == int16Follows {
return data[3:]
} else if cborInfo == int32Follows {
return data[5:]
} else if cborInfo == int64Follows {
return data[9:]
}
panic("shouldnt actually hit this")
}
func (enc *Encoder) writeInt(x int64) error {
if x < 0 {
return enc.tagAuxOut(cborNegint, uint64(-1-x))
}
return enc.tagAuxOut(cborUint, uint64(x))
}
func (enc *Encoder) tagAuxOut(tag byte, x uint64) error {
var err error
if x <= 23 {
// tiny literal
enc.scratch[0] = tag | byte(x)
_, err = enc.out.Write(enc.scratch[:1])
} else if x < 0x0ff {
enc.scratch[0] = tag | int8Follows
enc.scratch[1] = byte(x & 0x0ff)
_, err = enc.out.Write(enc.scratch[:2])
} else if x < 0x0ffff {
enc.scratch[0] = tag | int16Follows
enc.scratch[1] = byte((x >> 8) & 0x0ff)
enc.scratch[2] = byte(x & 0x0ff)
_, err = enc.out.Write(enc.scratch[:3])
} else if x < 0x0ffffffff {
enc.scratch[0] = tag | int32Follows
enc.scratch[1] = byte((x >> 24) & 0x0ff)
enc.scratch[2] = byte((x >> 16) & 0x0ff)
enc.scratch[3] = byte((x >> 8) & 0x0ff)
enc.scratch[4] = byte(x & 0x0ff)
_, err = enc.out.Write(enc.scratch[:5])
} else {
err = enc.tagAux64(tag, x)
}
return err
}
func (enc *Encoder) tagAux64(tag byte, x uint64) error {
enc.scratch[0] = tag | int64Follows
enc.scratch[1] = byte((x >> 56) & 0x0ff)
enc.scratch[2] = byte((x >> 48) & 0x0ff)
enc.scratch[3] = byte((x >> 40) & 0x0ff)
enc.scratch[4] = byte((x >> 32) & 0x0ff)
enc.scratch[5] = byte((x >> 24) & 0x0ff)
enc.scratch[6] = byte((x >> 16) & 0x0ff)
enc.scratch[7] = byte((x >> 8) & 0x0ff)
enc.scratch[8] = byte(x & 0x0ff)
_, err := enc.out.Write(enc.scratch[:9])
return err
}
// Encode a CBOR integer unit. The first argument is the major type, the second
// argument is the integer value. The result is a byte array from 1 to 9 bytes
// depending on the size of the integer value.
//
// The major type (tag argument) must be an integer between 0 and 7 else this
// function panics
//
// If the third parameter is non nil, the slice is reused to construct the
// result to avoid a memory allocation. It should be a slice with a sufficient
// capacity.
func EncodeInt(tag byte, v uint64, buf []byte) []byte {
switch {
case v <= 23:
// tiny literal
return EncodeOpcode(tag, byte(v), buf)
case 23 < v && v < 0x0ff:
return EncodeInt8(tag, uint8(v), buf)
case 0xff <= v && v < 0x0ffff:
return EncodeInt16(tag, uint16(v), buf)
case 0xffff <= v && v < 0x0ffffffff:
return EncodeInt32(tag, uint32(v), buf)
default:
return EncodeInt64(tag, v, buf)
}
}
func EncodeOpcode(tag byte, opcode byte, buf []byte) []byte {
if tag > 7 {
panic("Wrong tag value")
}
return append(buf[0:0],
(tag<<5)|opcode,
)
}
func EncodeInt8(tag byte, v uint8, buf []byte) []byte {
if tag > 7 {
panic("Wrong tag value")
}
return append(buf[0:0],
(tag<<5)|int8Follows,
byte(v&0xff),
)
}
func EncodeInt16(tag byte, v uint16, buf []byte) []byte {
if tag > 7 {
panic("Wrong tag value")
}
return append(buf[0:0],
(tag<<5)|int16Follows,
byte((v>>8)&0xff),
byte(v&0xff),
)
}
func EncodeInt32(tag byte, v uint32, buf []byte) []byte {
if tag > 7 {
panic("Wrong tag value")
}
return append(buf[0:0],
(tag<<5)|int32Follows,
byte((v>>24)&0xff),
byte((v>>16)&0xff),
byte((v>>8)&0xff),
byte(v&0xff),
)
}
func EncodeInt64(tag byte, v uint64, buf []byte) []byte {
if tag > 7 {
panic("Wrong tag value")
}
return append(buf[0:0],
(tag<<5)|int64Follows,
byte((v>>56)&0xff),
byte((v>>48)&0xff),
byte((v>>40)&0xff),
byte((v>>32)&0xff),
byte((v>>24)&0xff),
byte((v>>16)&0xff),
byte((v>>8)&0xff),
byte(v&0xff),
)
}
func (enc *Encoder) writeText(x string) error {
enc.tagAuxOut(cborText, uint64(len(x)))
_, err := io.WriteString(enc.out, x)
return err
}
func (enc *Encoder) writeBytes(x []byte) error {
enc.tagAuxOut(cborBytes, uint64(len(x)))
_, err := enc.out.Write(x)
return err
}
func (enc *Encoder) writeFloat(x float64) error {
return enc.tagAux64(cbor7, math.Float64bits(x))
}
func (enc *Encoder) writeBool(x bool) error {
if x {
return enc.tagAuxOut(cbor7, uint64(cborTrue))
} else {
return enc.tagAuxOut(cbor7, uint64(cborFalse))
}
}
func min(x, y uint64) uint64 {
if x < y {
return x
}
return y
}