gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

cbor.go (21605B)


      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.
      3 
      4 package codec
      5 
      6 import (
      7 	"math"
      8 	"reflect"
      9 	"time"
     10 	"unicode/utf8"
     11 )
     12 
     13 // major
     14 const (
     15 	cborMajorUint byte = iota
     16 	cborMajorNegInt
     17 	cborMajorBytes
     18 	cborMajorString
     19 	cborMajorArray
     20 	cborMajorMap
     21 	cborMajorTag
     22 	cborMajorSimpleOrFloat
     23 )
     24 
     25 // simple
     26 const (
     27 	cborBdFalse byte = 0xf4 + iota
     28 	cborBdTrue
     29 	cborBdNil
     30 	cborBdUndefined
     31 	cborBdExt
     32 	cborBdFloat16
     33 	cborBdFloat32
     34 	cborBdFloat64
     35 )
     36 
     37 // indefinite
     38 const (
     39 	cborBdIndefiniteBytes  byte = 0x5f
     40 	cborBdIndefiniteString byte = 0x7f
     41 	cborBdIndefiniteArray  byte = 0x9f
     42 	cborBdIndefiniteMap    byte = 0xbf
     43 	cborBdBreak            byte = 0xff
     44 )
     45 
     46 // These define some in-stream descriptors for
     47 // manual encoding e.g. when doing explicit indefinite-length
     48 const (
     49 	CborStreamBytes  byte = 0x5f
     50 	CborStreamString byte = 0x7f
     51 	CborStreamArray  byte = 0x9f
     52 	CborStreamMap    byte = 0xbf
     53 	CborStreamBreak  byte = 0xff
     54 )
     55 
     56 // base values
     57 const (
     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
     66 )
     67 
     68 // const (
     69 // 	cborSelfDesrTag  byte = 0xd9
     70 // 	cborSelfDesrTag2 byte = 0xd9
     71 // 	cborSelfDesrTag3 byte = 0xf7
     72 // )
     73 
     74 var (
     75 	cbordescSimpleNames = map[byte]string{
     76 		cborBdNil:     "nil",
     77 		cborBdFalse:   "false",
     78 		cborBdTrue:    "true",
     79 		cborBdFloat16: "float",
     80 		cborBdFloat32: "float",
     81 		cborBdFloat64: "float",
     82 		cborBdBreak:   "break",
     83 	}
     84 	cbordescIndefNames = map[byte]string{
     85 		cborBdIndefiniteBytes:  "bytes*",
     86 		cborBdIndefiniteString: "string*",
     87 		cborBdIndefiniteArray:  "array*",
     88 		cborBdIndefiniteMap:    "map*",
     89 	}
     90 	cbordescMajorNames = map[byte]string{
     91 		cborMajorUint:          "(u)int",
     92 		cborMajorNegInt:        "int",
     93 		cborMajorBytes:         "bytes",
     94 		cborMajorString:        "string",
     95 		cborMajorArray:         "array",
     96 		cborMajorMap:           "map",
     97 		cborMajorTag:           "tag",
     98 		cborMajorSimpleOrFloat: "simple",
     99 	}
    100 )
    101 
    102 func cbordesc(bd byte) (s string) {
    103 	bm := bd >> 5
    104 	if bm == cborMajorSimpleOrFloat {
    105 		s = cbordescSimpleNames[bd]
    106 	} else {
    107 		s = cbordescMajorNames[bm]
    108 		if s == "" {
    109 			s = cbordescIndefNames[bd]
    110 		}
    111 	}
    112 	if s == "" {
    113 		s = "unknown"
    114 	}
    115 	return
    116 }
    117 
    118 // -------------------
    119 
    120 type cborEncDriver struct {
    121 	noBuiltInTypes
    122 	encDriverNoState
    123 	encDriverNoopContainerWriter
    124 	h *CborHandle
    125 
    126 	e Encoder
    127 }
    128 
    129 func (e *cborEncDriver) encoder() *Encoder {
    130 	return &e.e
    131 }
    132 
    133 func (e *cborEncDriver) EncodeNil() {
    134 	e.e.encWr.writen1(cborBdNil)
    135 }
    136 
    137 func (e *cborEncDriver) EncodeBool(b bool) {
    138 	if b {
    139 		e.e.encWr.writen1(cborBdTrue)
    140 	} else {
    141 		e.e.encWr.writen1(cborBdFalse)
    142 	}
    143 }
    144 
    145 func (e *cborEncDriver) EncodeFloat32(f float32) {
    146 	b := math.Float32bits(f)
    147 	if e.h.OptimumSize {
    148 		if h := floatToHalfFloatBits(b); halfFloatToFloatBits(h) == b {
    149 			e.e.encWr.writen1(cborBdFloat16)
    150 			bigen.writeUint16(e.e.w(), h)
    151 			return
    152 		}
    153 	}
    154 	e.e.encWr.writen1(cborBdFloat32)
    155 	bigen.writeUint32(e.e.w(), b)
    156 }
    157 
    158 func (e *cborEncDriver) EncodeFloat64(f float64) {
    159 	if e.h.OptimumSize {
    160 		if f32 := float32(f); float64(f32) == f {
    161 			e.EncodeFloat32(f32)
    162 			return
    163 		}
    164 	}
    165 	e.e.encWr.writen1(cborBdFloat64)
    166 	bigen.writeUint64(e.e.w(), math.Float64bits(f))
    167 }
    168 
    169 func (e *cborEncDriver) encUint(v uint64, bd byte) {
    170 	if v <= 0x17 {
    171 		e.e.encWr.writen1(byte(v) + bd)
    172 	} else if v <= math.MaxUint8 {
    173 		e.e.encWr.writen2(bd+0x18, uint8(v))
    174 	} else if v <= math.MaxUint16 {
    175 		e.e.encWr.writen1(bd + 0x19)
    176 		bigen.writeUint16(e.e.w(), uint16(v))
    177 	} else if v <= math.MaxUint32 {
    178 		e.e.encWr.writen1(bd + 0x1a)
    179 		bigen.writeUint32(e.e.w(), uint32(v))
    180 	} else { // if v <= math.MaxUint64 {
    181 		e.e.encWr.writen1(bd + 0x1b)
    182 		bigen.writeUint64(e.e.w(), v)
    183 	}
    184 }
    185 
    186 func (e *cborEncDriver) EncodeInt(v int64) {
    187 	if v < 0 {
    188 		e.encUint(uint64(-1-v), cborBaseNegInt)
    189 	} else {
    190 		e.encUint(uint64(v), cborBaseUint)
    191 	}
    192 }
    193 
    194 func (e *cborEncDriver) EncodeUint(v uint64) {
    195 	e.encUint(v, cborBaseUint)
    196 }
    197 
    198 func (e *cborEncDriver) encLen(bd byte, length int) {
    199 	e.encUint(uint64(length), bd)
    200 }
    201 
    202 func (e *cborEncDriver) EncodeTime(t time.Time) {
    203 	if t.IsZero() {
    204 		e.EncodeNil()
    205 	} else if e.h.TimeRFC3339 {
    206 		e.encUint(0, cborBaseTag)
    207 		e.encStringBytesS(cborBaseString, t.Format(time.RFC3339Nano))
    208 	} else {
    209 		e.encUint(1, cborBaseTag)
    210 		t = t.UTC().Round(time.Microsecond)
    211 		sec, nsec := t.Unix(), uint64(t.Nanosecond())
    212 		if nsec == 0 {
    213 			e.EncodeInt(sec)
    214 		} else {
    215 			e.EncodeFloat64(float64(sec) + float64(nsec)/1e9)
    216 		}
    217 	}
    218 }
    219 
    220 func (e *cborEncDriver) EncodeExt(rv interface{}, basetype reflect.Type, xtag uint64, ext Ext) {
    221 	e.encUint(uint64(xtag), cborBaseTag)
    222 	if ext == SelfExt {
    223 		e.e.encodeValue(baseRV(rv), e.h.fnNoExt(basetype))
    224 	} else if v := ext.ConvertExt(rv); v == nil {
    225 		e.EncodeNil()
    226 	} else {
    227 		e.e.encode(v)
    228 	}
    229 }
    230 
    231 func (e *cborEncDriver) EncodeRawExt(re *RawExt) {
    232 	e.encUint(uint64(re.Tag), cborBaseTag)
    233 	// only encodes re.Value (never re.Data)
    234 	if re.Value != nil {
    235 		e.e.encode(re.Value)
    236 	} else {
    237 		e.EncodeNil()
    238 	}
    239 }
    240 
    241 func (e *cborEncDriver) WriteArrayStart(length int) {
    242 	if e.h.IndefiniteLength {
    243 		e.e.encWr.writen1(cborBdIndefiniteArray)
    244 	} else {
    245 		e.encLen(cborBaseArray, length)
    246 	}
    247 }
    248 
    249 func (e *cborEncDriver) WriteMapStart(length int) {
    250 	if e.h.IndefiniteLength {
    251 		e.e.encWr.writen1(cborBdIndefiniteMap)
    252 	} else {
    253 		e.encLen(cborBaseMap, length)
    254 	}
    255 }
    256 
    257 func (e *cborEncDriver) WriteMapEnd() {
    258 	if e.h.IndefiniteLength {
    259 		e.e.encWr.writen1(cborBdBreak)
    260 	}
    261 }
    262 
    263 func (e *cborEncDriver) WriteArrayEnd() {
    264 	if e.h.IndefiniteLength {
    265 		e.e.encWr.writen1(cborBdBreak)
    266 	}
    267 }
    268 
    269 func (e *cborEncDriver) EncodeString(v string) {
    270 	bb := cborBaseString
    271 	if e.h.StringToRaw {
    272 		bb = cborBaseBytes
    273 	}
    274 	e.encStringBytesS(bb, v)
    275 }
    276 
    277 func (e *cborEncDriver) EncodeStringBytesRaw(v []byte) {
    278 	if v == nil {
    279 		e.EncodeNil()
    280 	} else {
    281 		e.encStringBytesS(cborBaseBytes, stringView(v))
    282 	}
    283 }
    284 
    285 func (e *cborEncDriver) encStringBytesS(bb byte, v string) {
    286 	if e.h.IndefiniteLength {
    287 		if bb == cborBaseBytes {
    288 			e.e.encWr.writen1(cborBdIndefiniteBytes)
    289 		} else {
    290 			e.e.encWr.writen1(cborBdIndefiniteString)
    291 		}
    292 		var vlen uint = uint(len(v))
    293 		blen := vlen / 4
    294 		if blen == 0 {
    295 			blen = 64
    296 		} else if blen > 1024 {
    297 			blen = 1024
    298 		}
    299 		for i := uint(0); i < vlen; {
    300 			var v2 string
    301 			i2 := i + blen
    302 			if i2 >= i && i2 < vlen {
    303 				v2 = v[i:i2]
    304 			} else {
    305 				v2 = v[i:]
    306 			}
    307 			e.encLen(bb, len(v2))
    308 			e.e.encWr.writestr(v2)
    309 			i = i2
    310 		}
    311 		e.e.encWr.writen1(cborBdBreak)
    312 	} else {
    313 		e.encLen(bb, len(v))
    314 		e.e.encWr.writestr(v)
    315 	}
    316 }
    317 
    318 // ----------------------
    319 
    320 type cborDecDriver struct {
    321 	decDriverNoopContainerReader
    322 	decDriverNoopNumberHelper
    323 	h *CborHandle
    324 	bdAndBdread
    325 	st bool // skip tags
    326 	_  bool // found nil
    327 	noBuiltInTypes
    328 	d Decoder
    329 }
    330 
    331 func (d *cborDecDriver) decoder() *Decoder {
    332 	return &d.d
    333 }
    334 
    335 func (d *cborDecDriver) descBd() string {
    336 	return sprintf("%v (%s)", d.bd, cbordesc(d.bd))
    337 }
    338 
    339 func (d *cborDecDriver) readNextBd() {
    340 	d.bd = d.d.decRd.readn1()
    341 	d.bdRead = true
    342 }
    343 
    344 func (d *cborDecDriver) advanceNil() (null bool) {
    345 	if !d.bdRead {
    346 		d.readNextBd()
    347 	}
    348 	if d.bd == cborBdNil || d.bd == cborBdUndefined {
    349 		d.bdRead = false
    350 		return true // null = true
    351 	}
    352 	return
    353 }
    354 
    355 func (d *cborDecDriver) TryNil() bool {
    356 	return d.advanceNil()
    357 }
    358 
    359 // skipTags is called to skip any tags in the stream.
    360 //
    361 // Since any value can be tagged, then we should call skipTags
    362 // before any value is decoded.
    363 //
    364 // By definition, skipTags should not be called before
    365 // checking for break, or nil or undefined.
    366 func (d *cborDecDriver) skipTags() {
    367 	for d.bd>>5 == cborMajorTag {
    368 		d.decUint()
    369 		d.bd = d.d.decRd.readn1()
    370 	}
    371 }
    372 
    373 func (d *cborDecDriver) ContainerType() (vt valueType) {
    374 	if !d.bdRead {
    375 		d.readNextBd()
    376 	}
    377 	if d.st {
    378 		d.skipTags()
    379 	}
    380 	if d.bd == cborBdNil {
    381 		d.bdRead = false // always consume nil after seeing it in container type
    382 		return valueTypeNil
    383 	}
    384 	major := d.bd >> 5
    385 	if major == cborMajorBytes {
    386 		return valueTypeBytes
    387 	} else if major == cborMajorString {
    388 		return valueTypeString
    389 	} else if major == cborMajorArray {
    390 		return valueTypeArray
    391 	} else if major == cborMajorMap {
    392 		return valueTypeMap
    393 	}
    394 	return valueTypeUnset
    395 }
    396 
    397 func (d *cborDecDriver) CheckBreak() (v bool) {
    398 	if !d.bdRead {
    399 		d.readNextBd()
    400 	}
    401 	if d.bd == cborBdBreak {
    402 		d.bdRead = false
    403 		v = true
    404 	}
    405 	return
    406 }
    407 
    408 func (d *cborDecDriver) decUint() (ui uint64) {
    409 	v := d.bd & 0x1f
    410 	if v <= 0x17 {
    411 		ui = uint64(v)
    412 	} else if v == 0x18 {
    413 		ui = uint64(d.d.decRd.readn1())
    414 	} else if v == 0x19 {
    415 		ui = uint64(bigen.Uint16(d.d.decRd.readn2()))
    416 	} else if v == 0x1a {
    417 		ui = uint64(bigen.Uint32(d.d.decRd.readn4()))
    418 	} else if v == 0x1b {
    419 		ui = uint64(bigen.Uint64(d.d.decRd.readn8()))
    420 	} else {
    421 		d.d.errorf("invalid descriptor decoding uint: %x/%s", d.bd, cbordesc(d.bd))
    422 	}
    423 	return
    424 }
    425 
    426 func (d *cborDecDriver) decLen() int {
    427 	return int(d.decUint())
    428 }
    429 
    430 func (d *cborDecDriver) decAppendIndefiniteBytes(bs []byte) []byte {
    431 	d.bdRead = false
    432 	for !d.CheckBreak() {
    433 		if major := d.bd >> 5; major != cborMajorBytes && major != cborMajorString {
    434 			d.d.errorf("invalid indefinite string/bytes %x (%s); got major %v, expected %v or %v",
    435 				d.bd, cbordesc(d.bd), major, cborMajorBytes, cborMajorString)
    436 		}
    437 		n := uint(d.decLen())
    438 		oldLen := uint(len(bs))
    439 		newLen := oldLen + n
    440 		if newLen > uint(cap(bs)) {
    441 			bs2 := make([]byte, newLen, 2*uint(cap(bs))+n)
    442 			copy(bs2, bs)
    443 			bs = bs2
    444 		} else {
    445 			bs = bs[:newLen]
    446 		}
    447 		d.d.decRd.readb(bs[oldLen:newLen])
    448 		d.bdRead = false
    449 	}
    450 	d.bdRead = false
    451 	return bs
    452 }
    453 
    454 func (d *cborDecDriver) decFloat() (f float64, ok bool) {
    455 	ok = true
    456 	switch d.bd {
    457 	case cborBdFloat16:
    458 		f = float64(math.Float32frombits(halfFloatToFloatBits(bigen.Uint16(d.d.decRd.readn2()))))
    459 	case cborBdFloat32:
    460 		f = float64(math.Float32frombits(bigen.Uint32(d.d.decRd.readn4())))
    461 	case cborBdFloat64:
    462 		f = math.Float64frombits(bigen.Uint64(d.d.decRd.readn8()))
    463 	default:
    464 		ok = false
    465 	}
    466 	return
    467 }
    468 
    469 func (d *cborDecDriver) decInteger() (ui uint64, neg, ok bool) {
    470 	ok = true
    471 	switch d.bd >> 5 {
    472 	case cborMajorUint:
    473 		ui = d.decUint()
    474 	case cborMajorNegInt:
    475 		ui = d.decUint()
    476 		neg = true
    477 	default:
    478 		ok = false
    479 	}
    480 	return
    481 }
    482 
    483 func (d *cborDecDriver) DecodeInt64() (i int64) {
    484 	if d.advanceNil() {
    485 		return
    486 	}
    487 	if d.st {
    488 		d.skipTags()
    489 	}
    490 	i = decNegintPosintFloatNumberHelper{&d.d}.int64(d.decInteger())
    491 	d.bdRead = false
    492 	return
    493 }
    494 
    495 func (d *cborDecDriver) DecodeUint64() (ui uint64) {
    496 	if d.advanceNil() {
    497 		return
    498 	}
    499 	if d.st {
    500 		d.skipTags()
    501 	}
    502 	ui = decNegintPosintFloatNumberHelper{&d.d}.uint64(d.decInteger())
    503 	d.bdRead = false
    504 	return
    505 }
    506 
    507 func (d *cborDecDriver) DecodeFloat64() (f float64) {
    508 	if d.advanceNil() {
    509 		return
    510 	}
    511 	if d.st {
    512 		d.skipTags()
    513 	}
    514 	f = decNegintPosintFloatNumberHelper{&d.d}.float64(d.decFloat())
    515 	d.bdRead = false
    516 	return
    517 }
    518 
    519 // bool can be decoded from bool only (single byte).
    520 func (d *cborDecDriver) DecodeBool() (b bool) {
    521 	if d.advanceNil() {
    522 		return
    523 	}
    524 	if d.st {
    525 		d.skipTags()
    526 	}
    527 	if d.bd == cborBdTrue {
    528 		b = true
    529 	} else if d.bd == cborBdFalse {
    530 	} else {
    531 		d.d.errorf("not bool - %s %x/%s", msgBadDesc, d.bd, cbordesc(d.bd))
    532 	}
    533 	d.bdRead = false
    534 	return
    535 }
    536 
    537 func (d *cborDecDriver) ReadMapStart() (length int) {
    538 	if d.advanceNil() {
    539 		return containerLenNil
    540 	}
    541 	if d.st {
    542 		d.skipTags()
    543 	}
    544 	d.bdRead = false
    545 	if d.bd == cborBdIndefiniteMap {
    546 		return containerLenUnknown
    547 	}
    548 	if d.bd>>5 != cborMajorMap {
    549 		d.d.errorf("error reading map; got major type: %x, expected %x/%s", d.bd>>5, cborMajorMap, cbordesc(d.bd))
    550 	}
    551 	return d.decLen()
    552 }
    553 
    554 func (d *cborDecDriver) ReadArrayStart() (length int) {
    555 	if d.advanceNil() {
    556 		return containerLenNil
    557 	}
    558 	if d.st {
    559 		d.skipTags()
    560 	}
    561 	d.bdRead = false
    562 	if d.bd == cborBdIndefiniteArray {
    563 		return containerLenUnknown
    564 	}
    565 	if d.bd>>5 != cborMajorArray {
    566 		d.d.errorf("invalid array; got major type: %x, expect: %x/%s", d.bd>>5, cborMajorArray, cbordesc(d.bd))
    567 	}
    568 	return d.decLen()
    569 }
    570 
    571 func (d *cborDecDriver) DecodeBytes(bs []byte) (bsOut []byte) {
    572 	d.d.decByteState = decByteStateNone
    573 	if d.advanceNil() {
    574 		return
    575 	}
    576 	if d.st {
    577 		d.skipTags()
    578 	}
    579 	if d.bd == cborBdIndefiniteBytes || d.bd == cborBdIndefiniteString {
    580 		d.bdRead = false
    581 		if bs == nil {
    582 			d.d.decByteState = decByteStateReuseBuf
    583 			return d.decAppendIndefiniteBytes(d.d.b[:0])
    584 		}
    585 		return d.decAppendIndefiniteBytes(bs[:0])
    586 	}
    587 	if d.bd == cborBdIndefiniteArray {
    588 		d.bdRead = false
    589 		if bs == nil {
    590 			d.d.decByteState = decByteStateReuseBuf
    591 			bs = d.d.b[:0]
    592 		} else {
    593 			bs = bs[:0]
    594 		}
    595 		for !d.CheckBreak() {
    596 			bs = append(bs, uint8(chkOvf.UintV(d.DecodeUint64(), 8)))
    597 		}
    598 		return bs
    599 	}
    600 	if d.bd>>5 == cborMajorArray {
    601 		d.bdRead = false
    602 		if bs == nil {
    603 			d.d.decByteState = decByteStateReuseBuf
    604 			bs = d.d.b[:]
    605 		}
    606 		slen := d.decLen()
    607 		var changed bool
    608 		if bs, changed = usableByteSlice(bs, slen); changed {
    609 			d.d.decByteState = decByteStateNone
    610 		}
    611 		for i := 0; i < len(bs); i++ {
    612 			bs[i] = uint8(chkOvf.UintV(d.DecodeUint64(), 8))
    613 		}
    614 		for i := len(bs); i < slen; i++ {
    615 			bs = append(bs, uint8(chkOvf.UintV(d.DecodeUint64(), 8)))
    616 		}
    617 		return bs
    618 	}
    619 	clen := d.decLen()
    620 	d.bdRead = false
    621 	if d.d.zerocopy() {
    622 		d.d.decByteState = decByteStateZerocopy
    623 		return d.d.decRd.rb.readx(uint(clen))
    624 	}
    625 	if bs == nil {
    626 		d.d.decByteState = decByteStateReuseBuf
    627 		bs = d.d.b[:]
    628 	}
    629 	return decByteSlice(d.d.r(), clen, d.h.MaxInitLen, bs)
    630 }
    631 
    632 func (d *cborDecDriver) DecodeStringAsBytes() (s []byte) {
    633 	s = d.DecodeBytes(nil)
    634 	if d.h.ValidateUnicode && !utf8.Valid(s) {
    635 		d.d.errorf("DecodeStringAsBytes: invalid UTF-8: %s", s)
    636 	}
    637 	return
    638 }
    639 
    640 func (d *cborDecDriver) DecodeTime() (t time.Time) {
    641 	if d.advanceNil() {
    642 		return
    643 	}
    644 	if d.bd>>5 != cborMajorTag {
    645 		d.d.errorf("error reading tag; expected major type: %x, got: %x", cborMajorTag, d.bd>>5)
    646 	}
    647 	xtag := d.decUint()
    648 	d.bdRead = false
    649 	return d.decodeTime(xtag)
    650 }
    651 
    652 func (d *cborDecDriver) decodeTime(xtag uint64) (t time.Time) {
    653 	switch xtag {
    654 	case 0:
    655 		var err error
    656 		t, err = time.Parse(time.RFC3339, stringView(d.DecodeStringAsBytes()))
    657 		d.d.onerror(err)
    658 	case 1:
    659 		f1, f2 := math.Modf(d.DecodeFloat64())
    660 		t = time.Unix(int64(f1), int64(f2*1e9))
    661 	default:
    662 		d.d.errorf("invalid tag for time.Time - expecting 0 or 1, got 0x%x", xtag)
    663 	}
    664 	t = t.UTC().Round(time.Microsecond)
    665 	return
    666 }
    667 
    668 func (d *cborDecDriver) DecodeExt(rv interface{}, basetype reflect.Type, xtag uint64, ext Ext) {
    669 	if d.advanceNil() {
    670 		return
    671 	}
    672 	if d.bd>>5 != cborMajorTag {
    673 		d.d.errorf("error reading tag; expected major type: %x, got: %x", cborMajorTag, d.bd>>5)
    674 	}
    675 	realxtag := d.decUint()
    676 	d.bdRead = false
    677 	if ext == nil {
    678 		re := rv.(*RawExt)
    679 		re.Tag = realxtag
    680 		d.d.decode(&re.Value)
    681 	} else if xtag != realxtag {
    682 		d.d.errorf("Wrong extension tag. Got %b. Expecting: %v", realxtag, xtag)
    683 	} else if ext == SelfExt {
    684 		d.d.decodeValue(baseRV(rv), d.h.fnNoExt(basetype))
    685 	} else {
    686 		d.d.interfaceExtConvertAndDecode(rv, ext)
    687 	}
    688 	d.bdRead = false
    689 }
    690 
    691 func (d *cborDecDriver) DecodeNaked() {
    692 	if !d.bdRead {
    693 		d.readNextBd()
    694 	}
    695 
    696 	n := d.d.naked()
    697 	var decodeFurther bool
    698 
    699 	switch d.bd >> 5 {
    700 	case cborMajorUint:
    701 		if d.h.SignedInteger {
    702 			n.v = valueTypeInt
    703 			n.i = d.DecodeInt64()
    704 		} else {
    705 			n.v = valueTypeUint
    706 			n.u = d.DecodeUint64()
    707 		}
    708 	case cborMajorNegInt:
    709 		n.v = valueTypeInt
    710 		n.i = d.DecodeInt64()
    711 	case cborMajorBytes:
    712 		d.d.fauxUnionReadRawBytes(false)
    713 	case cborMajorString:
    714 		n.v = valueTypeString
    715 		n.s = d.d.stringZC(d.DecodeStringAsBytes())
    716 	case cborMajorArray:
    717 		n.v = valueTypeArray
    718 		decodeFurther = true
    719 	case cborMajorMap:
    720 		n.v = valueTypeMap
    721 		decodeFurther = true
    722 	case cborMajorTag:
    723 		n.v = valueTypeExt
    724 		n.u = d.decUint()
    725 		n.l = nil
    726 		if n.u == 0 || n.u == 1 {
    727 			d.bdRead = false
    728 			n.v = valueTypeTime
    729 			n.t = d.decodeTime(n.u)
    730 		} else if d.st && d.h.getExtForTag(n.u) == nil {
    731 			// d.skipTags() // no need to call this - tags already skipped
    732 			d.bdRead = false
    733 			d.DecodeNaked()
    734 			return // return when done (as true recursive function)
    735 		}
    736 	case cborMajorSimpleOrFloat:
    737 		switch d.bd {
    738 		case cborBdNil, cborBdUndefined:
    739 			n.v = valueTypeNil
    740 		case cborBdFalse:
    741 			n.v = valueTypeBool
    742 			n.b = false
    743 		case cborBdTrue:
    744 			n.v = valueTypeBool
    745 			n.b = true
    746 		case cborBdFloat16, cborBdFloat32, cborBdFloat64:
    747 			n.v = valueTypeFloat
    748 			n.f = d.DecodeFloat64()
    749 		default:
    750 			d.d.errorf("decodeNaked: Unrecognized d.bd: 0x%x", d.bd)
    751 		}
    752 	default: // should never happen
    753 		d.d.errorf("decodeNaked: Unrecognized d.bd: 0x%x", d.bd)
    754 	}
    755 	if !decodeFurther {
    756 		d.bdRead = false
    757 	}
    758 }
    759 
    760 func (d *cborDecDriver) uintBytes() (v []byte, ui uint64) {
    761 	// this is only used by nextValueBytes, so it's ok to
    762 	// use readx and bigenstd here.
    763 	switch vv := d.bd & 0x1f; vv {
    764 	case 0x18:
    765 		v = d.d.decRd.readx(1)
    766 		ui = uint64(v[0])
    767 	case 0x19:
    768 		v = d.d.decRd.readx(2)
    769 		ui = uint64(bigenstd.Uint16(v))
    770 	case 0x1a:
    771 		v = d.d.decRd.readx(4)
    772 		ui = uint64(bigenstd.Uint32(v))
    773 	case 0x1b:
    774 		v = d.d.decRd.readx(8)
    775 		ui = uint64(bigenstd.Uint64(v))
    776 	default:
    777 		if vv > 0x1b {
    778 			d.d.errorf("invalid descriptor decoding uint: %x/%s", d.bd, cbordesc(d.bd))
    779 		}
    780 		ui = uint64(vv)
    781 	}
    782 	return
    783 }
    784 
    785 func (d *cborDecDriver) nextValueBytes(v0 []byte) (v []byte) {
    786 	if !d.bdRead {
    787 		d.readNextBd()
    788 	}
    789 	v = v0
    790 	var h = decNextValueBytesHelper{d: &d.d}
    791 	var cursor = d.d.rb.c - 1
    792 	h.append1(&v, d.bd)
    793 	v = d.nextValueBytesBdReadR(v)
    794 	d.bdRead = false
    795 	h.bytesRdV(&v, cursor)
    796 	return
    797 }
    798 
    799 func (d *cborDecDriver) nextValueBytesR(v0 []byte) (v []byte) {
    800 	d.readNextBd()
    801 	v = v0
    802 	var h = decNextValueBytesHelper{d: &d.d}
    803 	h.append1(&v, d.bd)
    804 	return d.nextValueBytesBdReadR(v)
    805 }
    806 
    807 func (d *cborDecDriver) nextValueBytesBdReadR(v0 []byte) (v []byte) {
    808 	v = v0
    809 	var h = decNextValueBytesHelper{d: &d.d}
    810 
    811 	var bs []byte
    812 	var ui uint64
    813 
    814 	switch d.bd >> 5 {
    815 	case cborMajorUint, cborMajorNegInt:
    816 		bs, _ = d.uintBytes()
    817 		h.appendN(&v, bs...)
    818 	case cborMajorString, cborMajorBytes:
    819 		if d.bd == cborBdIndefiniteBytes || d.bd == cborBdIndefiniteString {
    820 			for {
    821 				d.readNextBd()
    822 				h.append1(&v, d.bd)
    823 				if d.bd == cborBdBreak {
    824 					break
    825 				}
    826 				bs, ui = d.uintBytes()
    827 				h.appendN(&v, bs...)
    828 				h.appendN(&v, d.d.decRd.readx(uint(ui))...)
    829 			}
    830 		} else {
    831 			bs, ui = d.uintBytes()
    832 			h.appendN(&v, bs...)
    833 			h.appendN(&v, d.d.decRd.readx(uint(ui))...)
    834 		}
    835 	case cborMajorArray:
    836 		if d.bd == cborBdIndefiniteArray {
    837 			for {
    838 				d.readNextBd()
    839 				h.append1(&v, d.bd)
    840 				if d.bd == cborBdBreak {
    841 					break
    842 				}
    843 				v = d.nextValueBytesBdReadR(v)
    844 			}
    845 		} else {
    846 			bs, ui = d.uintBytes()
    847 			h.appendN(&v, bs...)
    848 			for i := uint64(0); i < ui; i++ {
    849 				v = d.nextValueBytesR(v)
    850 			}
    851 		}
    852 	case cborMajorMap:
    853 		if d.bd == cborBdIndefiniteMap {
    854 			for {
    855 				d.readNextBd()
    856 				h.append1(&v, d.bd)
    857 				if d.bd == cborBdBreak {
    858 					break
    859 				}
    860 				v = d.nextValueBytesBdReadR(v)
    861 				v = d.nextValueBytesR(v)
    862 			}
    863 		} else {
    864 			bs, ui = d.uintBytes()
    865 			h.appendN(&v, bs...)
    866 			for i := uint64(0); i < ui; i++ {
    867 				v = d.nextValueBytesR(v)
    868 				v = d.nextValueBytesR(v)
    869 			}
    870 		}
    871 	case cborMajorTag:
    872 		bs, _ = d.uintBytes()
    873 		h.appendN(&v, bs...)
    874 		v = d.nextValueBytesR(v)
    875 	case cborMajorSimpleOrFloat:
    876 		switch d.bd {
    877 		case cborBdNil, cborBdUndefined, cborBdFalse, cborBdTrue: // pass
    878 		case cborBdFloat16:
    879 			h.appendN(&v, d.d.decRd.readx(2)...)
    880 		case cborBdFloat32:
    881 			h.appendN(&v, d.d.decRd.readx(4)...)
    882 		case cborBdFloat64:
    883 			h.appendN(&v, d.d.decRd.readx(8)...)
    884 		default:
    885 			d.d.errorf("nextValueBytes: Unrecognized d.bd: 0x%x", d.bd)
    886 		}
    887 	default: // should never happen
    888 		d.d.errorf("nextValueBytes: Unrecognized d.bd: 0x%x", d.bd)
    889 	}
    890 	return
    891 }
    892 
    893 // -------------------------
    894 
    895 // CborHandle is a Handle for the CBOR encoding format,
    896 // defined at http://tools.ietf.org/html/rfc7049 and documented further at http://cbor.io .
    897 //
    898 // CBOR is comprehensively supported, including support for:
    899 //   - indefinite-length arrays/maps/bytes/strings
    900 //   - (extension) tags in range 0..0xffff (0 .. 65535)
    901 //   - half, single and double-precision floats
    902 //   - all numbers (1, 2, 4 and 8-byte signed and unsigned integers)
    903 //   - nil, true, false, ...
    904 //   - arrays and maps, bytes and text strings
    905 //
    906 // None of the optional extensions (with tags) defined in the spec are supported out-of-the-box.
    907 // Users can implement them as needed (using SetExt), including spec-documented ones:
    908 //   - timestamp, BigNum, BigFloat, Decimals,
    909 //   - Encoded Text (e.g. URL, regexp, base64, MIME Message), etc.
    910 type CborHandle struct {
    911 	binaryEncodingType
    912 	// noElemSeparators
    913 	BasicHandle
    914 
    915 	// IndefiniteLength=true, means that we encode using indefinitelength
    916 	IndefiniteLength bool
    917 
    918 	// TimeRFC3339 says to encode time.Time using RFC3339 format.
    919 	// If unset, we encode time.Time using seconds past epoch.
    920 	TimeRFC3339 bool
    921 
    922 	// SkipUnexpectedTags says to skip over any tags for which extensions are
    923 	// not defined. This is in keeping with the cbor spec on "Optional Tagging of Items".
    924 	//
    925 	// Furthermore, this allows the skipping over of the Self Describing Tag 0xd9d9f7.
    926 	SkipUnexpectedTags bool
    927 }
    928 
    929 // Name returns the name of the handle: cbor
    930 func (h *CborHandle) Name() string { return "cbor" }
    931 
    932 func (h *CborHandle) desc(bd byte) string { return cbordesc(bd) }
    933 
    934 func (h *CborHandle) newEncDriver() encDriver {
    935 	var e = &cborEncDriver{h: h}
    936 	e.e.e = e
    937 	e.e.init(h)
    938 	e.reset()
    939 	return e
    940 }
    941 
    942 func (h *CborHandle) newDecDriver() decDriver {
    943 	d := &cborDecDriver{h: h, st: h.SkipUnexpectedTags}
    944 	d.d.d = d
    945 	d.d.cbor = true
    946 	d.d.init(h)
    947 	d.reset()
    948 	return d
    949 }
    950 
    951 func (d *cborDecDriver) reset() {
    952 	d.bdAndBdread.reset()
    953 	d.st = d.h.SkipUnexpectedTags
    954 }
    955 
    956 var _ decDriver = (*cborDecDriver)(nil)
    957 var _ encDriver = (*cborEncDriver)(nil)