diff --git a/bytestring.go b/bytestring.go index 88d64fe8..26f5ef91 100644 --- a/bytestring.go +++ b/bytestring.go @@ -4,31 +4,59 @@ package cbor import ( - "encoding/hex" - "reflect" + "errors" ) -var ( - typeByteString = reflect.TypeOf(NewByteString(nil)) -) +// ByteString represents CBOR byte string (major type 2). ByteString can be used +// when using a Go []byte is not possible or convenient. For example, Go doesn't +// allow []byte as map key, so ByteString can be used to support data formats +// having CBOR map with byte string keys. ByteString can also be used to +// encode invalid UTF-8 string as CBOR byte string. +// See DecOption.MapKeyByteStringMode for more details. +type ByteString string -type ByteString struct { - // XXX: replace with interface{} storing fixed-length byte array? - // We use a string because []byte isn't comparable - data string +// Bytes returns bytes representing ByteString. +func (bs ByteString) Bytes() []byte { + return []byte(bs) } -func NewByteString(data []byte) ByteString { - bs := ByteString{ - data: string(data), - } - return bs -} +// MarshalCBOR encodes ByteString as CBOR byte string (major type 2). +func (bs ByteString) MarshalCBOR() ([]byte, error) { + e := getEncoderBuffer() + defer putEncoderBuffer(e) -func (bs ByteString) Bytes() []byte { - return []byte(bs.data) + // Encode length + encodeHead(e, byte(cborTypeByteString), uint64(len(bs))) + + // Encode data + buf := make([]byte, e.Len()+len(bs)) + n := copy(buf, e.Bytes()) + copy(buf[n:], bs) + + return buf, nil } -func (bs ByteString) String() string { - return hex.EncodeToString([]byte(bs.data)) +// UnmarshalCBOR decodes CBOR byte string (major type 2) to ByteString. +// Decoding CBOR null and CBOR undefined sets ByteString to be empty. +func (bs *ByteString) UnmarshalCBOR(data []byte) error { + if bs == nil { + return errors.New("cbor.ByteString: UnmarshalCBOR on nil pointer") + } + + // Decoding CBOR null and CBOR undefined to ByteString resets data. + // This behavior is similar to decoding CBOR null and CBOR undefined to []byte. + if len(data) == 1 && (data[0] == 0xf6 || data[0] == 0xf7) { + *bs = "" + return nil + } + + d := decoder{data: data, dm: defaultDecMode} + + // Check if CBOR data type is byte string + if typ := d.nextCBORType(); typ != cborTypeByteString { + return &UnmarshalTypeError{CBORType: typ.String(), GoType: typeByteString.String()} + } + + *bs = ByteString(d.parseByteString()) + return nil } diff --git a/bytestring_test.go b/bytestring_test.go new file mode 100644 index 00000000..2f4920ef --- /dev/null +++ b/bytestring_test.go @@ -0,0 +1,101 @@ +// Copyright (c) Faye Amacker. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +package cbor + +import "testing" + +func TestByteString(t *testing.T) { + type s1 struct { + A ByteString `cbor:"a"` + } + type s2 struct { + A *ByteString `cbor:"a"` + } + type s3 struct { + A ByteString `cbor:"a,omitempty"` + } + type s4 struct { + A *ByteString `cbor:"a,omitempty"` + } + + emptybs := ByteString("") + bs := ByteString("\x01\x02\x03\x04") + + testCases := []roundTripTest{ + { + name: "empty", + obj: emptybs, + wantCborData: hexDecode("40"), + }, + { + name: "not empty", + obj: bs, + wantCborData: hexDecode("4401020304"), + }, + { + name: "array", + obj: []ByteString{bs}, + wantCborData: hexDecode("814401020304"), + }, + { + name: "map with ByteString key", + obj: map[ByteString]bool{bs: true}, + wantCborData: hexDecode("a14401020304f5"), + }, + { + name: "empty ByteString field", + obj: s1{}, + wantCborData: hexDecode("a1616140"), + }, + { + name: "not empty ByteString field", + obj: s1{A: bs}, + wantCborData: hexDecode("a161614401020304"), + }, + { + name: "nil *ByteString field", + obj: s2{}, + wantCborData: hexDecode("a16161f6"), + }, + { + name: "empty *ByteString field", + obj: s2{A: &emptybs}, + wantCborData: hexDecode("a1616140"), + }, + { + name: "not empty *ByteString field", + obj: s2{A: &bs}, + wantCborData: hexDecode("a161614401020304"), + }, + { + name: "empty ByteString field with omitempty option", + obj: s3{}, + wantCborData: hexDecode("a0"), + }, + { + name: "not empty ByteString field with omitempty option", + obj: s3{A: bs}, + wantCborData: hexDecode("a161614401020304"), + }, + { + name: "nil *ByteString field with omitempty option", + obj: s4{}, + wantCborData: hexDecode("a0"), + }, + { + name: "empty *ByteString field with omitempty option", + obj: s4{A: &emptybs}, + wantCborData: hexDecode("a1616140"), + }, + { + name: "not empty *ByteString field with omitempty option", + obj: s4{A: &bs}, + wantCborData: hexDecode("a161614401020304"), + }, + } + + em, _ := EncOptions{}.EncMode() + dm, _ := DecOptions{}.DecMode() + testRoundTrip(t, testCases, em, dm) +} diff --git a/decode.go b/decode.go index 524d6571..d2cc039a 100644 --- a/decode.go +++ b/decode.go @@ -239,24 +239,27 @@ func (idm IntDecMode) valid() bool { return idm < maxIntDec } -// MapKeyByteStringMode specifies whether to use a wrapper object for byte strings. +// MapKeyByteStringMode specifies how to decode CBOR byte string (major type 2) +// as Go map key when decoding CBOR map with byte string keys into an empty +// Go interface value. Since Go doesn't allow []byte as map key, this option +// can be used to make CBOR byte string decodable as a Go map key. type MapKeyByteStringMode int const ( - // MapKeyByteStringFail affects how a CBOR byte string as a map key is decoded. - // It makes the parsing fail as Go cannot use []byte as a map key. - MapKeyByteStringFail MapKeyByteStringMode = iota + // MapKeyByteStringForbidden forbids CBOR byte string being decoded as Go map key. + // This is the default setting because Go cannot use []byte as a map key. + MapKeyByteStringForbidden MapKeyByteStringMode = iota - // MapKeyByteStringWrap affects how a CBOR byte string as a map key is decoded. - // It allows the parsing to succeed by wrapping the byte string in a wrapper object - // that can be used as a map key in Go. - MapKeyByteStringWrap + // MapKeyByteStringAllowed allows CBOR byte string being decoded as Go map key. + // Since Go doesn't allow []byte as map key, CBOR byte string is decoded to + // ByteString, which is an alias for Go string. + MapKeyByteStringAllowed - maxMapKeyByteString + maxMapKeyByteStringMode ) -func (bsm MapKeyByteStringMode) valid() bool { - return bsm < maxMapKeyByteString +func (mkbsm MapKeyByteStringMode) valid() bool { + return mkbsm < maxMapKeyByteStringMode } // ExtraDecErrorCond specifies extra conditions that should be treated as errors. @@ -329,7 +332,10 @@ type DecOptions struct { // when decoding CBOR int (major type 0 and 1) to Go interface{}. IntDec IntDecMode - // MapKeyByteString specifies whether to use a wrapper object for byte strings. + // MapKeyByteString specifies how to decode CBOR byte string as map key + // when decoding CBOR map with byte string key into an empty interface value. + // By default, an error is returned when attempting to decode CBOR byte string + // as map key because Go doesn't allow []byte as map key. MapKeyByteString MapKeyByteStringMode // ExtraReturnErrors specifies extra conditions that should be treated as errors. @@ -1236,7 +1242,6 @@ func (d *decoder) parseMap() (interface{}, error) { var k, e interface{} var err, lastErr error keyCount := 0 - typeByteSlice := reflect.TypeOf([]byte{}) for i := 0; (hasSize && i < count) || (!hasSize && !d.foundBreak()); i++ { // Parse CBOR map key. if k, lastErr = d.parse(true); lastErr != nil { @@ -1249,17 +1254,17 @@ func (d *decoder) parseMap() (interface{}, error) { // Detect if CBOR map key can be used as Go map key. rv := reflect.ValueOf(k) - // Wrap byte string if enabled - if rv.IsValid() && rv.Type() == typeByteSlice && d.dm.mapKeyByteString == MapKeyByteStringWrap { - k = NewByteString(rv.Bytes()) - rv = reflect.ValueOf(k) - } if !isHashableValue(rv) { - if err == nil { - err = errors.New("cbor: invalid map key type: " + rv.Type().String()) + if b, ok := k.([]byte); ok && d.dm.mapKeyByteString == MapKeyByteStringAllowed { + // Use decoded []byte as a ByteString map key. + k = ByteString(b) + } else { + if err == nil { + err = errors.New("cbor: invalid map key type: " + rv.Type().String()) + } + d.skip() + continue } - d.skip() - continue } // Parse CBOR map value. @@ -1310,7 +1315,6 @@ func (d *decoder) parseMapToMap(v reflect.Value, tInfo *typeInfo) error { //noli keyIsInterfaceType := keyType == typeIntf // If key type is interface{}, need to check if key value is hashable. var err, lastErr error keyCount := v.Len() - typeByteSlice := reflect.TypeOf([]byte{}) var existingKeys map[interface{}]bool // Store existing map keys, used for detecting duplicate map key. if d.dm.dupMapKey == DupMapKeyEnforcedAPF { existingKeys = make(map[interface{}]bool, keyCount) @@ -1338,11 +1342,6 @@ func (d *decoder) parseMapToMap(v reflect.Value, tInfo *typeInfo) error { //noli d.skip() continue } - // Wrap byte string if enabled - if keyType == typeByteSlice && d.dm.mapKeyByteString == MapKeyByteStringWrap { - keyValue = reflect.ValueOf(NewByteString(keyValue.Bytes())) - keyType = keyValue.Type() - } // Detect if CBOR map key can be used as Go map key. if keyIsInterfaceType && keyValue.Elem().IsValid() { diff --git a/decode_test.go b/decode_test.go index ac65fe7a..cdb8c5ab 100644 --- a/decode_test.go +++ b/decode_test.go @@ -54,116 +54,116 @@ var unmarshalTests = []unmarshalTest{ hexDecode("00"), uint64(0), []interface{}{uint8(0), uint16(0), uint32(0), uint64(0), uint(0), int8(0), int16(0), int32(0), int64(0), int(0), float32(0), float64(0), bigIntOrPanic("0")}, - []reflect.Type{typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag}, + []reflect.Type{typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeByteString}, }, { hexDecode("01"), uint64(1), []interface{}{uint8(1), uint16(1), uint32(1), uint64(1), uint(1), int8(1), int16(1), int32(1), int64(1), int(1), float32(1), float64(1), bigIntOrPanic("1")}, - []reflect.Type{typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag}, + []reflect.Type{typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeByteString}, }, { hexDecode("0a"), uint64(10), []interface{}{uint8(10), uint16(10), uint32(10), uint64(10), uint(10), int8(10), int16(10), int32(10), int64(10), int(10), float32(10), float64(10), bigIntOrPanic("10")}, - []reflect.Type{typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag}, + []reflect.Type{typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeByteString}, }, { hexDecode("17"), uint64(23), []interface{}{uint8(23), uint16(23), uint32(23), uint64(23), uint(23), int8(23), int16(23), int32(23), int64(23), int(23), float32(23), float64(23), bigIntOrPanic("23")}, - []reflect.Type{typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag}, + []reflect.Type{typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeByteString}, }, { hexDecode("1818"), uint64(24), []interface{}{uint8(24), uint16(24), uint32(24), uint64(24), uint(24), int8(24), int16(24), int32(24), int64(24), int(24), float32(24), float64(24), bigIntOrPanic("24")}, - []reflect.Type{typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag}, + []reflect.Type{typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeByteString}, }, { hexDecode("1819"), uint64(25), []interface{}{uint8(25), uint16(25), uint32(25), uint64(25), uint(25), int8(25), int16(25), int32(25), int64(25), int(25), float32(25), float64(25), bigIntOrPanic("25")}, - []reflect.Type{typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag}, + []reflect.Type{typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeByteString}, }, { hexDecode("1864"), uint64(100), []interface{}{uint8(100), uint16(100), uint32(100), uint64(100), uint(100), int8(100), int16(100), int32(100), int64(100), int(100), float32(100), float64(100), bigIntOrPanic("100")}, - []reflect.Type{typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag}, + []reflect.Type{typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeByteString}, }, { hexDecode("1903e8"), uint64(1000), []interface{}{uint16(1000), uint32(1000), uint64(1000), uint(1000), int16(1000), int32(1000), int64(1000), int(1000), float32(1000), float64(1000), bigIntOrPanic("1000")}, - []reflect.Type{typeUint8, typeInt8, typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag}, + []reflect.Type{typeUint8, typeInt8, typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeByteString}, }, { hexDecode("1a000f4240"), uint64(1000000), []interface{}{uint32(1000000), uint64(1000000), uint(1000000), int32(1000000), int64(1000000), int(1000000), float32(1000000), float64(1000000), bigIntOrPanic("1000000")}, - []reflect.Type{typeUint8, typeUint16, typeInt8, typeInt16, typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag}, + []reflect.Type{typeUint8, typeUint16, typeInt8, typeInt16, typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeByteString}, }, { hexDecode("1b000000e8d4a51000"), uint64(1000000000000), []interface{}{uint64(1000000000000), uint(1000000000000), int64(1000000000000), int(1000000000000), float32(1000000000000), float64(1000000000000), bigIntOrPanic("1000000000000")}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeInt8, typeInt16, typeInt32, typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeInt8, typeInt16, typeInt32, typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeByteString}, }, { hexDecode("1bffffffffffffffff"), uint64(18446744073709551615), []interface{}{uint64(18446744073709551615), uint(18446744073709551615), float32(18446744073709551615), float64(18446744073709551615), bigIntOrPanic("18446744073709551615")}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeInt8, typeInt16, typeInt32, typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeInt8, typeInt16, typeInt32, typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeByteString}, }, // negative integer { hexDecode("20"), int64(-1), []interface{}{int8(-1), int16(-1), int32(-1), int64(-1), int(-1), float32(-1), float64(-1), bigIntOrPanic("-1")}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeByteString}, }, { hexDecode("29"), int64(-10), []interface{}{int8(-10), int16(-10), int32(-10), int64(-10), int(-10), float32(-10), float64(-10), bigIntOrPanic("-10")}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeByteString}, }, { hexDecode("3863"), int64(-100), []interface{}{int8(-100), int16(-100), int32(-100), int64(-100), int(-100), float32(-100), float64(-100), bigIntOrPanic("-100")}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeByteString}, }, { hexDecode("3903e7"), int64(-1000), []interface{}{int16(-1000), int32(-1000), int64(-1000), int(-1000), float32(-1000), float64(-1000), bigIntOrPanic("-1000")}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeByteString}, }, { hexDecode("3bffffffffffffffff"), bigIntOrPanic("-18446744073709551616"), []interface{}{bigIntOrPanic("-18446744073709551616")}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeByteString}, }, // CBOR value -18446744073709551616 overflows Go's int64, see TestNegIntOverflow // byte string { hexDecode("40"), []byte{}, - []interface{}{[]byte{}, [0]byte{}, [1]byte{0}, [5]byte{0, 0, 0, 0, 0}}, + []interface{}{[]byte{}, [0]byte{}, [1]byte{0}, [5]byte{0, 0, 0, 0, 0}, ByteString("")}, []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, }, { hexDecode("4401020304"), []byte{1, 2, 3, 4}, - []interface{}{[]byte{1, 2, 3, 4}, [0]byte{}, [1]byte{1}, [5]byte{1, 2, 3, 4, 0}}, + []interface{}{[]byte{1, 2, 3, 4}, [0]byte{}, [1]byte{1}, [5]byte{1, 2, 3, 4, 0}, ByteString("\x01\x02\x03\x04")}, []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, }, { hexDecode("5f42010243030405ff"), []byte{1, 2, 3, 4, 5}, - []interface{}{[]byte{1, 2, 3, 4, 5}, [0]byte{}, [1]byte{1}, [5]byte{1, 2, 3, 4, 5}, [6]byte{1, 2, 3, 4, 5, 0}}, + []interface{}{[]byte{1, 2, 3, 4, 5}, [0]byte{}, [1]byte{1}, [5]byte{1, 2, 3, 4, 5}, [6]byte{1, 2, 3, 4, 5, 0}, ByteString("\x01\x02\x03\x04\x05")}, []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, }, // text string @@ -171,80 +171,80 @@ var unmarshalTests = []unmarshalTest{ hexDecode("60"), "", []interface{}{""}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, }, { hexDecode("6161"), "a", []interface{}{"a"}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, }, { hexDecode("6449455446"), "IETF", []interface{}{"IETF"}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, }, { hexDecode("62225c"), "\"\\", []interface{}{"\"\\"}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, }, { hexDecode("62c3bc"), "ü", []interface{}{"ü"}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, }, { hexDecode("63e6b0b4"), "水", []interface{}{"水"}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, }, { hexDecode("64f0908591"), "𐅑", []interface{}{"𐅑"}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, }, { hexDecode("7f657374726561646d696e67ff"), "streaming", []interface{}{"streaming"}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, }, // array { hexDecode("80"), []interface{}{}, []interface{}{[]interface{}{}, []byte{}, []string{}, []int{}, [0]int{}, [1]int{0}, [5]int{0}, []float32{}, []float64{}}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeString, typeBool, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeString, typeBool, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, }, { hexDecode("83010203"), []interface{}{uint64(1), uint64(2), uint64(3)}, []interface{}{[]interface{}{uint64(1), uint64(2), uint64(3)}, []byte{1, 2, 3}, []int{1, 2, 3}, []uint{1, 2, 3}, [0]int{}, [1]int{1}, [3]int{1, 2, 3}, [5]int{1, 2, 3, 0, 0}, []float32{1, 2, 3}, []float64{1, 2, 3}}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeString, typeBool, typeStringSlice, typeMapStringInt, reflect.TypeOf([3]string{}), typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeString, typeBool, typeStringSlice, typeMapStringInt, reflect.TypeOf([3]string{}), typeTag, typeRawTag, typeBigInt, typeByteString}, }, { hexDecode("8301820203820405"), []interface{}{uint64(1), []interface{}{uint64(2), uint64(3)}, []interface{}{uint64(4), uint64(5)}}, []interface{}{[]interface{}{uint64(1), []interface{}{uint64(2), uint64(3)}, []interface{}{uint64(4), uint64(5)}}, [...]interface{}{uint64(1), []interface{}{uint64(2), uint64(3)}, []interface{}{uint64(4), uint64(5)}}}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeString, typeBool, typeStringSlice, typeMapStringInt, reflect.TypeOf([3]string{}), typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeString, typeBool, typeStringSlice, typeMapStringInt, reflect.TypeOf([3]string{}), typeTag, typeRawTag, typeBigInt, typeByteString}, }, { hexDecode("83018202039f0405ff"), []interface{}{uint64(1), []interface{}{uint64(2), uint64(3)}, []interface{}{uint64(4), uint64(5)}}, []interface{}{[]interface{}{uint64(1), []interface{}{uint64(2), uint64(3)}, []interface{}{uint64(4), uint64(5)}}, [...]interface{}{uint64(1), []interface{}{uint64(2), uint64(3)}, []interface{}{uint64(4), uint64(5)}}}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeString, typeBool, typeStringSlice, typeMapStringInt, reflect.TypeOf([3]string{}), typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeString, typeBool, typeStringSlice, typeMapStringInt, reflect.TypeOf([3]string{}), typeTag, typeRawTag, typeBigInt, typeByteString}, }, { hexDecode("83019f0203ff820405"), []interface{}{uint64(1), []interface{}{uint64(2), uint64(3)}, []interface{}{uint64(4), uint64(5)}}, []interface{}{[]interface{}{uint64(1), []interface{}{uint64(2), uint64(3)}, []interface{}{uint64(4), uint64(5)}}, [...]interface{}{uint64(1), []interface{}{uint64(2), uint64(3)}, []interface{}{uint64(4), uint64(5)}}}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeString, typeBool, typeStringSlice, typeMapStringInt, reflect.TypeOf([3]string{}), typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeString, typeBool, typeStringSlice, typeMapStringInt, reflect.TypeOf([3]string{}), typeTag, typeRawTag, typeBigInt, typeByteString}, }, { hexDecode("98190102030405060708090a0b0c0d0e0f101112131415161718181819"), @@ -260,25 +260,25 @@ var unmarshalTests = []unmarshalTest{ [30]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0}, []float32{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeString, typeBool, typeStringSlice, typeMapStringInt, reflect.TypeOf([3]string{}), typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeString, typeBool, typeStringSlice, typeMapStringInt, reflect.TypeOf([3]string{}), typeTag, typeRawTag, typeBigInt, typeByteString}, }, { hexDecode("9fff"), []interface{}{}, []interface{}{[]interface{}{}, []byte{}, []string{}, []int{}, [0]int{}, [1]int{0}, [5]int{0, 0, 0, 0, 0}, []float32{}, []float64{}}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeString, typeBool, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeString, typeBool, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, }, { hexDecode("9f018202039f0405ffff"), []interface{}{uint64(1), []interface{}{uint64(2), uint64(3)}, []interface{}{uint64(4), uint64(5)}}, []interface{}{[]interface{}{uint64(1), []interface{}{uint64(2), uint64(3)}, []interface{}{uint64(4), uint64(5)}}, [...]interface{}{uint64(1), []interface{}{uint64(2), uint64(3)}, []interface{}{uint64(4), uint64(5)}}}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeString, typeBool, typeStringSlice, typeMapStringInt, reflect.TypeOf([3]string{}), typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeString, typeBool, typeStringSlice, typeMapStringInt, reflect.TypeOf([3]string{}), typeTag, typeRawTag, typeBigInt, typeByteString}, }, { hexDecode("9f01820203820405ff"), []interface{}{uint64(1), []interface{}{uint64(2), uint64(3)}, []interface{}{uint64(4), uint64(5)}}, []interface{}{[]interface{}{uint64(1), []interface{}{uint64(2), uint64(3)}, []interface{}{uint64(4), uint64(5)}}, [...]interface{}{uint64(1), []interface{}{uint64(2), uint64(3)}, []interface{}{uint64(4), uint64(5)}}}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeString, typeBool, typeStringSlice, typeMapStringInt, reflect.TypeOf([3]string{}), typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeString, typeBool, typeStringSlice, typeMapStringInt, reflect.TypeOf([3]string{}), typeTag, typeRawTag, typeBigInt, typeByteString}, }, { hexDecode("9f0102030405060708090a0b0c0d0e0f101112131415161718181819ff"), @@ -294,39 +294,39 @@ var unmarshalTests = []unmarshalTest{ [30]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0}, []float32{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeString, typeBool, typeStringSlice, typeMapStringInt, reflect.TypeOf([3]string{}), typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeString, typeBool, typeStringSlice, typeMapStringInt, reflect.TypeOf([3]string{}), typeTag, typeRawTag, typeBigInt, typeByteString}, }, { hexDecode("826161a161626163"), []interface{}{"a", map[interface{}]interface{}{"b": "c"}}, []interface{}{[]interface{}{"a", map[interface{}]interface{}{"b": "c"}}, [...]interface{}{"a", map[interface{}]interface{}{"b": "c"}}}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeString, typeBool, typeByteArray, typeStringSlice, typeMapStringInt, reflect.TypeOf([3]string{}), typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeString, typeBool, typeByteArray, typeStringSlice, typeMapStringInt, reflect.TypeOf([3]string{}), typeTag, typeRawTag, typeBigInt, typeByteString}, }, { hexDecode("826161bf61626163ff"), []interface{}{"a", map[interface{}]interface{}{"b": "c"}}, []interface{}{[]interface{}{"a", map[interface{}]interface{}{"b": "c"}}, [...]interface{}{"a", map[interface{}]interface{}{"b": "c"}}}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeString, typeBool, typeByteArray, typeStringSlice, typeMapStringInt, reflect.TypeOf([3]string{}), typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeString, typeBool, typeByteArray, typeStringSlice, typeMapStringInt, reflect.TypeOf([3]string{}), typeTag, typeRawTag, typeBigInt, typeByteString}, }, // map { hexDecode("a0"), map[interface{}]interface{}{}, []interface{}{map[interface{}]interface{}{}, map[string]bool{}, map[string]int{}, map[int]string{}, map[int]bool{}}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeByteSlice, typeByteArray, typeString, typeBool, typeIntSlice, typeTag, typeRawTag}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeByteSlice, typeByteArray, typeString, typeBool, typeIntSlice, typeTag, typeRawTag, typeByteString}, }, { hexDecode("a201020304"), map[interface{}]interface{}{uint64(1): uint64(2), uint64(3): uint64(4)}, []interface{}{map[interface{}]interface{}{uint64(1): uint64(2), uint64(3): uint64(4)}, map[uint]int{1: 2, 3: 4}, map[int]uint{1: 2, 3: 4}}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeByteSlice, typeByteArray, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeByteSlice, typeByteArray, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeByteString}, }, { hexDecode("a26161016162820203"), map[interface{}]interface{}{"a": uint64(1), "b": []interface{}{uint64(2), uint64(3)}}, []interface{}{map[interface{}]interface{}{"a": uint64(1), "b": []interface{}{uint64(2), uint64(3)}}, map[string]interface{}{"a": uint64(1), "b": []interface{}{uint64(2), uint64(3)}}}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeByteSlice, typeByteArray, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeByteSlice, typeByteArray, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeByteString}, }, { hexDecode("a56161614161626142616361436164614461656145"), @@ -334,34 +334,34 @@ var unmarshalTests = []unmarshalTest{ []interface{}{map[interface{}]interface{}{"a": "A", "b": "B", "c": "C", "d": "D", "e": "E"}, map[string]interface{}{"a": "A", "b": "B", "c": "C", "d": "D", "e": "E"}, map[string]string{"a": "A", "b": "B", "c": "C", "d": "D", "e": "E"}}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeByteSlice, typeByteArray, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeByteSlice, typeByteArray, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeByteString}, }, { hexDecode("bf61610161629f0203ffff"), map[interface{}]interface{}{"a": uint64(1), "b": []interface{}{uint64(2), uint64(3)}}, []interface{}{map[interface{}]interface{}{"a": uint64(1), "b": []interface{}{uint64(2), uint64(3)}}, map[string]interface{}{"a": uint64(1), "b": []interface{}{uint64(2), uint64(3)}}}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeByteSlice, typeByteArray, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeByteSlice, typeByteArray, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeByteString}, }, { hexDecode("bf6346756ef563416d7421ff"), map[interface{}]interface{}{"Fun": true, "Amt": int64(-2)}, []interface{}{map[interface{}]interface{}{"Fun": true, "Amt": int64(-2)}, map[string]interface{}{"Fun": true, "Amt": int64(-2)}}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeByteSlice, typeByteArray, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeByteSlice, typeByteArray, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeByteString}, }, // tag { hexDecode("c074323031332d30332d32315432303a30343a30305a"), time.Date(2013, 3, 21, 20, 4, 0, 0, time.UTC), // 2013-03-21 20:04:00 +0000 UTC []interface{}{"2013-03-21T20:04:00Z", time.Date(2013, 3, 21, 20, 4, 0, 0, time.UTC), Tag{0, "2013-03-21T20:04:00Z"}, RawTag{0, hexDecode("74323031332d30332d32315432303a30343a30305a")}}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeBigInt, typeByteString}, }, // 0: standard date/time { hexDecode("c11a514b67b0"), time.Date(2013, 3, 21, 20, 4, 0, 0, time.UTC), // 2013-03-21 20:04:00 +0000 UTC []interface{}{uint32(1363896240), uint64(1363896240), int32(1363896240), int64(1363896240), float32(1363896240), float64(1363896240), time.Date(2013, 3, 21, 20, 4, 0, 0, time.UTC), Tag{1, uint64(1363896240)}, RawTag{1, hexDecode("1a514b67b0")}}, - []reflect.Type{typeUint8, typeUint16, typeInt8, typeInt16, typeByteSlice, typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt}, + []reflect.Type{typeUint8, typeUint16, typeInt8, typeInt16, typeByteSlice, typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeByteString}, }, // 1: epoch-based date/time { hexDecode("c249010000000000000000"), @@ -381,7 +381,7 @@ var unmarshalTests = []unmarshalTest{ // Decode to big.Int bigIntOrPanic("18446744073709551616"), }, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeIntSlice, typeMapStringInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeIntSlice, typeMapStringInt, typeByteString}, }, // 2: positive bignum: 18446744073709551616 { hexDecode("c349010000000000000000"), @@ -401,44 +401,44 @@ var unmarshalTests = []unmarshalTest{ // Decode to big.Int bigIntOrPanic("-18446744073709551617"), }, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeIntSlice, typeMapStringInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeIntSlice, typeMapStringInt, typeByteString}, }, // 3: negative bignum: -18446744073709551617 { hexDecode("c1fb41d452d9ec200000"), time.Date(2013, 3, 21, 20, 4, 0, 500000000, time.UTC), // 2013-03-21 20:04:00.5 +0000 UTC []interface{}{float32(1363896240.5), float64(1363896240.5), time.Date(2013, 3, 21, 20, 4, 0, 500000000, time.UTC), Tag{1, float64(1363896240.5)}, RawTag{1, hexDecode("fb41d452d9ec200000")}}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteSlice, typeByteArray, typeString, typeBool, typeIntSlice, typeMapStringInt, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteSlice, typeByteArray, typeString, typeBool, typeIntSlice, typeMapStringInt, typeBigInt, typeByteString}, }, // 1: epoch-based date/time { hexDecode("d74401020304"), Tag{23, []byte{0x01, 0x02, 0x03, 0x04}}, []interface{}{[]byte{0x01, 0x02, 0x03, 0x04}, [0]byte{}, [1]byte{0x01}, [3]byte{0x01, 0x02, 0x03}, [...]byte{0x01, 0x02, 0x03, 0x04}, [5]byte{0x01, 0x02, 0x03, 0x04, 0x00}, Tag{23, []byte{0x01, 0x02, 0x03, 0x04}}, RawTag{23, hexDecode("4401020304")}}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeIntSlice, typeMapStringInt, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeIntSlice, typeMapStringInt, typeBigInt, typeByteString}, }, // 23: expected conversion to base16 encoding { hexDecode("d818456449455446"), Tag{24, []byte{0x64, 0x49, 0x45, 0x54, 0x46}}, []interface{}{[]byte{0x64, 0x49, 0x45, 0x54, 0x46}, [0]byte{}, [1]byte{0x64}, [3]byte{0x64, 0x49, 0x45}, [...]byte{0x64, 0x49, 0x45, 0x54, 0x46}, [6]byte{0x64, 0x49, 0x45, 0x54, 0x46, 0x00}, Tag{24, []byte{0x64, 0x49, 0x45, 0x54, 0x46}}, RawTag{24, hexDecode("456449455446")}}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeIntSlice, typeMapStringInt, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeIntSlice, typeMapStringInt, typeBigInt, typeByteString}, }, // 24: encoded cborBytes data item { hexDecode("d82076687474703a2f2f7777772e6578616d706c652e636f6d"), Tag{32, "http://www.example.com"}, []interface{}{"http://www.example.com", Tag{32, "http://www.example.com"}, RawTag{32, hexDecode("76687474703a2f2f7777772e6578616d706c652e636f6d")}}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeBigInt, typeByteString}, }, // 32: URI // primitives { hexDecode("f4"), false, []interface{}{false, SimpleValue(20)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeByteArray, typeByteSlice, typeString, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeByteArray, typeByteSlice, typeString, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, }, { hexDecode("f5"), true, []interface{}{true, SimpleValue(21)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeByteArray, typeByteSlice, typeString, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeByteArray, typeByteSlice, typeString, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, }, { hexDecode("f6"), @@ -456,7 +456,7 @@ var unmarshalTests = []unmarshalTest{ hexDecode("f0"), SimpleValue(16), []interface{}{SimpleValue(16), uint8(16), uint16(16), uint32(16), uint64(16), uint(16), int8(16), int16(16), int32(16), int64(16), int(16), float32(16), float64(16), bigIntOrPanic("16")}, - []reflect.Type{typeByteSlice, typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag}, + []reflect.Type{typeByteSlice, typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeByteString}, }, // This example is not well-formed because Simple value (with 5-bit value 24) must be >= 32. // See RFC 7049 section 2.3 for details, instead of the incorrect example in RFC 7049 Appendex A. @@ -473,45 +473,45 @@ var unmarshalTests = []unmarshalTest{ hexDecode("f820"), SimpleValue(32), []interface{}{SimpleValue(32), uint8(32), uint16(32), uint32(32), uint64(32), uint(32), int8(32), int16(32), int32(32), int64(32), int(32), float32(32), float64(32), bigIntOrPanic("32")}, - []reflect.Type{typeByteSlice, typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag}, + []reflect.Type{typeByteSlice, typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeByteString}, }, { hexDecode("f8ff"), SimpleValue(255), []interface{}{SimpleValue(255), uint8(255), uint16(255), uint32(255), uint64(255), uint(255), int16(255), int32(255), int64(255), int(255), float32(255), float64(255), bigIntOrPanic("255")}, - []reflect.Type{typeByteSlice, typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag}, + []reflect.Type{typeByteSlice, typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeByteString}, }, // More testcases not covered by https://tools.ietf.org/html/rfc7049#appendix-A. { hexDecode("5fff"), // empty indefinite length byte string []byte{}, - []interface{}{[]byte{}, [0]byte{}, [1]byte{0x00}}, + []interface{}{[]byte{}, [0]byte{}, [1]byte{0x00}, ByteString("")}, []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, }, { hexDecode("7fff"), // empty indefinite length text string "", []interface{}{""}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, }, { hexDecode("bfff"), // empty indefinite length map map[interface{}]interface{}{}, []interface{}{map[interface{}]interface{}{}, map[string]bool{}, map[string]int{}, map[int]string{}, map[int]bool{}}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeTag, typeRawTag}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeTag, typeRawTag, typeByteString}, }, // More test data with tags { hexDecode("c13a0177f2cf"), // 1969-03-21T20:04:00Z, tag 1 with negative integer as epoch time time.Date(1969, 3, 21, 20, 4, 0, 0, time.UTC), []interface{}{int32(-24638160), int64(-24638160), int32(-24638160), int64(-24638160), float32(-24638160), float64(-24638160), time.Date(1969, 3, 21, 20, 4, 0, 0, time.UTC), Tag{1, int64(-24638160)}, RawTag{1, hexDecode("3a0177f2cf")}, bigIntOrPanic("-24638160")}, - []reflect.Type{typeUint8, typeUint16, typeInt8, typeInt16, typeByteSlice, typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt}, + []reflect.Type{typeUint8, typeUint16, typeInt8, typeInt16, typeByteSlice, typeString, typeBool, typeByteArray, typeIntSlice, typeMapStringInt, typeByteString}, }, { hexDecode("d83dd183010203"), // 61(17([1, 2, 3])), nested tags 61 and 17 Tag{61, Tag{17, []interface{}{uint64(1), uint64(2), uint64(3)}}}, []interface{}{[]interface{}{uint64(1), uint64(2), uint64(3)}, []byte{1, 2, 3}, [0]byte{}, [1]byte{1}, [3]byte{1, 2, 3}, [5]byte{1, 2, 3, 0, 0}, []int{1, 2, 3}, []uint{1, 2, 3}, [...]int{1, 2, 3}, []float32{1, 2, 3}, []float64{1, 2, 3}, Tag{61, Tag{17, []interface{}{uint64(1), uint64(2), uint64(3)}}}, RawTag{61, hexDecode("d183010203")}}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeString, typeBool, typeStringSlice, typeMapStringInt, reflect.TypeOf([3]string{})}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeFloat64, typeString, typeBool, typeStringSlice, typeMapStringInt, reflect.TypeOf([3]string{}), typeByteString}, }, } @@ -533,77 +533,77 @@ var unmarshalFloatTests = []unmarshalFloatTest{ hexDecode("f90000"), float64(0.0), []interface{}{float32(0.0), float64(0.0)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 0.0, }, { hexDecode("f98000"), float64(-0.0), //nolint:staticcheck // we know -0.0 is 0.0 in Go []interface{}{float32(-0.0), float64(-0.0)}, //nolint:staticcheck // we know -0.0 is 0.0 in Go - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 0.0, }, { hexDecode("f93c00"), float64(1.0), []interface{}{float32(1.0), float64(1.0)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 0.0, }, { hexDecode("f93e00"), float64(1.5), []interface{}{float32(1.5), float64(1.5)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 0.0, }, { hexDecode("f97bff"), float64(65504.0), []interface{}{float32(65504.0), float64(65504.0)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 0.0, }, { hexDecode("f90001"), // float16 subnormal value float64(5.960464477539063e-08), []interface{}{float32(5.960464477539063e-08), float64(5.960464477539063e-08)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 1e-16, }, { hexDecode("f90400"), float64(6.103515625e-05), []interface{}{float32(6.103515625e-05), float64(6.103515625e-05)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 1e-16, }, { hexDecode("f9c400"), float64(-4.0), []interface{}{float32(-4.0), float64(-4.0)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 0.0, }, { hexDecode("f97c00"), math.Inf(1), []interface{}{math.Float32frombits(0x7f800000), math.Inf(1)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 0.0, }, { hexDecode("f97e00"), math.NaN(), []interface{}{math.Float32frombits(0x7fc00000), math.NaN()}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 0.0, }, { hexDecode("f9fc00"), math.Inf(-1), []interface{}{math.Float32frombits(0xff800000), math.Inf(-1)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 0.0, }, // float32 @@ -611,35 +611,35 @@ var unmarshalFloatTests = []unmarshalFloatTest{ hexDecode("fa47c35000"), float64(100000.0), []interface{}{float32(100000.0), float64(100000.0)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 0.0, }, { hexDecode("fa7f7fffff"), float64(3.4028234663852886e+38), []interface{}{float32(3.4028234663852886e+38), float64(3.4028234663852886e+38)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 1e-9, }, { hexDecode("fa7f800000"), math.Inf(1), []interface{}{math.Float32frombits(0x7f800000), math.Inf(1)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 0.0, }, { hexDecode("fa7fc00000"), math.NaN(), []interface{}{math.Float32frombits(0x7fc00000), math.NaN()}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 0.0, }, { hexDecode("faff800000"), math.Inf(-1), []interface{}{math.Float32frombits(0xff800000), math.Inf(-1)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 0.0, }, // float64 @@ -647,42 +647,42 @@ var unmarshalFloatTests = []unmarshalFloatTest{ hexDecode("fb3ff199999999999a"), float64(1.1), []interface{}{float32(1.1), float64(1.1)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 1e-9, }, { hexDecode("fb7e37e43c8800759c"), float64(1.0e+300), []interface{}{float64(1.0e+300)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeFloat32, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 1e-9, }, { hexDecode("fbc010666666666666"), float64(-4.1), []interface{}{float32(-4.1), float64(-4.1)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 1e-9, }, { hexDecode("fb7ff0000000000000"), math.Inf(1), []interface{}{math.Float32frombits(0x7f800000), math.Inf(1)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 0.0, }, { hexDecode("fb7ff8000000000000"), math.NaN(), []interface{}{math.Float32frombits(0x7fc00000), math.NaN()}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 0.0, }, { hexDecode("fbfff0000000000000"), math.Inf(-1), []interface{}{math.Float32frombits(0xff800000), math.Inf(-1)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 0.0, }, @@ -691,28 +691,28 @@ var unmarshalFloatTests = []unmarshalFloatTest{ hexDecode("f903ff"), float64(0.000060976), []interface{}{float32(0.000060976), float64(0.000060976)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 1e-9, }, { hexDecode("f93bff"), float64(0.999511719), []interface{}{float32(0.999511719), float64(0.999511719)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 1e-9, }, { hexDecode("f93c01"), float64(1.000976563), []interface{}{float32(1.000976563), float64(1.000976563)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 1e-9, }, { hexDecode("f93555"), float64(0.333251953125), []interface{}{float32(0.333251953125), float64(0.333251953125)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 1e-9, }, // CBOR test data "canonNums" are from https://github.com/cbor-wg/cbor-test-vectors @@ -720,70 +720,70 @@ var unmarshalFloatTests = []unmarshalFloatTest{ hexDecode("f9bd00"), float64(-1.25), []interface{}{float32(-1.25), float64(-1.25)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 0.0, }, { hexDecode("f93e00"), float64(1.5), []interface{}{float32(1.5), float64(1.5)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 0.0, }, { hexDecode("fb4024333333333333"), float64(10.1), []interface{}{float32(10.1), float64(10.1)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 0.0, }, { hexDecode("f90001"), float64(5.960464477539063e-8), []interface{}{float32(5.960464477539063e-8), float64(5.960464477539063e-8)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 0.0, }, { hexDecode("fa7f7fffff"), float64(3.4028234663852886e+38), []interface{}{float32(3.4028234663852886e+38), float64(3.4028234663852886e+38)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 0.0, }, { hexDecode("f90400"), float64(0.00006103515625), []interface{}{float32(0.00006103515625), float64(0.00006103515625)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 0.0, }, { hexDecode("f933ff"), float64(0.2498779296875), []interface{}{float32(0.2498779296875), float64(0.2498779296875)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 0.0, }, { hexDecode("fa33000000"), float64(2.9802322387695312e-8), []interface{}{float32(2.9802322387695312e-8), float64(2.9802322387695312e-8)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 0.0, }, { hexDecode("fa33333866"), float64(4.1727979294137185e-8), []interface{}{float32(4.1727979294137185e-8), float64(4.1727979294137185e-8)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 0.0, }, { hexDecode("fa37002000"), float64(0.000007636845111846924), []interface{}{float32(0.000007636845111846924), float64(0.000007636845111846924)}, - []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt}, + []reflect.Type{typeUint8, typeUint16, typeUint32, typeUint64, typeInt8, typeInt16, typeInt32, typeInt64, typeByteArray, typeByteSlice, typeString, typeBool, typeIntSlice, typeMapStringInt, typeTag, typeRawTag, typeBigInt, typeByteString}, 0.0, }, } @@ -1194,6 +1194,9 @@ func TestUnmarshalNil(t *testing.T) { {"slice", []string{"hello", "world"}, []string(nil)}, {"map", map[string]bool{"hello": true, "goodbye": false}, map[string]bool(nil)}, + // Unmarshalling CBOR null to ByteString (string wrapper for []byte) resets ByteString to empty string. + {"cbor.ByteString", ByteString("\x01\x02\x03"), ByteString("")}, + // Unmarshalling CBOR null to time.Time is a no-op. {"time.Time", time.Date(2020, time.January, 2, 3, 4, 5, 6, time.UTC), time.Date(2020, time.January, 2, 3, 4, 5, 6, time.UTC)}, @@ -4677,18 +4680,18 @@ func TestMapKeyByteString(t *testing.T) { mapKeyByteString MapKeyByteStringMode }{ { - name: "CBOR map with byte string key with MapKeyByteStringFail", - cborData: hexDecode("A143ABCDEF187B"), + name: "CBOR map with byte string key with MapKeyByteStringForbidden", + cborData: hexDecode("a143abcdef187b"), wantErrorMsg: "cbor: invalid map key type: []uint8", - mapKeyByteString: MapKeyByteStringFail, + mapKeyByteString: MapKeyByteStringForbidden, }, { - name: "CBOR map with byte string key with MapKeyByteStringWrap", - cborData: hexDecode("A143ABCDEF187B"), + name: "CBOR map with byte string key with MapKeyByteStringAllowed", + cborData: hexDecode("a143abcdef187b"), wantObj: map[interface{}]interface{}{ - NewByteString(hexDecode("abcdef")): uint64(123), + ByteString("\xab\xcd\xef"): uint64(123), }, - mapKeyByteString: MapKeyByteStringWrap, + mapKeyByteString: MapKeyByteStringAllowed, }, } for _, tc := range testCases { diff --git a/encode.go b/encode.go index ae2920ed..ee2c92a8 100644 --- a/encode.go +++ b/encode.go @@ -786,10 +786,6 @@ func encodeFloat64(e *encoderBuffer, f64 float64) error { } func encodeByteString(e *encoderBuffer, em *encMode, v reflect.Value) error { - // Unwrap byte string - if v.Type() == typeByteString { - v = reflect.ValueOf(v.Interface().(ByteString).Bytes()) - } vk := v.Kind() if vk == reflect.Slice && v.IsNil() { e.Write(cborNil) @@ -1294,6 +1290,7 @@ var ( typeMarshaler = reflect.TypeOf((*Marshaler)(nil)).Elem() typeBinaryMarshaler = reflect.TypeOf((*encoding.BinaryMarshaler)(nil)).Elem() typeRawMessage = reflect.TypeOf(RawMessage(nil)) + typeByteString = reflect.TypeOf(ByteString("")) ) func getEncodeFuncInternal(t reflect.Type) (encodeFunc, isEmptyFunc) { @@ -1313,7 +1310,7 @@ func getEncodeFuncInternal(t reflect.Type) (encodeFunc, isEmptyFunc) { case typeRawMessage: return encodeMarshalerType, isEmptySlice case typeByteString: - return encodeByteString, isEmptyByteString + return encodeMarshalerType, isEmptyString } if reflect.PtrTo(t).Implements(typeMarshaler) { return encodeMarshalerType, alwaysNotEmpty @@ -1413,10 +1410,6 @@ func isEmptySlice(v reflect.Value) (bool, error) { return v.Len() == 0, nil } -func isEmptyByteString(v reflect.Value) (bool, error) { - return len(v.Interface().(ByteString).Bytes()) == 0, nil -} - func isEmptyMap(v reflect.Value) (bool, error) { return v.Len() == 0, nil } diff --git a/encode_test.go b/encode_test.go index 03300588..0c53fc09 100644 --- a/encode_test.go +++ b/encode_test.go @@ -3653,34 +3653,3 @@ func TestMapWithSimpleValueKey(t *testing.T) { t.Errorf("Marshal(%v) = 0x%x, want 0x%x", v, encodedData, data) } } - -func TestMarshalByteStringUnwrap(t *testing.T) { - testCases := []struct { - name string - value interface{} - wantCborData []byte - }{ - { - name: "map with ByteString keys", - value: map[interface{}]interface{}{ - NewByteString(hexDecode("abcdef")): uint64(123), - }, - wantCborData: hexDecode("A143ABCDEF187B"), - }, - } - dm, err := EncOptions{}.EncMode() - if err != nil { - t.Errorf("EncMode() returned an error %v", err) - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - fmt.Printf("tc.value = %#v\n", tc.value) - if b, err := dm.Marshal(tc.value); err != nil { - t.Errorf("Marshal(%v) returned error %v", tc.value, err) - } else if !bytes.Equal(b, tc.wantCborData) { - t.Errorf("Marshal(%v) = 0x%x, want 0x%x", tc.value, b, tc.wantCborData) - } - }) - } -}