github.com/patricebensoussan/go/codec@v1.2.99/binc.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  // Symbol management:
    13  // - symbols are stored in a symbol map during encoding and decoding.
    14  // - the symbols persist until the (En|De)coder ResetXXX method is called.
    15  
    16  const bincDoPrune = true
    17  
    18  // vd as low 4 bits (there are 16 slots)
    19  const (
    20  	bincVdSpecial byte = iota
    21  	bincVdPosInt
    22  	bincVdNegInt
    23  	bincVdFloat
    24  
    25  	bincVdString
    26  	bincVdByteArray
    27  	bincVdArray
    28  	bincVdMap
    29  
    30  	bincVdTimestamp
    31  	bincVdSmallInt
    32  	_ // bincVdUnicodeOther
    33  	bincVdSymbol
    34  
    35  	_               // bincVdDecimal
    36  	_               // open slot
    37  	_               // open slot
    38  	bincVdCustomExt = 0x0f
    39  )
    40  
    41  const (
    42  	bincSpNil byte = iota
    43  	bincSpFalse
    44  	bincSpTrue
    45  	bincSpNan
    46  	bincSpPosInf
    47  	bincSpNegInf
    48  	bincSpZeroFloat
    49  	bincSpZero
    50  	bincSpNegOne
    51  )
    52  
    53  const (
    54  	_ byte = iota // bincFlBin16
    55  	bincFlBin32
    56  	_ // bincFlBin32e
    57  	bincFlBin64
    58  	_ // bincFlBin64e
    59  	// others not currently supported
    60  )
    61  
    62  const bincBdNil = 0 // bincVdSpecial<<4 | bincSpNil // staticcheck barfs on this (SA4016)
    63  
    64  var (
    65  	bincdescSpecialVsNames = map[byte]string{
    66  		bincSpNil:       "nil",
    67  		bincSpFalse:     "false",
    68  		bincSpTrue:      "true",
    69  		bincSpNan:       "float",
    70  		bincSpPosInf:    "float",
    71  		bincSpNegInf:    "float",
    72  		bincSpZeroFloat: "float",
    73  		bincSpZero:      "uint",
    74  		bincSpNegOne:    "int",
    75  	}
    76  	bincdescVdNames = map[byte]string{
    77  		bincVdSpecial:   "special",
    78  		bincVdSmallInt:  "uint",
    79  		bincVdPosInt:    "uint",
    80  		bincVdFloat:     "float",
    81  		bincVdSymbol:    "string",
    82  		bincVdString:    "string",
    83  		bincVdByteArray: "bytes",
    84  		bincVdTimestamp: "time",
    85  		bincVdCustomExt: "ext",
    86  		bincVdArray:     "array",
    87  		bincVdMap:       "map",
    88  	}
    89  )
    90  
    91  func bincdescbd(bd byte) (s string) {
    92  	return bincdesc(bd>>4, bd&0x0f)
    93  }
    94  
    95  func bincdesc(vd, vs byte) (s string) {
    96  	if vd == bincVdSpecial {
    97  		s = bincdescSpecialVsNames[vs]
    98  	} else {
    99  		s = bincdescVdNames[vd]
   100  	}
   101  	if s == "" {
   102  		s = "unknown"
   103  	}
   104  	return
   105  }
   106  
   107  type bincEncState struct {
   108  	m map[string]uint16 // symbols
   109  }
   110  
   111  func (e bincEncState) captureState() interface{}   { return e.m }
   112  func (e *bincEncState) resetState()                { e.m = nil }
   113  func (e *bincEncState) reset()                     { e.resetState() }
   114  func (e *bincEncState) restoreState(v interface{}) { e.m = v.(map[string]uint16) }
   115  
   116  type bincEncDriver struct {
   117  	noBuiltInTypes
   118  	encDriverNoopContainerWriter
   119  	h *BincHandle
   120  	bincEncState
   121  
   122  	e Encoder
   123  }
   124  
   125  func (e *bincEncDriver) encoder() *Encoder {
   126  	return &e.e
   127  }
   128  
   129  func (e *bincEncDriver) EncodeNil() {
   130  	e.e.encWr.writen1(bincBdNil)
   131  }
   132  
   133  func (e *bincEncDriver) EncodeTime(t time.Time) {
   134  	if t.IsZero() {
   135  		e.EncodeNil()
   136  	} else {
   137  		bs := bincEncodeTime(t)
   138  		e.e.encWr.writen1(bincVdTimestamp<<4 | uint8(len(bs)))
   139  		e.e.encWr.writeb(bs)
   140  	}
   141  }
   142  
   143  func (e *bincEncDriver) EncodeBool(b bool) {
   144  	if b {
   145  		e.e.encWr.writen1(bincVdSpecial<<4 | bincSpTrue)
   146  	} else {
   147  		e.e.encWr.writen1(bincVdSpecial<<4 | bincSpFalse)
   148  	}
   149  }
   150  
   151  func (e *bincEncDriver) encSpFloat(f float64) (done bool) {
   152  	if f == 0 {
   153  		e.e.encWr.writen1(bincVdSpecial<<4 | bincSpZeroFloat)
   154  	} else if math.IsNaN(float64(f)) {
   155  		e.e.encWr.writen1(bincVdSpecial<<4 | bincSpNan)
   156  	} else if math.IsInf(float64(f), +1) {
   157  		e.e.encWr.writen1(bincVdSpecial<<4 | bincSpPosInf)
   158  	} else if math.IsInf(float64(f), -1) {
   159  		e.e.encWr.writen1(bincVdSpecial<<4 | bincSpNegInf)
   160  	} else {
   161  		return
   162  	}
   163  	return true
   164  }
   165  
   166  func (e *bincEncDriver) EncodeFloat32(f float32) {
   167  	if !e.encSpFloat(float64(f)) {
   168  		e.e.encWr.writen1(bincVdFloat<<4 | bincFlBin32)
   169  		bigen.writeUint32(e.e.w(), math.Float32bits(f))
   170  	}
   171  }
   172  
   173  func (e *bincEncDriver) EncodeFloat64(f float64) {
   174  	if e.encSpFloat(f) {
   175  		return
   176  	}
   177  	b := bigen.PutUint64(math.Float64bits(f))
   178  	if bincDoPrune {
   179  		i := 7
   180  		for ; i >= 0 && (b[i] == 0); i-- {
   181  		}
   182  		i++
   183  		if i <= 6 {
   184  			e.e.encWr.writen1(bincVdFloat<<4 | 0x8 | bincFlBin64)
   185  			e.e.encWr.writen1(byte(i))
   186  			e.e.encWr.writeb(b[:i])
   187  			return
   188  		}
   189  	}
   190  	e.e.encWr.writen1(bincVdFloat<<4 | bincFlBin64)
   191  	e.e.encWr.writen8(b)
   192  }
   193  
   194  func (e *bincEncDriver) encIntegerPrune32(bd byte, pos bool, v uint64) {
   195  	b := bigen.PutUint32(uint32(v))
   196  	if bincDoPrune {
   197  		i := byte(pruneSignExt(b[:], pos))
   198  		e.e.encWr.writen1(bd | 3 - i)
   199  		e.e.encWr.writeb(b[i:])
   200  	} else {
   201  		e.e.encWr.writen1(bd | 3)
   202  		e.e.encWr.writen4(b)
   203  	}
   204  }
   205  
   206  func (e *bincEncDriver) encIntegerPrune64(bd byte, pos bool, v uint64) {
   207  	b := bigen.PutUint64(v)
   208  	if bincDoPrune {
   209  		i := byte(pruneSignExt(b[:], pos))
   210  		e.e.encWr.writen1(bd | 7 - i)
   211  		e.e.encWr.writeb(b[i:])
   212  	} else {
   213  		e.e.encWr.writen1(bd | 7)
   214  		e.e.encWr.writen8(b)
   215  	}
   216  }
   217  
   218  func (e *bincEncDriver) EncodeInt(v int64) {
   219  	if v >= 0 {
   220  		e.encUint(bincVdPosInt<<4, true, uint64(v))
   221  	} else if v == -1 {
   222  		e.e.encWr.writen1(bincVdSpecial<<4 | bincSpNegOne)
   223  	} else {
   224  		e.encUint(bincVdNegInt<<4, false, uint64(-v))
   225  	}
   226  }
   227  
   228  func (e *bincEncDriver) EncodeUint(v uint64) {
   229  	e.encUint(bincVdPosInt<<4, true, v)
   230  }
   231  
   232  func (e *bincEncDriver) encUint(bd byte, pos bool, v uint64) {
   233  	if v == 0 {
   234  		e.e.encWr.writen1(bincVdSpecial<<4 | bincSpZero)
   235  	} else if pos && v >= 1 && v <= 16 {
   236  		e.e.encWr.writen1(bincVdSmallInt<<4 | byte(v-1))
   237  	} else if v <= math.MaxUint8 {
   238  		e.e.encWr.writen2(bd|0x0, byte(v))
   239  	} else if v <= math.MaxUint16 {
   240  		e.e.encWr.writen1(bd | 0x01)
   241  		bigen.writeUint16(e.e.w(), uint16(v))
   242  	} else if v <= math.MaxUint32 {
   243  		e.encIntegerPrune32(bd, pos, v)
   244  	} else {
   245  		e.encIntegerPrune64(bd, pos, v)
   246  	}
   247  }
   248  
   249  func (e *bincEncDriver) EncodeExt(v interface{}, basetype reflect.Type, xtag uint64, ext Ext) {
   250  	var bs0, bs []byte
   251  	if ext == SelfExt {
   252  		bs0 = e.e.blist.get(1024)
   253  		bs = bs0
   254  		e.e.sideEncode(v, basetype, &bs)
   255  	} else {
   256  		bs = ext.WriteExt(v)
   257  	}
   258  	if bs == nil {
   259  		e.EncodeNil()
   260  		goto END
   261  	}
   262  	e.encodeExtPreamble(uint8(xtag), len(bs))
   263  	e.e.encWr.writeb(bs)
   264  END:
   265  	if ext == SelfExt {
   266  		e.e.blist.put(bs)
   267  		if !byteSliceSameData(bs0, bs) {
   268  			e.e.blist.put(bs0)
   269  		}
   270  	}
   271  }
   272  
   273  func (e *bincEncDriver) EncodeRawExt(re *RawExt) {
   274  	e.encodeExtPreamble(uint8(re.Tag), len(re.Data))
   275  	e.e.encWr.writeb(re.Data)
   276  }
   277  
   278  func (e *bincEncDriver) encodeExtPreamble(xtag byte, length int) {
   279  	e.encLen(bincVdCustomExt<<4, uint64(length))
   280  	e.e.encWr.writen1(xtag)
   281  }
   282  
   283  func (e *bincEncDriver) WriteArrayStart(length int) {
   284  	e.encLen(bincVdArray<<4, uint64(length))
   285  }
   286  
   287  func (e *bincEncDriver) WriteMapStart(length int) {
   288  	e.encLen(bincVdMap<<4, uint64(length))
   289  }
   290  
   291  func (e *bincEncDriver) EncodeSymbol(v string) {
   292  	//symbols only offer benefit when string length > 1.
   293  	//This is because strings with length 1 take only 2 bytes to store
   294  	//(bd with embedded length, and single byte for string val).
   295  
   296  	l := len(v)
   297  	if l == 0 {
   298  		e.encBytesLen(cUTF8, 0)
   299  		return
   300  	} else if l == 1 {
   301  		e.encBytesLen(cUTF8, 1)
   302  		e.e.encWr.writen1(v[0])
   303  		return
   304  	}
   305  	if e.m == nil {
   306  		e.m = make(map[string]uint16, 16)
   307  	}
   308  	ui, ok := e.m[v]
   309  	if ok {
   310  		if ui <= math.MaxUint8 {
   311  			e.e.encWr.writen2(bincVdSymbol<<4, byte(ui))
   312  		} else {
   313  			e.e.encWr.writen1(bincVdSymbol<<4 | 0x8)
   314  			bigen.writeUint16(e.e.w(), ui)
   315  		}
   316  	} else {
   317  		e.e.seq++
   318  		ui = e.e.seq
   319  		e.m[v] = ui
   320  		var lenprec uint8
   321  		if l <= math.MaxUint8 {
   322  			// lenprec = 0
   323  		} else if l <= math.MaxUint16 {
   324  			lenprec = 1
   325  		} else if int64(l) <= math.MaxUint32 {
   326  			lenprec = 2
   327  		} else {
   328  			lenprec = 3
   329  		}
   330  		if ui <= math.MaxUint8 {
   331  			e.e.encWr.writen2(bincVdSymbol<<4|0x0|0x4|lenprec, byte(ui))
   332  		} else {
   333  			e.e.encWr.writen1(bincVdSymbol<<4 | 0x8 | 0x4 | lenprec)
   334  			bigen.writeUint16(e.e.w(), ui)
   335  		}
   336  		if lenprec == 0 {
   337  			e.e.encWr.writen1(byte(l))
   338  		} else if lenprec == 1 {
   339  			bigen.writeUint16(e.e.w(), uint16(l))
   340  		} else if lenprec == 2 {
   341  			bigen.writeUint32(e.e.w(), uint32(l))
   342  		} else {
   343  			bigen.writeUint64(e.e.w(), uint64(l))
   344  		}
   345  		e.e.encWr.writestr(v)
   346  	}
   347  }
   348  
   349  func (e *bincEncDriver) EncodeString(v string) {
   350  	if e.h.StringToRaw {
   351  		e.encLen(bincVdByteArray<<4, uint64(len(v)))
   352  		if len(v) > 0 {
   353  			e.e.encWr.writestr(v)
   354  		}
   355  		return
   356  	}
   357  	e.EncodeStringEnc(cUTF8, v)
   358  }
   359  
   360  func (e *bincEncDriver) EncodeStringEnc(c charEncoding, v string) {
   361  	if e.e.c == containerMapKey && c == cUTF8 && (e.h.AsSymbols == 1) {
   362  		e.EncodeSymbol(v)
   363  		return
   364  	}
   365  	e.encLen(bincVdString<<4, uint64(len(v)))
   366  	if len(v) > 0 {
   367  		e.e.encWr.writestr(v)
   368  	}
   369  }
   370  
   371  func (e *bincEncDriver) EncodeStringBytesRaw(v []byte) {
   372  	if v == nil {
   373  		e.EncodeNil()
   374  		return
   375  	}
   376  	e.encLen(bincVdByteArray<<4, uint64(len(v)))
   377  	if len(v) > 0 {
   378  		e.e.encWr.writeb(v)
   379  	}
   380  }
   381  
   382  func (e *bincEncDriver) encBytesLen(c charEncoding, length uint64) {
   383  	// MARKER: we currently only support UTF-8 (string) and RAW (bytearray).
   384  	// We should consider supporting bincUnicodeOther.
   385  
   386  	if c == cRAW {
   387  		e.encLen(bincVdByteArray<<4, length)
   388  	} else {
   389  		e.encLen(bincVdString<<4, length)
   390  	}
   391  }
   392  
   393  func (e *bincEncDriver) encLen(bd byte, l uint64) {
   394  	if l < 12 {
   395  		e.e.encWr.writen1(bd | uint8(l+4))
   396  	} else {
   397  		e.encLenNumber(bd, l)
   398  	}
   399  }
   400  
   401  func (e *bincEncDriver) encLenNumber(bd byte, v uint64) {
   402  	if v <= math.MaxUint8 {
   403  		e.e.encWr.writen2(bd, byte(v))
   404  	} else if v <= math.MaxUint16 {
   405  		e.e.encWr.writen1(bd | 0x01)
   406  		bigen.writeUint16(e.e.w(), uint16(v))
   407  	} else if v <= math.MaxUint32 {
   408  		e.e.encWr.writen1(bd | 0x02)
   409  		bigen.writeUint32(e.e.w(), uint32(v))
   410  	} else {
   411  		e.e.encWr.writen1(bd | 0x03)
   412  		bigen.writeUint64(e.e.w(), uint64(v))
   413  	}
   414  }
   415  
   416  //------------------------------------
   417  
   418  type bincDecState struct {
   419  	bdRead bool
   420  	bd     byte
   421  	vd     byte
   422  	vs     byte
   423  
   424  	_ bool
   425  	// MARKER: consider using binary search here instead of a map (ie bincDecSymbol)
   426  	s map[uint16][]byte
   427  }
   428  
   429  func (x bincDecState) captureState() interface{}   { return x }
   430  func (x *bincDecState) resetState()                { *x = bincDecState{} }
   431  func (x *bincDecState) reset()                     { x.resetState() }
   432  func (x *bincDecState) restoreState(v interface{}) { *x = v.(bincDecState) }
   433  
   434  type bincDecDriver struct {
   435  	decDriverNoopContainerReader
   436  	decDriverNoopNumberHelper
   437  	noBuiltInTypes
   438  
   439  	h *BincHandle
   440  
   441  	bincDecState
   442  	d Decoder
   443  }
   444  
   445  func (d *bincDecDriver) decoder() *Decoder {
   446  	return &d.d
   447  }
   448  
   449  func (d *bincDecDriver) descBd() string {
   450  	return sprintf("%v (%s)", d.bd, bincdescbd(d.bd))
   451  }
   452  
   453  func (d *bincDecDriver) readNextBd() {
   454  	d.bd = d.d.decRd.readn1()
   455  	d.vd = d.bd >> 4
   456  	d.vs = d.bd & 0x0f
   457  	d.bdRead = true
   458  }
   459  
   460  func (d *bincDecDriver) advanceNil() (null bool) {
   461  	if !d.bdRead {
   462  		d.readNextBd()
   463  	}
   464  	if d.bd == bincBdNil {
   465  		d.bdRead = false
   466  		return true // null = true
   467  	}
   468  	return
   469  }
   470  
   471  func (d *bincDecDriver) TryNil() bool {
   472  	return d.advanceNil()
   473  }
   474  
   475  func (d *bincDecDriver) ContainerType() (vt valueType) {
   476  	if !d.bdRead {
   477  		d.readNextBd()
   478  	}
   479  	if d.bd == bincBdNil {
   480  		d.bdRead = false
   481  		return valueTypeNil
   482  	} else if d.vd == bincVdByteArray {
   483  		return valueTypeBytes
   484  	} else if d.vd == bincVdString {
   485  		return valueTypeString
   486  	} else if d.vd == bincVdArray {
   487  		return valueTypeArray
   488  	} else if d.vd == bincVdMap {
   489  		return valueTypeMap
   490  	}
   491  	return valueTypeUnset
   492  }
   493  
   494  func (d *bincDecDriver) DecodeTime() (t time.Time) {
   495  	if d.advanceNil() {
   496  		return
   497  	}
   498  	if d.vd != bincVdTimestamp {
   499  		d.d.errorf("cannot decode time - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
   500  	}
   501  	t, err := bincDecodeTime(d.d.decRd.readx(uint(d.vs)))
   502  	halt.onerror(err)
   503  	d.bdRead = false
   504  	return
   505  }
   506  
   507  func (d *bincDecDriver) decFloatPruned(maxlen uint8) {
   508  	l := d.d.decRd.readn1()
   509  	if l > maxlen {
   510  		d.d.errorf("cannot read float - at most %v bytes used to represent float - received %v bytes", maxlen, l)
   511  	}
   512  	for i := l; i < maxlen; i++ {
   513  		d.d.b[i] = 0
   514  	}
   515  	d.d.decRd.readb(d.d.b[0:l])
   516  }
   517  
   518  func (d *bincDecDriver) decFloatPre32() (b [4]byte) {
   519  	if d.vs&0x8 == 0 {
   520  		b = d.d.decRd.readn4()
   521  	} else {
   522  		d.decFloatPruned(4)
   523  		copy(b[:], d.d.b[:])
   524  	}
   525  	return
   526  }
   527  
   528  func (d *bincDecDriver) decFloatPre64() (b [8]byte) {
   529  	if d.vs&0x8 == 0 {
   530  		b = d.d.decRd.readn8()
   531  	} else {
   532  		d.decFloatPruned(8)
   533  		copy(b[:], d.d.b[:])
   534  	}
   535  	return
   536  }
   537  
   538  func (d *bincDecDriver) decFloatVal() (f float64) {
   539  	switch d.vs & 0x7 {
   540  	case bincFlBin32:
   541  		f = float64(math.Float32frombits(bigen.Uint32(d.decFloatPre32())))
   542  	case bincFlBin64:
   543  		f = math.Float64frombits(bigen.Uint64(d.decFloatPre64()))
   544  	default:
   545  		// ok = false
   546  		d.d.errorf("read float supports only float32/64 - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
   547  	}
   548  	return
   549  }
   550  
   551  func (d *bincDecDriver) decUint() (v uint64) {
   552  	switch d.vs {
   553  	case 0:
   554  		v = uint64(d.d.decRd.readn1())
   555  	case 1:
   556  		v = uint64(bigen.Uint16(d.d.decRd.readn2()))
   557  	case 2:
   558  		v = uint64(bigen.Uint32(d.d.decRd.readn3()))
   559  	case 3:
   560  		v = uint64(bigen.Uint32(d.d.decRd.readn4()))
   561  	case 4, 5, 6:
   562  		var b [8]byte
   563  		lim := 7 - d.vs
   564  		bs := d.d.b[lim:8]
   565  		d.d.decRd.readb(bs)
   566  		copy(b[lim:], bs)
   567  		v = bigen.Uint64(b)
   568  	case 7:
   569  		v = bigen.Uint64(d.d.decRd.readn8())
   570  	default:
   571  		d.d.errorf("unsigned integers with greater than 64 bits of precision not supported: d.vs: %v %x", d.vs, d.vs)
   572  	}
   573  	return
   574  }
   575  
   576  func (d *bincDecDriver) uintBytes() (bs []byte) {
   577  	switch d.vs {
   578  	case 0:
   579  		bs = d.d.b[:1]
   580  		bs[0] = d.d.decRd.readn1()
   581  	case 1:
   582  		bs = d.d.b[:2]
   583  		d.d.decRd.readb(bs)
   584  	case 2:
   585  		bs = d.d.b[:3]
   586  		d.d.decRd.readb(bs)
   587  	case 3:
   588  		bs = d.d.b[:4]
   589  		d.d.decRd.readb(bs)
   590  	case 4, 5, 6:
   591  		lim := 7 - d.vs
   592  		bs = d.d.b[lim:8]
   593  		d.d.decRd.readb(bs)
   594  	case 7:
   595  		bs = d.d.b[:8]
   596  		d.d.decRd.readb(bs)
   597  	default:
   598  		d.d.errorf("unsigned integers with greater than 64 bits of precision not supported: d.vs: %v %x", d.vs, d.vs)
   599  	}
   600  	return
   601  }
   602  
   603  func (d *bincDecDriver) decInteger() (ui uint64, neg, ok bool) {
   604  	ok = true
   605  	vd, vs := d.vd, d.vs
   606  	if vd == bincVdPosInt {
   607  		ui = d.decUint()
   608  	} else if vd == bincVdNegInt {
   609  		ui = d.decUint()
   610  		neg = true
   611  	} else if vd == bincVdSmallInt {
   612  		ui = uint64(d.vs) + 1
   613  	} else if vd == bincVdSpecial {
   614  		if vs == bincSpZero {
   615  			// i = 0
   616  		} else if vs == bincSpNegOne {
   617  			neg = true
   618  			ui = 1
   619  		} else {
   620  			ok = false
   621  			// d.d.errorf("integer decode has invalid special value %x-%x/%s", d.vd, d.vs, bincdesc(d.vd, d.vs))
   622  		}
   623  	} else {
   624  		ok = false
   625  		// d.d.errorf("integer can only be decoded from int/uint. d.bd: 0x%x, d.vd: 0x%x", d.bd, d.vd)
   626  	}
   627  	return
   628  }
   629  
   630  func (d *bincDecDriver) decFloat() (f float64, ok bool) {
   631  	ok = true
   632  	vd, vs := d.vd, d.vs
   633  	if vd == bincVdSpecial {
   634  		if vs == bincSpNan {
   635  			f = math.NaN()
   636  		} else if vs == bincSpPosInf {
   637  			f = math.Inf(1)
   638  		} else if vs == bincSpZeroFloat || vs == bincSpZero {
   639  
   640  		} else if vs == bincSpNegInf {
   641  			f = math.Inf(-1)
   642  		} else {
   643  			ok = false
   644  			// d.d.errorf("float - invalid special value %x-%x/%s", d.vd, d.vs, bincdesc(d.vd, d.vs))
   645  		}
   646  	} else if vd == bincVdFloat {
   647  		f = d.decFloatVal()
   648  	} else {
   649  		ok = false
   650  	}
   651  	return
   652  }
   653  
   654  func (d *bincDecDriver) DecodeInt64() (i int64) {
   655  	if d.advanceNil() {
   656  		return
   657  	}
   658  	i = decNegintPosintFloatNumberHelper{&d.d}.int64(d.decInteger())
   659  	d.bdRead = false
   660  	return
   661  }
   662  
   663  func (d *bincDecDriver) DecodeUint64() (ui uint64) {
   664  	if d.advanceNil() {
   665  		return
   666  	}
   667  	ui = decNegintPosintFloatNumberHelper{&d.d}.uint64(d.decInteger())
   668  	d.bdRead = false
   669  	return
   670  }
   671  
   672  func (d *bincDecDriver) DecodeFloat64() (f float64) {
   673  	if d.advanceNil() {
   674  		return
   675  	}
   676  	f = decNegintPosintFloatNumberHelper{&d.d}.float64(d.decFloat())
   677  	d.bdRead = false
   678  	return
   679  }
   680  
   681  func (d *bincDecDriver) DecodeBool() (b bool) {
   682  	if d.advanceNil() {
   683  		return
   684  	}
   685  	if d.bd == (bincVdSpecial | bincSpFalse) {
   686  		// b = false
   687  	} else if d.bd == (bincVdSpecial | bincSpTrue) {
   688  		b = true
   689  	} else {
   690  		d.d.errorf("bool - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
   691  	}
   692  	d.bdRead = false
   693  	return
   694  }
   695  
   696  func (d *bincDecDriver) ReadMapStart() (length int) {
   697  	if d.advanceNil() {
   698  		return containerLenNil
   699  	}
   700  	if d.vd != bincVdMap {
   701  		d.d.errorf("map - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
   702  	}
   703  	length = d.decLen()
   704  	d.bdRead = false
   705  	return
   706  }
   707  
   708  func (d *bincDecDriver) ReadArrayStart() (length int) {
   709  	if d.advanceNil() {
   710  		return containerLenNil
   711  	}
   712  	if d.vd != bincVdArray {
   713  		d.d.errorf("array - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
   714  	}
   715  	length = d.decLen()
   716  	d.bdRead = false
   717  	return
   718  }
   719  
   720  func (d *bincDecDriver) decLen() int {
   721  	if d.vs > 3 {
   722  		return int(d.vs - 4)
   723  	}
   724  	return int(d.decLenNumber())
   725  }
   726  
   727  func (d *bincDecDriver) decLenNumber() (v uint64) {
   728  	if x := d.vs; x == 0 {
   729  		v = uint64(d.d.decRd.readn1())
   730  	} else if x == 1 {
   731  		v = uint64(bigen.Uint16(d.d.decRd.readn2()))
   732  	} else if x == 2 {
   733  		v = uint64(bigen.Uint32(d.d.decRd.readn4()))
   734  	} else {
   735  		v = bigen.Uint64(d.d.decRd.readn8())
   736  	}
   737  	return
   738  }
   739  
   740  // func (d *bincDecDriver) decStringBytes(bs []byte, zerocopy bool) (bs2 []byte) {
   741  func (d *bincDecDriver) DecodeStringAsBytes() (bs2 []byte) {
   742  	d.d.decByteState = decByteStateNone
   743  	if d.advanceNil() {
   744  		return
   745  	}
   746  	var slen = -1
   747  	switch d.vd {
   748  	case bincVdString, bincVdByteArray:
   749  		slen = d.decLen()
   750  		if d.d.bytes {
   751  			d.d.decByteState = decByteStateZerocopy
   752  			bs2 = d.d.decRd.rb.readx(uint(slen))
   753  		} else {
   754  			d.d.decByteState = decByteStateReuseBuf
   755  			bs2 = decByteSlice(d.d.r(), slen, d.d.h.MaxInitLen, d.d.b[:])
   756  		}
   757  	case bincVdSymbol:
   758  		// zerocopy doesn't apply for symbols,
   759  		// as the values must be stored in a table for later use.
   760  		var symbol uint16
   761  		vs := d.vs
   762  		if vs&0x8 == 0 {
   763  			symbol = uint16(d.d.decRd.readn1())
   764  		} else {
   765  			symbol = uint16(bigen.Uint16(d.d.decRd.readn2()))
   766  		}
   767  		if d.s == nil {
   768  			d.s = make(map[uint16][]byte, 16)
   769  		}
   770  
   771  		if vs&0x4 == 0 {
   772  			bs2 = d.s[symbol]
   773  		} else {
   774  			switch vs & 0x3 {
   775  			case 0:
   776  				slen = int(d.d.decRd.readn1())
   777  			case 1:
   778  				slen = int(bigen.Uint16(d.d.decRd.readn2()))
   779  			case 2:
   780  				slen = int(bigen.Uint32(d.d.decRd.readn4()))
   781  			case 3:
   782  				slen = int(bigen.Uint64(d.d.decRd.readn8()))
   783  			}
   784  			// As we are using symbols, do not store any part of
   785  			// the parameter bs in the map, as it might be a shared buffer.
   786  			bs2 = decByteSlice(d.d.r(), slen, d.d.h.MaxInitLen, nil)
   787  			d.s[symbol] = bs2
   788  		}
   789  	default:
   790  		d.d.errorf("string/bytes - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
   791  	}
   792  	d.bdRead = false
   793  	return
   794  }
   795  
   796  func (d *bincDecDriver) DecodeBytes(bs []byte) (bsOut []byte) {
   797  	d.d.decByteState = decByteStateNone
   798  	if d.advanceNil() {
   799  		return
   800  	}
   801  	if d.vd == bincVdArray {
   802  		if bs == nil {
   803  			bs = d.d.b[:]
   804  			d.d.decByteState = decByteStateReuseBuf
   805  		}
   806  		slen := d.ReadArrayStart()
   807  		var changed bool
   808  		if bs, changed = usableByteSlice(bs, slen); changed {
   809  			d.d.decByteState = decByteStateNone
   810  		}
   811  		for i := 0; i < slen; i++ {
   812  			bs[i] = uint8(chkOvf.UintV(d.DecodeUint64(), 8))
   813  		}
   814  		return bs
   815  	}
   816  	var clen int
   817  	if d.vd == bincVdString || d.vd == bincVdByteArray {
   818  		clen = d.decLen()
   819  	} else {
   820  		d.d.errorf("bytes - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
   821  	}
   822  	d.bdRead = false
   823  	if d.d.zerocopy() {
   824  		d.d.decByteState = decByteStateZerocopy
   825  		return d.d.decRd.rb.readx(uint(clen))
   826  	}
   827  	if bs == nil {
   828  		bs = d.d.b[:]
   829  		d.d.decByteState = decByteStateReuseBuf
   830  	}
   831  	return decByteSlice(d.d.r(), clen, d.d.h.MaxInitLen, bs)
   832  }
   833  
   834  func (d *bincDecDriver) DecodeExt(rv interface{}, basetype reflect.Type, xtag uint64, ext Ext) {
   835  	if xtag > 0xff {
   836  		d.d.errorf("ext: tag must be <= 0xff; got: %v", xtag)
   837  	}
   838  	if d.advanceNil() {
   839  		return
   840  	}
   841  	xbs, realxtag1, zerocopy := d.decodeExtV(ext != nil, uint8(xtag))
   842  	realxtag := uint64(realxtag1)
   843  	if ext == nil {
   844  		re := rv.(*RawExt)
   845  		re.Tag = realxtag
   846  		re.setData(xbs, zerocopy)
   847  	} else if ext == SelfExt {
   848  		d.d.sideDecode(rv, basetype, xbs)
   849  	} else {
   850  		ext.ReadExt(rv, xbs)
   851  	}
   852  }
   853  
   854  func (d *bincDecDriver) decodeExtV(verifyTag bool, tag byte) (xbs []byte, xtag byte, zerocopy bool) {
   855  	if d.vd == bincVdCustomExt {
   856  		l := d.decLen()
   857  		xtag = d.d.decRd.readn1()
   858  		if verifyTag && xtag != tag {
   859  			d.d.errorf("wrong extension tag - got %b, expecting: %v", xtag, tag)
   860  		}
   861  		if d.d.bytes {
   862  			xbs = d.d.decRd.rb.readx(uint(l))
   863  			zerocopy = true
   864  		} else {
   865  			xbs = decByteSlice(d.d.r(), l, d.d.h.MaxInitLen, d.d.b[:])
   866  		}
   867  	} else if d.vd == bincVdByteArray {
   868  		xbs = d.DecodeBytes(nil)
   869  	} else {
   870  		d.d.errorf("ext expects extensions or byte array - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
   871  	}
   872  	d.bdRead = false
   873  	return
   874  }
   875  
   876  func (d *bincDecDriver) DecodeNaked() {
   877  	if !d.bdRead {
   878  		d.readNextBd()
   879  	}
   880  
   881  	n := d.d.naked()
   882  	var decodeFurther bool
   883  
   884  	switch d.vd {
   885  	case bincVdSpecial:
   886  		switch d.vs {
   887  		case bincSpNil:
   888  			n.v = valueTypeNil
   889  		case bincSpFalse:
   890  			n.v = valueTypeBool
   891  			n.b = false
   892  		case bincSpTrue:
   893  			n.v = valueTypeBool
   894  			n.b = true
   895  		case bincSpNan:
   896  			n.v = valueTypeFloat
   897  			n.f = math.NaN()
   898  		case bincSpPosInf:
   899  			n.v = valueTypeFloat
   900  			n.f = math.Inf(1)
   901  		case bincSpNegInf:
   902  			n.v = valueTypeFloat
   903  			n.f = math.Inf(-1)
   904  		case bincSpZeroFloat:
   905  			n.v = valueTypeFloat
   906  			n.f = float64(0)
   907  		case bincSpZero:
   908  			n.v = valueTypeUint
   909  			n.u = uint64(0) // int8(0)
   910  		case bincSpNegOne:
   911  			n.v = valueTypeInt
   912  			n.i = int64(-1) // int8(-1)
   913  		default:
   914  			d.d.errorf("cannot infer value - unrecognized special value %x-%x/%s", d.vd, d.vs, bincdesc(d.vd, d.vs))
   915  		}
   916  	case bincVdSmallInt:
   917  		n.v = valueTypeUint
   918  		n.u = uint64(int8(d.vs)) + 1 // int8(d.vs) + 1
   919  	case bincVdPosInt:
   920  		n.v = valueTypeUint
   921  		n.u = d.decUint()
   922  	case bincVdNegInt:
   923  		n.v = valueTypeInt
   924  		n.i = -(int64(d.decUint()))
   925  	case bincVdFloat:
   926  		n.v = valueTypeFloat
   927  		n.f = d.decFloatVal()
   928  	case bincVdString:
   929  		n.v = valueTypeString
   930  		n.s = d.d.stringZC(d.DecodeStringAsBytes())
   931  	case bincVdByteArray:
   932  		d.d.fauxUnionReadRawBytes(false)
   933  	case bincVdSymbol:
   934  		n.v = valueTypeSymbol
   935  		n.s = d.d.stringZC(d.DecodeStringAsBytes())
   936  	case bincVdTimestamp:
   937  		n.v = valueTypeTime
   938  		tt, err := bincDecodeTime(d.d.decRd.readx(uint(d.vs)))
   939  		halt.onerror(err)
   940  		n.t = tt
   941  	case bincVdCustomExt:
   942  		n.v = valueTypeExt
   943  		l := d.decLen()
   944  		n.u = uint64(d.d.decRd.readn1())
   945  		if d.d.bytes {
   946  			n.l = d.d.decRd.rb.readx(uint(l))
   947  		} else {
   948  			n.l = decByteSlice(d.d.r(), l, d.d.h.MaxInitLen, d.d.b[:])
   949  		}
   950  	case bincVdArray:
   951  		n.v = valueTypeArray
   952  		decodeFurther = true
   953  	case bincVdMap:
   954  		n.v = valueTypeMap
   955  		decodeFurther = true
   956  	default:
   957  		d.d.errorf("cannot infer value - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
   958  	}
   959  
   960  	if !decodeFurther {
   961  		d.bdRead = false
   962  	}
   963  	if n.v == valueTypeUint && d.h.SignedInteger {
   964  		n.v = valueTypeInt
   965  		n.i = int64(n.u)
   966  	}
   967  }
   968  
   969  func (d *bincDecDriver) nextValueBytes(v0 []byte) (v []byte) {
   970  	if !d.bdRead {
   971  		d.readNextBd()
   972  	}
   973  	v = v0
   974  	var h = decNextValueBytesHelper{d: &d.d}
   975  	var cursor = d.d.rb.c - 1
   976  	h.append1(&v, d.bd)
   977  	v = d.nextValueBytesBdReadR(v)
   978  	d.bdRead = false
   979  	h.bytesRdV(&v, cursor)
   980  	return
   981  }
   982  
   983  func (d *bincDecDriver) nextValueBytesR(v0 []byte) (v []byte) {
   984  	d.readNextBd()
   985  	v = v0
   986  	var h = decNextValueBytesHelper{d: &d.d}
   987  	h.append1(&v, d.bd)
   988  	return d.nextValueBytesBdReadR(v)
   989  }
   990  
   991  func (d *bincDecDriver) nextValueBytesBdReadR(v0 []byte) (v []byte) {
   992  	v = v0
   993  	var h = decNextValueBytesHelper{d: &d.d}
   994  
   995  	fnLen := func(vs byte) uint {
   996  		switch vs {
   997  		case 0:
   998  			x := d.d.decRd.readn1()
   999  			h.append1(&v, x)
  1000  			return uint(x)
  1001  		case 1:
  1002  			x := d.d.decRd.readn2()
  1003  			h.appendN(&v, x[:]...)
  1004  			return uint(bigen.Uint16(x))
  1005  		case 2:
  1006  			x := d.d.decRd.readn4()
  1007  			h.appendN(&v, x[:]...)
  1008  			return uint(bigen.Uint32(x))
  1009  		case 3:
  1010  			x := d.d.decRd.readn8()
  1011  			h.appendN(&v, x[:]...)
  1012  			return uint(bigen.Uint64(x))
  1013  		default:
  1014  			return uint(vs - 4)
  1015  		}
  1016  	}
  1017  
  1018  	var clen uint
  1019  
  1020  	switch d.vd {
  1021  	case bincVdSpecial:
  1022  		switch d.vs {
  1023  		case bincSpNil, bincSpFalse, bincSpTrue, bincSpNan, bincSpPosInf: // pass
  1024  		case bincSpNegInf, bincSpZeroFloat, bincSpZero, bincSpNegOne: // pass
  1025  		default:
  1026  			d.d.errorf("cannot infer value - unrecognized special value %x-%x/%s", d.vd, d.vs, bincdesc(d.vd, d.vs))
  1027  		}
  1028  	case bincVdSmallInt: // pass
  1029  	case bincVdPosInt, bincVdNegInt:
  1030  		bs := d.uintBytes()
  1031  		h.appendN(&v, bs...)
  1032  	case bincVdFloat:
  1033  		fn := func(xlen byte) {
  1034  			if d.vs&0x8 != 0 {
  1035  				xlen = d.d.decRd.readn1()
  1036  				h.append1(&v, xlen)
  1037  				if xlen > 8 {
  1038  					d.d.errorf("cannot read float - at most 8 bytes used to represent float - received %v bytes", xlen)
  1039  				}
  1040  			}
  1041  			d.d.decRd.readb(d.d.b[:xlen])
  1042  			h.appendN(&v, d.d.b[:xlen]...)
  1043  		}
  1044  		switch d.vs & 0x7 {
  1045  		case bincFlBin32:
  1046  			fn(4)
  1047  		case bincFlBin64:
  1048  			fn(8)
  1049  		default:
  1050  			d.d.errorf("read float supports only float32/64 - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
  1051  		}
  1052  	case bincVdString, bincVdByteArray:
  1053  		clen = fnLen(d.vs)
  1054  		h.appendN(&v, d.d.decRd.readx(clen)...)
  1055  	case bincVdSymbol:
  1056  		if d.vs&0x8 == 0 {
  1057  			h.append1(&v, d.d.decRd.readn1())
  1058  		} else {
  1059  			h.appendN(&v, d.d.decRd.rb.readx(2)...)
  1060  		}
  1061  		if d.vs&0x4 != 0 {
  1062  			clen = fnLen(d.vs & 0x3)
  1063  			h.appendN(&v, d.d.decRd.readx(clen)...)
  1064  		}
  1065  	case bincVdTimestamp:
  1066  		h.appendN(&v, d.d.decRd.readx(uint(d.vs))...)
  1067  	case bincVdCustomExt:
  1068  		clen = fnLen(d.vs)
  1069  		h.append1(&v, d.d.decRd.readn1()) // tag
  1070  		h.appendN(&v, d.d.decRd.readx(clen)...)
  1071  	case bincVdArray:
  1072  		clen = fnLen(d.vs)
  1073  		for i := uint(0); i < clen; i++ {
  1074  			v = d.nextValueBytesR(v)
  1075  		}
  1076  	case bincVdMap:
  1077  		clen = fnLen(d.vs)
  1078  		for i := uint(0); i < clen; i++ {
  1079  			v = d.nextValueBytesR(v)
  1080  			v = d.nextValueBytesR(v)
  1081  		}
  1082  	default:
  1083  		d.d.errorf("cannot infer value - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
  1084  	}
  1085  	return
  1086  }
  1087  
  1088  //------------------------------------
  1089  
  1090  //BincHandle is a Handle for the Binc Schema-Free Encoding Format
  1091  //defined at https://github.com/ugorji/binc .
  1092  //
  1093  //BincHandle currently supports all Binc features with the following EXCEPTIONS:
  1094  //  - only integers up to 64 bits of precision are supported.
  1095  //    big integers are unsupported.
  1096  //  - Only IEEE 754 binary32 and binary64 floats are supported (ie Go float32 and float64 types).
  1097  //    extended precision and decimal IEEE 754 floats are unsupported.
  1098  //  - Only UTF-8 strings supported.
  1099  //    Unicode_Other Binc types (UTF16, UTF32) are currently unsupported.
  1100  //
  1101  //Note that these EXCEPTIONS are temporary and full support is possible and may happen soon.
  1102  type BincHandle struct {
  1103  	BasicHandle
  1104  	binaryEncodingType
  1105  	// noElemSeparators
  1106  
  1107  	// AsSymbols defines what should be encoded as symbols.
  1108  	//
  1109  	// Encoding as symbols can reduce the encoded size significantly.
  1110  	//
  1111  	// However, during decoding, each string to be encoded as a symbol must
  1112  	// be checked to see if it has been seen before. Consequently, encoding time
  1113  	// will increase if using symbols, because string comparisons has a clear cost.
  1114  	//
  1115  	// Values:
  1116  	// - 0: default: library uses best judgement
  1117  	// - 1: use symbols
  1118  	// - 2: do not use symbols
  1119  	AsSymbols uint8
  1120  
  1121  	// AsSymbols: may later on introduce more options ...
  1122  	// - m: map keys
  1123  	// - s: struct fields
  1124  	// - n: none
  1125  	// - a: all: same as m, s, ...
  1126  
  1127  	// _ [7]uint64 // padding (cache-aligned)
  1128  }
  1129  
  1130  // Name returns the name of the handle: binc
  1131  func (h *BincHandle) Name() string { return "binc" }
  1132  
  1133  func (h *BincHandle) desc(bd byte) string { return bincdesc(bd>>4, bd&0x0f) }
  1134  
  1135  func (h *BincHandle) newEncDriver() encDriver {
  1136  	var e = &bincEncDriver{h: h}
  1137  	e.e.e = e
  1138  	e.e.init(h)
  1139  	e.reset()
  1140  	return e
  1141  }
  1142  
  1143  func (h *BincHandle) newDecDriver() decDriver {
  1144  	d := &bincDecDriver{h: h}
  1145  	d.d.d = d
  1146  	d.d.init(h)
  1147  	d.reset()
  1148  	return d
  1149  }
  1150  
  1151  // var timeDigits = [...]byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
  1152  
  1153  // EncodeTime encodes a time.Time as a []byte, including
  1154  // information on the instant in time and UTC offset.
  1155  //
  1156  // Format Description
  1157  //
  1158  //   A timestamp is composed of 3 components:
  1159  //
  1160  //   - secs: signed integer representing seconds since unix epoch
  1161  //   - nsces: unsigned integer representing fractional seconds as a
  1162  //     nanosecond offset within secs, in the range 0 <= nsecs < 1e9
  1163  //   - tz: signed integer representing timezone offset in minutes east of UTC,
  1164  //     and a dst (daylight savings time) flag
  1165  //
  1166  //   When encoding a timestamp, the first byte is the descriptor, which
  1167  //   defines which components are encoded and how many bytes are used to
  1168  //   encode secs and nsecs components. *If secs/nsecs is 0 or tz is UTC, it
  1169  //   is not encoded in the byte array explicitly*.
  1170  //
  1171  //       Descriptor 8 bits are of the form `A B C DDD EE`:
  1172  //           A:   Is secs component encoded? 1 = true
  1173  //           B:   Is nsecs component encoded? 1 = true
  1174  //           C:   Is tz component encoded? 1 = true
  1175  //           DDD: Number of extra bytes for secs (range 0-7).
  1176  //                If A = 1, secs encoded in DDD+1 bytes.
  1177  //                    If A = 0, secs is not encoded, and is assumed to be 0.
  1178  //                    If A = 1, then we need at least 1 byte to encode secs.
  1179  //                    DDD says the number of extra bytes beyond that 1.
  1180  //                    E.g. if DDD=0, then secs is represented in 1 byte.
  1181  //                         if DDD=2, then secs is represented in 3 bytes.
  1182  //           EE:  Number of extra bytes for nsecs (range 0-3).
  1183  //                If B = 1, nsecs encoded in EE+1 bytes (similar to secs/DDD above)
  1184  //
  1185  //   Following the descriptor bytes, subsequent bytes are:
  1186  //
  1187  //       secs component encoded in `DDD + 1` bytes (if A == 1)
  1188  //       nsecs component encoded in `EE + 1` bytes (if B == 1)
  1189  //       tz component encoded in 2 bytes (if C == 1)
  1190  //
  1191  //   secs and nsecs components are integers encoded in a BigEndian
  1192  //   2-complement encoding format.
  1193  //
  1194  //   tz component is encoded as 2 bytes (16 bits). Most significant bit 15 to
  1195  //   Least significant bit 0 are described below:
  1196  //
  1197  //       Timezone offset has a range of -12:00 to +14:00 (ie -720 to +840 minutes).
  1198  //       Bit 15 = have\_dst: set to 1 if we set the dst flag.
  1199  //       Bit 14 = dst\_on: set to 1 if dst is in effect at the time, or 0 if not.
  1200  //       Bits 13..0 = timezone offset in minutes. It is a signed integer in Big Endian format.
  1201  //
  1202  func bincEncodeTime(t time.Time) []byte {
  1203  	// t := rv2i(rv).(time.Time)
  1204  	tsecs, tnsecs := t.Unix(), t.Nanosecond()
  1205  	var (
  1206  		bd byte
  1207  		bs [16]byte
  1208  		i  int = 1
  1209  	)
  1210  	l := t.Location()
  1211  	if l == time.UTC {
  1212  		l = nil
  1213  	}
  1214  	if tsecs != 0 {
  1215  		bd = bd | 0x80
  1216  		btmp := bigen.PutUint64(uint64(tsecs))
  1217  		f := pruneSignExt(btmp[:], tsecs >= 0)
  1218  		bd = bd | (byte(7-f) << 2)
  1219  		copy(bs[i:], btmp[f:])
  1220  		i = i + (8 - f)
  1221  	}
  1222  	if tnsecs != 0 {
  1223  		bd = bd | 0x40
  1224  		btmp := bigen.PutUint32(uint32(tnsecs))
  1225  		f := pruneSignExt(btmp[:4], true)
  1226  		bd = bd | byte(3-f)
  1227  		copy(bs[i:], btmp[f:4])
  1228  		i = i + (4 - f)
  1229  	}
  1230  	if l != nil {
  1231  		bd = bd | 0x20
  1232  		// Note that Go Libs do not give access to dst flag.
  1233  		_, zoneOffset := t.Zone()
  1234  		// zoneName, zoneOffset := t.Zone()
  1235  		zoneOffset /= 60
  1236  		z := uint16(zoneOffset)
  1237  		btmp := bigen.PutUint16(z)
  1238  		// clear dst flags
  1239  		bs[i] = btmp[0] & 0x3f
  1240  		bs[i+1] = btmp[1]
  1241  		i = i + 2
  1242  	}
  1243  	bs[0] = bd
  1244  	return bs[0:i]
  1245  }
  1246  
  1247  // bincDecodeTime decodes a []byte into a time.Time.
  1248  func bincDecodeTime(bs []byte) (tt time.Time, err error) {
  1249  	bd := bs[0]
  1250  	var (
  1251  		tsec  int64
  1252  		tnsec uint32
  1253  		tz    uint16
  1254  		i     byte = 1
  1255  		i2    byte
  1256  		n     byte
  1257  	)
  1258  	if bd&(1<<7) != 0 {
  1259  		var btmp [8]byte
  1260  		n = ((bd >> 2) & 0x7) + 1
  1261  		i2 = i + n
  1262  		copy(btmp[8-n:], bs[i:i2])
  1263  		// if first bit of bs[i] is set, then fill btmp[0..8-n] with 0xff (ie sign extend it)
  1264  		if bs[i]&(1<<7) != 0 {
  1265  			copy(btmp[0:8-n], bsAll0xff)
  1266  		}
  1267  		i = i2
  1268  		tsec = int64(bigen.Uint64(btmp))
  1269  	}
  1270  	if bd&(1<<6) != 0 {
  1271  		var btmp [4]byte
  1272  		n = (bd & 0x3) + 1
  1273  		i2 = i + n
  1274  		copy(btmp[4-n:], bs[i:i2])
  1275  		i = i2
  1276  		tnsec = bigen.Uint32(btmp)
  1277  	}
  1278  	if bd&(1<<5) == 0 {
  1279  		tt = time.Unix(tsec, int64(tnsec)).UTC()
  1280  		return
  1281  	}
  1282  	// In stdlib time.Parse, when a date is parsed without a zone name, it uses "" as zone name.
  1283  	// However, we need name here, so it can be shown when time is printf.d.
  1284  	// Zone name is in form: UTC-08:00.
  1285  	// Note that Go Libs do not give access to dst flag, so we ignore dst bits
  1286  
  1287  	tz = bigen.Uint16([2]byte{bs[i], bs[i+1]})
  1288  	// sign extend sign bit into top 2 MSB (which were dst bits):
  1289  	if tz&(1<<13) == 0 { // positive
  1290  		tz = tz & 0x3fff //clear 2 MSBs: dst bits
  1291  	} else { // negative
  1292  		tz = tz | 0xc000 //set 2 MSBs: dst bits
  1293  	}
  1294  	tzint := int16(tz)
  1295  	if tzint == 0 {
  1296  		tt = time.Unix(tsec, int64(tnsec)).UTC()
  1297  	} else {
  1298  		// For Go Time, do not use a descriptive timezone.
  1299  		// It's unnecessary, and makes it harder to do a reflect.DeepEqual.
  1300  		// The Offset already tells what the offset should be, if not on UTC and unknown zone name.
  1301  		// var zoneName = timeLocUTCName(tzint)
  1302  		tt = time.Unix(tsec, int64(tnsec)).In(time.FixedZone("", int(tzint)*60))
  1303  	}
  1304  	return
  1305  }
  1306  
  1307  var _ decDriver = (*bincDecDriver)(nil)
  1308  var _ encDriver = (*bincEncDriver)(nil)