1
// Copyright (c) 2012-2020 Ugorji Nwoke. All rights reserved.
2
// Use of this source code is governed by a MIT license found in the LICENSE file.
15
cborMajorUint byte = iota
22
cborMajorSimpleOrFloat
27
cborBdFalse byte = 0xf4 + iota
39
cborBdIndefiniteBytes byte = 0x5f
40
cborBdIndefiniteString byte = 0x7f
41
cborBdIndefiniteArray byte = 0x9f
42
cborBdIndefiniteMap byte = 0xbf
43
cborBdBreak byte = 0xff
46
// These define some in-stream descriptors for
47
// manual encoding e.g. when doing explicit indefinite-length
49
CborStreamBytes byte = 0x5f
50
CborStreamString byte = 0x7f
51
CborStreamArray byte = 0x9f
52
CborStreamMap byte = 0xbf
53
CborStreamBreak byte = 0xff
58
cborBaseUint byte = 0x00
59
cborBaseNegInt byte = 0x20
60
cborBaseBytes byte = 0x40
61
cborBaseString byte = 0x60
62
cborBaseArray byte = 0x80
63
cborBaseMap byte = 0xa0
64
cborBaseTag byte = 0xc0
65
cborBaseSimple byte = 0xe0
69
// cborSelfDesrTag byte = 0xd9
70
// cborSelfDesrTag2 byte = 0xd9
71
// cborSelfDesrTag3 byte = 0xf7
75
cbordescSimpleNames = map[byte]string{
79
cborBdFloat16: "float",
80
cborBdFloat32: "float",
81
cborBdFloat64: "float",
84
cbordescIndefNames = map[byte]string{
85
cborBdIndefiniteBytes: "bytes*",
86
cborBdIndefiniteString: "string*",
87
cborBdIndefiniteArray: "array*",
88
cborBdIndefiniteMap: "map*",
90
cbordescMajorNames = map[byte]string{
91
cborMajorUint: "(u)int",
92
cborMajorNegInt: "int",
93
cborMajorBytes: "bytes",
94
cborMajorString: "string",
95
cborMajorArray: "array",
98
cborMajorSimpleOrFloat: "simple",
102
func cbordesc(bd byte) (s string) {
104
if bm == cborMajorSimpleOrFloat {
105
s = cbordescSimpleNames[bd]
107
s = cbordescMajorNames[bm]
109
s = cbordescIndefNames[bd]
118
// -------------------
120
type cborEncDriver struct {
123
encDriverNoopContainerWriter
126
// scratch buffer for: encode time, numbers, etc
128
// RFC3339Nano uses 35 chars: 2006-01-02T15:04:05.999999999Z07:00
134
func (e *cborEncDriver) encoder() *Encoder {
138
func (e *cborEncDriver) EncodeNil() {
139
e.e.encWr.writen1(cborBdNil)
142
func (e *cborEncDriver) EncodeBool(b bool) {
144
e.e.encWr.writen1(cborBdTrue)
146
e.e.encWr.writen1(cborBdFalse)
150
func (e *cborEncDriver) EncodeFloat32(f float32) {
151
b := math.Float32bits(f)
153
if h := floatToHalfFloatBits(b); halfFloatToFloatBits(h) == b {
154
e.e.encWr.writen1(cborBdFloat16)
155
bigen.writeUint16(e.e.w(), h)
159
e.e.encWr.writen1(cborBdFloat32)
160
bigen.writeUint32(e.e.w(), b)
163
func (e *cborEncDriver) EncodeFloat64(f float64) {
165
if f32 := float32(f); float64(f32) == f {
170
e.e.encWr.writen1(cborBdFloat64)
171
bigen.writeUint64(e.e.w(), math.Float64bits(f))
174
func (e *cborEncDriver) encUint(v uint64, bd byte) {
176
e.e.encWr.writen1(byte(v) + bd)
177
} else if v <= math.MaxUint8 {
178
e.e.encWr.writen2(bd+0x18, uint8(v))
179
} else if v <= math.MaxUint16 {
180
e.e.encWr.writen1(bd + 0x19)
181
bigen.writeUint16(e.e.w(), uint16(v))
182
} else if v <= math.MaxUint32 {
183
e.e.encWr.writen1(bd + 0x1a)
184
bigen.writeUint32(e.e.w(), uint32(v))
185
} else { // if v <= math.MaxUint64 {
186
e.e.encWr.writen1(bd + 0x1b)
187
bigen.writeUint64(e.e.w(), v)
191
func (e *cborEncDriver) EncodeInt(v int64) {
193
e.encUint(uint64(-1-v), cborBaseNegInt)
195
e.encUint(uint64(v), cborBaseUint)
199
func (e *cborEncDriver) EncodeUint(v uint64) {
200
e.encUint(v, cborBaseUint)
203
func (e *cborEncDriver) encLen(bd byte, length int) {
204
e.encUint(uint64(length), bd)
207
func (e *cborEncDriver) EncodeTime(t time.Time) {
210
} else if e.h.TimeRFC3339 {
211
e.encUint(0, cborBaseTag)
212
e.encStringBytesS(cborBaseString, stringView(fmtTime(t, time.RFC3339Nano, e.b[:0])))
214
e.encUint(1, cborBaseTag)
215
t = t.UTC().Round(time.Microsecond)
216
sec, nsec := t.Unix(), uint64(t.Nanosecond())
220
e.EncodeFloat64(float64(sec) + float64(nsec)/1e9)
225
func (e *cborEncDriver) EncodeExt(rv interface{}, basetype reflect.Type, xtag uint64, ext Ext) {
226
e.encUint(uint64(xtag), cborBaseTag)
228
e.e.encodeValue(baseRV(rv), e.h.fnNoExt(basetype))
229
} else if v := ext.ConvertExt(rv); v == nil {
236
func (e *cborEncDriver) EncodeRawExt(re *RawExt) {
237
e.encUint(uint64(re.Tag), cborBaseTag)
238
// only encodes re.Value (never re.Data)
246
func (e *cborEncDriver) WriteArrayStart(length int) {
247
if e.h.IndefiniteLength {
248
e.e.encWr.writen1(cborBdIndefiniteArray)
250
e.encLen(cborBaseArray, length)
254
func (e *cborEncDriver) WriteMapStart(length int) {
255
if e.h.IndefiniteLength {
256
e.e.encWr.writen1(cborBdIndefiniteMap)
258
e.encLen(cborBaseMap, length)
262
func (e *cborEncDriver) WriteMapEnd() {
263
if e.h.IndefiniteLength {
264
e.e.encWr.writen1(cborBdBreak)
268
func (e *cborEncDriver) WriteArrayEnd() {
269
if e.h.IndefiniteLength {
270
e.e.encWr.writen1(cborBdBreak)
274
func (e *cborEncDriver) EncodeString(v string) {
279
e.encStringBytesS(bb, v)
282
func (e *cborEncDriver) EncodeStringBytesRaw(v []byte) {
286
e.encStringBytesS(cborBaseBytes, stringView(v))
290
func (e *cborEncDriver) encStringBytesS(bb byte, v string) {
291
if e.h.IndefiniteLength {
292
if bb == cborBaseBytes {
293
e.e.encWr.writen1(cborBdIndefiniteBytes)
295
e.e.encWr.writen1(cborBdIndefiniteString)
297
var vlen uint = uint(len(v))
301
} else if blen > 1024 {
304
for i := uint(0); i < vlen; {
307
if i2 >= i && i2 < vlen {
312
e.encLen(bb, len(v2))
313
e.e.encWr.writestr(v2)
316
e.e.encWr.writen1(cborBdBreak)
319
e.e.encWr.writestr(v)
323
// ----------------------
325
type cborDecDriver struct {
326
decDriverNoopContainerReader
327
decDriverNoopNumberHelper
336
func (d *cborDecDriver) decoder() *Decoder {
340
func (d *cborDecDriver) descBd() string {
341
return sprintf("%v (%s)", d.bd, cbordesc(d.bd))
344
func (d *cborDecDriver) readNextBd() {
345
d.bd = d.d.decRd.readn1()
349
func (d *cborDecDriver) advanceNil() (null bool) {
353
if d.bd == cborBdNil || d.bd == cborBdUndefined {
355
return true // null = true
360
func (d *cborDecDriver) TryNil() bool {
361
return d.advanceNil()
364
// skipTags is called to skip any tags in the stream.
366
// Since any value can be tagged, then we should call skipTags
367
// before any value is decoded.
369
// By definition, skipTags should not be called before
370
// checking for break, or nil or undefined.
371
func (d *cborDecDriver) skipTags() {
372
for d.bd>>5 == cborMajorTag {
374
d.bd = d.d.decRd.readn1()
378
func (d *cborDecDriver) ContainerType() (vt valueType) {
385
if d.bd == cborBdNil {
386
d.bdRead = false // always consume nil after seeing it in container type
390
if major == cborMajorBytes {
391
return valueTypeBytes
392
} else if major == cborMajorString {
393
return valueTypeString
394
} else if major == cborMajorArray {
395
return valueTypeArray
396
} else if major == cborMajorMap {
399
return valueTypeUnset
402
func (d *cborDecDriver) CheckBreak() (v bool) {
406
if d.bd == cborBdBreak {
413
func (d *cborDecDriver) decUint() (ui uint64) {
417
} else if v == 0x18 {
418
ui = uint64(d.d.decRd.readn1())
419
} else if v == 0x19 {
420
ui = uint64(bigen.Uint16(d.d.decRd.readn2()))
421
} else if v == 0x1a {
422
ui = uint64(bigen.Uint32(d.d.decRd.readn4()))
423
} else if v == 0x1b {
424
ui = uint64(bigen.Uint64(d.d.decRd.readn8()))
426
d.d.errorf("invalid descriptor decoding uint: %x/%s", d.bd, cbordesc(d.bd))
431
func (d *cborDecDriver) decLen() int {
432
return int(d.decUint())
435
func (d *cborDecDriver) decAppendIndefiniteBytes(bs []byte, major byte) []byte {
437
for !d.CheckBreak() {
438
chunkMajor := d.bd >> 5
439
if chunkMajor != major {
440
d.d.errorf("malformed indefinite string/bytes %x (%s); contains chunk with major type %v, expected %v",
441
d.bd, cbordesc(d.bd), chunkMajor, major)
443
n := uint(d.decLen())
444
oldLen := uint(len(bs))
446
if newLen > uint(cap(bs)) {
447
bs2 := make([]byte, newLen, 2*uint(cap(bs))+n)
453
d.d.decRd.readb(bs[oldLen:newLen])
454
if d.h.ValidateUnicode && major == cborMajorString && !utf8.Valid(bs[oldLen:newLen]) {
455
d.d.errorf("indefinite-length text string contains chunk that is not a valid utf-8 sequence: 0x%x", bs[oldLen:newLen])
463
func (d *cborDecDriver) decFloat() (f float64, ok bool) {
467
f = float64(math.Float32frombits(halfFloatToFloatBits(bigen.Uint16(d.d.decRd.readn2()))))
469
f = float64(math.Float32frombits(bigen.Uint32(d.d.decRd.readn4())))
471
f = math.Float64frombits(bigen.Uint64(d.d.decRd.readn8()))
478
func (d *cborDecDriver) decInteger() (ui uint64, neg, ok bool) {
483
case cborMajorNegInt:
492
func (d *cborDecDriver) DecodeInt64() (i int64) {
499
i = decNegintPosintFloatNumberHelper{&d.d}.int64(d.decInteger())
504
func (d *cborDecDriver) DecodeUint64() (ui uint64) {
511
ui = decNegintPosintFloatNumberHelper{&d.d}.uint64(d.decInteger())
516
func (d *cborDecDriver) DecodeFloat64() (f float64) {
523
f = decNegintPosintFloatNumberHelper{&d.d}.float64(d.decFloat())
528
// bool can be decoded from bool only (single byte).
529
func (d *cborDecDriver) DecodeBool() (b bool) {
536
if d.bd == cborBdTrue {
538
} else if d.bd == cborBdFalse {
540
d.d.errorf("not bool - %s %x/%s", msgBadDesc, d.bd, cbordesc(d.bd))
546
func (d *cborDecDriver) ReadMapStart() (length int) {
548
return containerLenNil
554
if d.bd == cborBdIndefiniteMap {
555
return containerLenUnknown
557
if d.bd>>5 != cborMajorMap {
558
d.d.errorf("error reading map; got major type: %x, expected %x/%s", d.bd>>5, cborMajorMap, cbordesc(d.bd))
563
func (d *cborDecDriver) ReadArrayStart() (length int) {
565
return containerLenNil
571
if d.bd == cborBdIndefiniteArray {
572
return containerLenUnknown
574
if d.bd>>5 != cborMajorArray {
575
d.d.errorf("invalid array; got major type: %x, expect: %x/%s", d.bd>>5, cborMajorArray, cbordesc(d.bd))
580
func (d *cborDecDriver) DecodeBytes(bs []byte) (bsOut []byte) {
581
d.d.decByteState = decByteStateNone
588
if d.bd == cborBdIndefiniteBytes || d.bd == cborBdIndefiniteString {
591
d.d.decByteState = decByteStateReuseBuf
592
return d.decAppendIndefiniteBytes(d.d.b[:0], d.bd>>5)
594
return d.decAppendIndefiniteBytes(bs[:0], d.bd>>5)
596
if d.bd == cborBdIndefiniteArray {
599
d.d.decByteState = decByteStateReuseBuf
604
for !d.CheckBreak() {
605
bs = append(bs, uint8(chkOvf.UintV(d.DecodeUint64(), 8)))
609
if d.bd>>5 == cborMajorArray {
612
d.d.decByteState = decByteStateReuseBuf
617
if bs, changed = usableByteSlice(bs, slen); changed {
618
d.d.decByteState = decByteStateNone
620
for i := 0; i < len(bs); i++ {
621
bs[i] = uint8(chkOvf.UintV(d.DecodeUint64(), 8))
623
for i := len(bs); i < slen; i++ {
624
bs = append(bs, uint8(chkOvf.UintV(d.DecodeUint64(), 8)))
631
d.d.decByteState = decByteStateZerocopy
632
return d.d.decRd.rb.readx(uint(clen))
635
d.d.decByteState = decByteStateReuseBuf
638
return decByteSlice(d.d.r(), clen, d.h.MaxInitLen, bs)
641
func (d *cborDecDriver) DecodeStringAsBytes() (s []byte) {
642
s = d.DecodeBytes(nil)
643
if d.h.ValidateUnicode && !utf8.Valid(s) {
644
d.d.errorf("DecodeStringAsBytes: invalid UTF-8: %s", s)
649
func (d *cborDecDriver) DecodeTime() (t time.Time) {
653
if d.bd>>5 != cborMajorTag {
654
d.d.errorf("error reading tag; expected major type: %x, got: %x", cborMajorTag, d.bd>>5)
658
return d.decodeTime(xtag)
661
func (d *cborDecDriver) decodeTime(xtag uint64) (t time.Time) {
665
t, err = time.Parse(time.RFC3339, stringView(d.DecodeStringAsBytes()))
668
f1, f2 := math.Modf(d.DecodeFloat64())
669
t = time.Unix(int64(f1), int64(f2*1e9))
671
d.d.errorf("invalid tag for time.Time - expecting 0 or 1, got 0x%x", xtag)
673
t = t.UTC().Round(time.Microsecond)
677
func (d *cborDecDriver) DecodeExt(rv interface{}, basetype reflect.Type, xtag uint64, ext Ext) {
681
if d.bd>>5 != cborMajorTag {
682
d.d.errorf("error reading tag; expected major type: %x, got: %x", cborMajorTag, d.bd>>5)
684
realxtag := d.decUint()
689
d.d.decode(&re.Value)
690
} else if xtag != realxtag {
691
d.d.errorf("Wrong extension tag. Got %b. Expecting: %v", realxtag, xtag)
692
} else if ext == SelfExt {
693
d.d.decodeValue(baseRV(rv), d.h.fnNoExt(basetype))
695
d.d.interfaceExtConvertAndDecode(rv, ext)
700
func (d *cborDecDriver) DecodeNaked() {
706
var decodeFurther bool
710
if d.h.SignedInteger {
712
n.i = d.DecodeInt64()
715
n.u = d.DecodeUint64()
717
case cborMajorNegInt:
719
n.i = d.DecodeInt64()
721
d.d.fauxUnionReadRawBytes(false)
722
case cborMajorString:
723
n.v = valueTypeString
724
n.s = d.d.stringZC(d.DecodeStringAsBytes())
735
if n.u == 0 || n.u == 1 {
738
n.t = d.decodeTime(n.u)
739
} else if d.st && d.h.getExtForTag(n.u) == nil {
740
// d.skipTags() // no need to call this - tags already skipped
743
return // return when done (as true recursive function)
745
case cborMajorSimpleOrFloat:
747
case cborBdNil, cborBdUndefined:
755
case cborBdFloat16, cborBdFloat32, cborBdFloat64:
757
n.f = d.DecodeFloat64()
759
d.d.errorf("decodeNaked: Unrecognized d.bd: 0x%x", d.bd)
761
default: // should never happen
762
d.d.errorf("decodeNaked: Unrecognized d.bd: 0x%x", d.bd)
769
func (d *cborDecDriver) uintBytes() (v []byte, ui uint64) {
770
// this is only used by nextValueBytes, so it's ok to
771
// use readx and bigenstd here.
772
switch vv := d.bd & 0x1f; vv {
774
v = d.d.decRd.readx(1)
777
v = d.d.decRd.readx(2)
778
ui = uint64(bigenstd.Uint16(v))
780
v = d.d.decRd.readx(4)
781
ui = uint64(bigenstd.Uint32(v))
783
v = d.d.decRd.readx(8)
784
ui = uint64(bigenstd.Uint64(v))
787
d.d.errorf("invalid descriptor decoding uint: %x/%s", d.bd, cbordesc(d.bd))
794
func (d *cborDecDriver) nextValueBytes(v0 []byte) (v []byte) {
799
var h = decNextValueBytesHelper{d: &d.d}
800
var cursor = d.d.rb.c - 1
802
v = d.nextValueBytesBdReadR(v)
804
h.bytesRdV(&v, cursor)
808
func (d *cborDecDriver) nextValueBytesR(v0 []byte) (v []byte) {
811
var h = decNextValueBytesHelper{d: &d.d}
813
return d.nextValueBytesBdReadR(v)
816
func (d *cborDecDriver) nextValueBytesBdReadR(v0 []byte) (v []byte) {
818
var h = decNextValueBytesHelper{d: &d.d}
824
case cborMajorUint, cborMajorNegInt:
825
bs, _ = d.uintBytes()
827
case cborMajorString, cborMajorBytes:
828
if d.bd == cborBdIndefiniteBytes || d.bd == cborBdIndefiniteString {
832
if d.bd == cborBdBreak {
835
bs, ui = d.uintBytes()
837
h.appendN(&v, d.d.decRd.readx(uint(ui))...)
840
bs, ui = d.uintBytes()
842
h.appendN(&v, d.d.decRd.readx(uint(ui))...)
845
if d.bd == cborBdIndefiniteArray {
849
if d.bd == cborBdBreak {
852
v = d.nextValueBytesBdReadR(v)
855
bs, ui = d.uintBytes()
857
for i := uint64(0); i < ui; i++ {
858
v = d.nextValueBytesR(v)
862
if d.bd == cborBdIndefiniteMap {
866
if d.bd == cborBdBreak {
869
v = d.nextValueBytesBdReadR(v)
870
v = d.nextValueBytesR(v)
873
bs, ui = d.uintBytes()
875
for i := uint64(0); i < ui; i++ {
876
v = d.nextValueBytesR(v)
877
v = d.nextValueBytesR(v)
881
bs, _ = d.uintBytes()
883
v = d.nextValueBytesR(v)
884
case cborMajorSimpleOrFloat:
886
case cborBdNil, cborBdUndefined, cborBdFalse, cborBdTrue: // pass
888
h.appendN(&v, d.d.decRd.readx(2)...)
890
h.appendN(&v, d.d.decRd.readx(4)...)
892
h.appendN(&v, d.d.decRd.readx(8)...)
894
d.d.errorf("nextValueBytes: Unrecognized d.bd: 0x%x", d.bd)
896
default: // should never happen
897
d.d.errorf("nextValueBytes: Unrecognized d.bd: 0x%x", d.bd)
902
// -------------------------
904
// CborHandle is a Handle for the CBOR encoding format,
905
// defined at http://tools.ietf.org/html/rfc7049 and documented further at http://cbor.io .
907
// CBOR is comprehensively supported, including support for:
908
// - indefinite-length arrays/maps/bytes/strings
909
// - (extension) tags in range 0..0xffff (0 .. 65535)
910
// - half, single and double-precision floats
911
// - all numbers (1, 2, 4 and 8-byte signed and unsigned integers)
912
// - nil, true, false, ...
913
// - arrays and maps, bytes and text strings
915
// None of the optional extensions (with tags) defined in the spec are supported out-of-the-box.
916
// Users can implement them as needed (using SetExt), including spec-documented ones:
917
// - timestamp, BigNum, BigFloat, Decimals,
918
// - Encoded Text (e.g. URL, regexp, base64, MIME Message), etc.
919
type CborHandle struct {
924
// IndefiniteLength=true, means that we encode using indefinitelength
925
IndefiniteLength bool
927
// TimeRFC3339 says to encode time.Time using RFC3339 format.
928
// If unset, we encode time.Time using seconds past epoch.
931
// SkipUnexpectedTags says to skip over any tags for which extensions are
932
// not defined. This is in keeping with the cbor spec on "Optional Tagging of Items".
934
// Furthermore, this allows the skipping over of the Self Describing Tag 0xd9d9f7.
935
SkipUnexpectedTags bool
938
// Name returns the name of the handle: cbor
939
func (h *CborHandle) Name() string { return "cbor" }
941
func (h *CborHandle) desc(bd byte) string { return cbordesc(bd) }
943
func (h *CborHandle) newEncDriver() encDriver {
944
var e = &cborEncDriver{h: h}
951
func (h *CborHandle) newDecDriver() decDriver {
952
d := &cborDecDriver{h: h, st: h.SkipUnexpectedTags}
960
func (d *cborDecDriver) reset() {
961
d.bdAndBdread.reset()
962
d.st = d.h.SkipUnexpectedTags
965
var _ decDriver = (*cborDecDriver)(nil)
966
var _ encDriver = (*cborEncDriver)(nil)