Support CBOR bignum in NextSize() (#325)
Add requested feature in stream-mode branch.
This commit is contained in:
parent
8cc0fef5e5
commit
1fafba071f
@ -158,13 +158,14 @@ func (sd *StreamDecoder) NextType() (Type, error) {
|
||||
return UndefinedType, errors.New("cbor: unrecognized type")
|
||||
}
|
||||
|
||||
// NextSize returns the next CBOR data size for four CBOR types.
|
||||
// NextSize returns the next CBOR data size for five types.
|
||||
// Returned uint64 represents different kind of size depending on
|
||||
// the CBOR type:
|
||||
// - byte string: length (in bytes) of byte string
|
||||
// - text string: length (in bytes) of text string
|
||||
// - array: number of array elements
|
||||
// - map: number of key/value pairs
|
||||
// the type:
|
||||
// - ByteStringType : length (in bytes) of byte string
|
||||
// - TextStringType : length (in bytes) of text string
|
||||
// - ArrayType : number of array elements
|
||||
// - MapType : number of key/value pairs
|
||||
// - BigNumType : length (in bytes) of encoded big number
|
||||
// Error is returned for indef length data and unsupported types.
|
||||
// Support for additional types wasn't added for simplicity.
|
||||
func (sd *StreamDecoder) NextSize() (uint64, error) {
|
||||
@ -173,12 +174,20 @@ func (sd *StreamDecoder) NextSize() (uint64, error) {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
ai := sd.dec.d.data[sd.dec.d.off] & 0x1f
|
||||
off := sd.dec.d.off
|
||||
|
||||
if t == BigNumType {
|
||||
// NextType() validates CBOR tag data (tag number + tag content),
|
||||
// so it's safe to increment offset to access tag content.
|
||||
off++ // Increment offset to point to tag content
|
||||
t = ByteStringType // tag content type is CBOR byte string
|
||||
}
|
||||
|
||||
switch t {
|
||||
|
||||
case ByteStringType, TextStringType, ArrayType, MapType:
|
||||
off := sd.dec.d.off + 1
|
||||
ai := sd.dec.d.data[off] & 0x1f
|
||||
off++
|
||||
|
||||
// This function only interprets valid head because
|
||||
// CBOR data is validated in NextType().
|
||||
|
||||
@ -1752,11 +1752,11 @@ func TestStreamDecodeNextSize(t *testing.T) {
|
||||
{"false", []byte{0xf4}, 0, "size operation is not supported"},
|
||||
{"true", []byte{0xf5}, 0, "size operation is not supported"},
|
||||
{"nil", []byte{0xf6}, 0, "size operation is not supported"},
|
||||
{"uint", []byte{0x01}, 0, "size operation is not supported"}, // 1
|
||||
{"int", []byte{0x20}, 0, "size operation is not supported"}, // -1
|
||||
{"tag", []byte{0xc2, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0, "size operation is not supported"}, // bignum(18446744073709551616)
|
||||
{"empty byte string", []byte{0x40}, 0, ""}, // []
|
||||
{"byte string", []byte{0x45, 0x01, 0x02, 0x03, 0x04, 0x05}, 5, ""}, // [1, 2, 3, 4, 5]
|
||||
{"uint", []byte{0x01}, 0, "size operation is not supported"}, // 1
|
||||
{"int", []byte{0x20}, 0, "size operation is not supported"}, // -1
|
||||
{"tag", []byte{0xc1, 0x1a, 0x51, 0x4b, 0x67, 0xb0}, 0, "size operation is not supported"}, // epoch-based date/time
|
||||
{"empty byte string", []byte{0x40}, 0, ""}, // []
|
||||
{"byte string", []byte{0x45, 0x01, 0x02, 0x03, 0x04, 0x05}, 5, ""}, // [1, 2, 3, 4, 5]
|
||||
{"indef length byte string", []byte{0x5f, 0x42, 0x01, 0x02, 0x043, 0x03, 0x04, 0x05, 0xff}, 0, "size is unavailable for indefinite length"},
|
||||
{"empty text string", []byte{0x60}, 0, ""}, // ""
|
||||
{"text string", []byte{0x65, 0x68, 0x65, 0x6c, 0x6c, 0x6f}, 5, ""}, // "hello"
|
||||
@ -1765,9 +1765,14 @@ func TestStreamDecodeNextSize(t *testing.T) {
|
||||
{"text string", []byte{0x7a, 0x00, 0x00, 0x00, 0x01, 0x61}, 1, ""}, // "a"
|
||||
{"text string", []byte{0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x61}, 1, ""}, // "a"
|
||||
{"indef length text string", []byte{0x7f, 0x65, 0x73, 0x74, 0x72, 0x65, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x67, 0xff}, 0, "size is unavailable for indefinite length"},
|
||||
{"empty array", []byte{0x80}, 0, ""}, // []
|
||||
{"array", []byte{0x83, 0x01, 0x02, 0x03}, 3, ""}, // [1, 2, 3]
|
||||
{"indef length array", []byte{0x9f, 0x01, 0x02, 0x03, 0xff}, 0, "size is unavailable for indefinite length"}, // [1, 2, 3]
|
||||
{"empty array", []byte{0x80}, 0, ""}, // []
|
||||
{"array", []byte{0x83, 0x01, 0x02, 0x03}, 3, ""}, // [1, 2, 3]
|
||||
{"indef length array", []byte{0x9f, 0x01, 0x02, 0x03, 0xff}, 0, "size is unavailable for indefinite length"}, // [1, 2, 3]
|
||||
{"big int 0", []byte{0xc2, 0x40}, 0, ""}, // bignum: 0
|
||||
{"big int 1", []byte{0xc2, 0x41, 0x01}, 1, ""}, // bignum: 1
|
||||
{"big int 18446744073709551616", []byte{0xc2, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 9, ""}, // bignum: 18446744073709551616
|
||||
{"big int -1", []byte{0xc3, 0x40}, 0, ""}, // bignum: -1
|
||||
{"big int -18446744073709551617", []byte{0xc3, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 9, ""}, // bignum: -18446744073709551617
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user