github.com/patricebensoussan/go/codec@v1.2.99/cbor.go (about)

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