Upgrade dependencies
This commit is contained in:
parent
d6d795e286
commit
83e09acc9f
177 changed files with 59841 additions and 39358 deletions
472
vendor/github.com/ugorji/go/codec/binc.go
generated
vendored
472
vendor/github.com/ugorji/go/codec/binc.go
generated
vendored
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
||||
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||
|
||||
package codec
|
||||
|
@ -55,39 +55,77 @@ const (
|
|||
// others not currently supported
|
||||
)
|
||||
|
||||
func bincdesc(vd, vs byte) string {
|
||||
switch vd {
|
||||
case bincVdSpecial:
|
||||
switch vs {
|
||||
case bincSpNil:
|
||||
return "nil"
|
||||
case bincSpFalse:
|
||||
return "false"
|
||||
case bincSpTrue:
|
||||
return "true"
|
||||
case bincSpNan, bincSpPosInf, bincSpNegInf, bincSpZeroFloat:
|
||||
return "float"
|
||||
case bincSpZero:
|
||||
return "uint"
|
||||
case bincSpNegOne:
|
||||
return "int"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
case bincVdSmallInt, bincVdPosInt:
|
||||
return "uint"
|
||||
case bincVdNegInt:
|
||||
return "int"
|
||||
case bincVdFloat:
|
||||
return "float"
|
||||
case bincVdSymbol:
|
||||
return "string"
|
||||
case bincVdString:
|
||||
return "string"
|
||||
case bincVdByteArray:
|
||||
return "bytes"
|
||||
case bincVdTimestamp:
|
||||
return "time"
|
||||
case bincVdCustomExt:
|
||||
return "ext"
|
||||
case bincVdArray:
|
||||
return "array"
|
||||
case bincVdMap:
|
||||
return "map"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
type bincEncDriver struct {
|
||||
e *Encoder
|
||||
h *BincHandle
|
||||
w encWriter
|
||||
m map[string]uint16 // symbols
|
||||
b [scratchByteArrayLen]byte
|
||||
s uint16 // symbols sequencer
|
||||
encNoSeparator
|
||||
}
|
||||
|
||||
func (e *bincEncDriver) IsBuiltinType(rt uintptr) bool {
|
||||
return rt == timeTypId
|
||||
}
|
||||
|
||||
func (e *bincEncDriver) EncodeBuiltin(rt uintptr, v interface{}) {
|
||||
if rt == timeTypId {
|
||||
var bs []byte
|
||||
switch x := v.(type) {
|
||||
case time.Time:
|
||||
bs = encodeTime(x)
|
||||
case *time.Time:
|
||||
bs = encodeTime(*x)
|
||||
default:
|
||||
e.e.errorf("binc error encoding builtin: expect time.Time, received %T", v)
|
||||
}
|
||||
e.w.writen1(bincVdTimestamp<<4 | uint8(len(bs)))
|
||||
e.w.writeb(bs)
|
||||
}
|
||||
b [16]byte // scratch, used for encoding numbers - bigendian style
|
||||
s uint16 // symbols sequencer
|
||||
// c containerState
|
||||
encDriverTrackContainerWriter
|
||||
noBuiltInTypes
|
||||
// encNoSeparator
|
||||
}
|
||||
|
||||
func (e *bincEncDriver) EncodeNil() {
|
||||
e.w.writen1(bincVdSpecial<<4 | bincSpNil)
|
||||
}
|
||||
|
||||
func (e *bincEncDriver) EncodeTime(t time.Time) {
|
||||
if t.IsZero() {
|
||||
e.EncodeNil()
|
||||
} else {
|
||||
bs := bincEncodeTime(t)
|
||||
e.w.writen1(bincVdTimestamp<<4 | uint8(len(bs)))
|
||||
e.w.writeb(bs)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *bincEncDriver) EncodeBool(b bool) {
|
||||
if b {
|
||||
e.w.writen1(bincVdSpecial<<4 | bincSpTrue)
|
||||
|
@ -195,15 +233,21 @@ func (e *bincEncDriver) encodeExtPreamble(xtag byte, length int) {
|
|||
e.w.writen1(xtag)
|
||||
}
|
||||
|
||||
func (e *bincEncDriver) EncodeArrayStart(length int) {
|
||||
func (e *bincEncDriver) WriteArrayStart(length int) {
|
||||
e.encLen(bincVdArray<<4, uint64(length))
|
||||
e.c = containerArrayStart
|
||||
}
|
||||
|
||||
func (e *bincEncDriver) EncodeMapStart(length int) {
|
||||
func (e *bincEncDriver) WriteMapStart(length int) {
|
||||
e.encLen(bincVdMap<<4, uint64(length))
|
||||
e.c = containerMapStart
|
||||
}
|
||||
|
||||
func (e *bincEncDriver) EncodeString(c charEncoding, v string) {
|
||||
if e.c == containerMapKey && c == cUTF8 && (e.h.AsSymbols == 0 || e.h.AsSymbols == 1) {
|
||||
e.EncodeSymbol(v)
|
||||
return
|
||||
}
|
||||
l := uint64(len(v))
|
||||
e.encBytesLen(c, l)
|
||||
if l > 0 {
|
||||
|
@ -213,7 +257,7 @@ func (e *bincEncDriver) EncodeString(c charEncoding, v string) {
|
|||
|
||||
func (e *bincEncDriver) EncodeSymbol(v string) {
|
||||
// if WriteSymbolsNoRefs {
|
||||
// e.encodeString(c_UTF8, v)
|
||||
// e.encodeString(cUTF8, v)
|
||||
// return
|
||||
// }
|
||||
|
||||
|
@ -223,10 +267,10 @@ func (e *bincEncDriver) EncodeSymbol(v string) {
|
|||
|
||||
l := len(v)
|
||||
if l == 0 {
|
||||
e.encBytesLen(c_UTF8, 0)
|
||||
e.encBytesLen(cUTF8, 0)
|
||||
return
|
||||
} else if l == 1 {
|
||||
e.encBytesLen(c_UTF8, 1)
|
||||
e.encBytesLen(cUTF8, 1)
|
||||
e.w.writen1(v[0])
|
||||
return
|
||||
}
|
||||
|
@ -276,6 +320,10 @@ func (e *bincEncDriver) EncodeSymbol(v string) {
|
|||
}
|
||||
|
||||
func (e *bincEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
|
||||
if v == nil {
|
||||
e.EncodeNil()
|
||||
return
|
||||
}
|
||||
l := uint64(len(v))
|
||||
e.encBytesLen(c, l)
|
||||
if l > 0 {
|
||||
|
@ -285,7 +333,7 @@ func (e *bincEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
|
|||
|
||||
func (e *bincEncDriver) encBytesLen(c charEncoding, length uint64) {
|
||||
//TODO: support bincUnicodeOther (for now, just use string or bytearray)
|
||||
if c == c_RAW {
|
||||
if c == cRAW {
|
||||
e.encLen(bincVdByteArray<<4, length)
|
||||
} else {
|
||||
e.encLen(bincVdString<<4, length)
|
||||
|
@ -324,6 +372,9 @@ type bincDecSymbol struct {
|
|||
}
|
||||
|
||||
type bincDecDriver struct {
|
||||
decDriverNoopContainerReader
|
||||
noBuiltInTypes
|
||||
|
||||
d *Decoder
|
||||
h *BincHandle
|
||||
r decReader
|
||||
|
@ -332,13 +383,15 @@ type bincDecDriver struct {
|
|||
bd byte
|
||||
vd byte
|
||||
vs byte
|
||||
noStreamingCodec
|
||||
decNoSeparator
|
||||
b [scratchByteArrayLen]byte
|
||||
|
||||
_ [3]byte // padding
|
||||
// linear searching on this slice is ok,
|
||||
// because we typically expect < 32 symbols in each stream.
|
||||
s []bincDecSymbol
|
||||
|
||||
// noStreamingCodec
|
||||
// decNoSeparator
|
||||
|
||||
b [8 * 8]byte // scratch
|
||||
}
|
||||
|
||||
func (d *bincDecDriver) readNextBd() {
|
||||
|
@ -348,7 +401,17 @@ func (d *bincDecDriver) readNextBd() {
|
|||
d.bdRead = true
|
||||
}
|
||||
|
||||
func (d *bincDecDriver) uncacheRead() {
|
||||
if d.bdRead {
|
||||
d.r.unreadn1()
|
||||
d.bdRead = false
|
||||
}
|
||||
}
|
||||
|
||||
func (d *bincDecDriver) ContainerType() (vt valueType) {
|
||||
if !d.bdRead {
|
||||
d.readNextBd()
|
||||
}
|
||||
if d.vd == bincVdSpecial && d.vs == bincSpNil {
|
||||
return valueTypeNil
|
||||
} else if d.vd == bincVdByteArray {
|
||||
|
@ -359,9 +422,10 @@ func (d *bincDecDriver) ContainerType() (vt valueType) {
|
|||
return valueTypeArray
|
||||
} else if d.vd == bincVdMap {
|
||||
return valueTypeMap
|
||||
} else {
|
||||
// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
|
||||
}
|
||||
// else {
|
||||
// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
|
||||
// }
|
||||
return valueTypeUnset
|
||||
}
|
||||
|
||||
|
@ -376,27 +440,24 @@ func (d *bincDecDriver) TryDecodeAsNil() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (d *bincDecDriver) IsBuiltinType(rt uintptr) bool {
|
||||
return rt == timeTypId
|
||||
}
|
||||
|
||||
func (d *bincDecDriver) DecodeBuiltin(rt uintptr, v interface{}) {
|
||||
func (d *bincDecDriver) DecodeTime() (t time.Time) {
|
||||
if !d.bdRead {
|
||||
d.readNextBd()
|
||||
}
|
||||
if rt == timeTypId {
|
||||
if d.vd != bincVdTimestamp {
|
||||
d.d.errorf("Invalid d.vd. Expecting 0x%x. Received: 0x%x", bincVdTimestamp, d.vd)
|
||||
return
|
||||
}
|
||||
tt, err := decodeTime(d.r.readx(int(d.vs)))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
var vt *time.Time = v.(*time.Time)
|
||||
*vt = tt
|
||||
if d.bd == bincVdSpecial<<4|bincSpNil {
|
||||
d.bdRead = false
|
||||
return
|
||||
}
|
||||
if d.vd != bincVdTimestamp {
|
||||
d.d.errorf("cannot decode time - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
|
||||
return
|
||||
}
|
||||
t, err := bincDecodeTime(d.r.readx(int(d.vs)))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
d.bdRead = false
|
||||
return
|
||||
}
|
||||
|
||||
func (d *bincDecDriver) decFloatPre(vs, defaultLen byte) {
|
||||
|
@ -405,7 +466,7 @@ func (d *bincDecDriver) decFloatPre(vs, defaultLen byte) {
|
|||
} else {
|
||||
l := d.r.readn1()
|
||||
if l > 8 {
|
||||
d.d.errorf("At most 8 bytes used to represent float. Received: %v bytes", l)
|
||||
d.d.errorf("cannot read float - at most 8 bytes used to represent float - received %v bytes", l)
|
||||
return
|
||||
}
|
||||
for i := l; i < 8; i++ {
|
||||
|
@ -424,7 +485,7 @@ func (d *bincDecDriver) decFloat() (f float64) {
|
|||
d.decFloatPre(d.vs, 8)
|
||||
f = math.Float64frombits(bigen.Uint64(d.b[0:8]))
|
||||
} else {
|
||||
d.d.errorf("only float32 and float64 are supported. d.vd: 0x%x, d.vs: 0x%x", d.vd, d.vs)
|
||||
d.d.errorf("read float - only float32 and float64 are supported - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
|
||||
return
|
||||
}
|
||||
return
|
||||
|
@ -481,49 +542,38 @@ func (d *bincDecDriver) decCheckInteger() (ui uint64, neg bool) {
|
|||
neg = true
|
||||
ui = 1
|
||||
} else {
|
||||
d.d.errorf("numeric decode fails for special value: d.vs: 0x%x", d.vs)
|
||||
d.d.errorf("integer decode fails - invalid special value from descriptor %x-%x/%s",
|
||||
d.vd, d.vs, bincdesc(d.vd, d.vs))
|
||||
return
|
||||
}
|
||||
} else {
|
||||
d.d.errorf("number can only be decoded from uint or int values. d.bd: 0x%x, d.vd: 0x%x", d.bd, d.vd)
|
||||
d.d.errorf("integer can only be decoded from int/uint. d.bd: 0x%x, d.vd: 0x%x", d.bd, d.vd)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (d *bincDecDriver) DecodeInt(bitsize uint8) (i int64) {
|
||||
func (d *bincDecDriver) DecodeInt64() (i int64) {
|
||||
ui, neg := d.decCheckInteger()
|
||||
i, overflow := chkOvf.SignedInt(ui)
|
||||
if overflow {
|
||||
d.d.errorf("simple: overflow converting %v to signed integer", ui)
|
||||
return
|
||||
}
|
||||
i = chkOvf.SignedIntV(ui)
|
||||
if neg {
|
||||
i = -i
|
||||
}
|
||||
if chkOvf.Int(i, bitsize) {
|
||||
d.d.errorf("binc: overflow integer: %v", i)
|
||||
return
|
||||
}
|
||||
d.bdRead = false
|
||||
return
|
||||
}
|
||||
|
||||
func (d *bincDecDriver) DecodeUint(bitsize uint8) (ui uint64) {
|
||||
func (d *bincDecDriver) DecodeUint64() (ui uint64) {
|
||||
ui, neg := d.decCheckInteger()
|
||||
if neg {
|
||||
d.d.errorf("Assigning negative signed value to unsigned type")
|
||||
return
|
||||
}
|
||||
if chkOvf.Uint(ui, bitsize) {
|
||||
d.d.errorf("binc: overflow integer: %v", ui)
|
||||
d.d.errorf("assigning negative signed value to unsigned integer type")
|
||||
return
|
||||
}
|
||||
d.bdRead = false
|
||||
return
|
||||
}
|
||||
|
||||
func (d *bincDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) {
|
||||
func (d *bincDecDriver) DecodeFloat64() (f float64) {
|
||||
if !d.bdRead {
|
||||
d.readNextBd()
|
||||
}
|
||||
|
@ -539,17 +589,14 @@ func (d *bincDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) {
|
|||
} else if vs == bincSpNegInf {
|
||||
return math.Inf(-1)
|
||||
} else {
|
||||
d.d.errorf("Invalid d.vs decoding float where d.vd=bincVdSpecial: %v", d.vs)
|
||||
d.d.errorf("float - invalid special value from descriptor %x-%x/%s",
|
||||
d.vd, d.vs, bincdesc(d.vd, d.vs))
|
||||
return
|
||||
}
|
||||
} else if vd == bincVdFloat {
|
||||
f = d.decFloat()
|
||||
} else {
|
||||
f = float64(d.DecodeInt(64))
|
||||
}
|
||||
if chkOverflow32 && chkOvf.Float32(f) {
|
||||
d.d.errorf("binc: float32 overflow: %v", f)
|
||||
return
|
||||
f = float64(d.DecodeInt64())
|
||||
}
|
||||
d.bdRead = false
|
||||
return
|
||||
|
@ -565,7 +612,7 @@ func (d *bincDecDriver) DecodeBool() (b bool) {
|
|||
} else if bd == (bincVdSpecial | bincSpTrue) {
|
||||
b = true
|
||||
} else {
|
||||
d.d.errorf("Invalid single-byte value for bool: %s: %x", msgBadDesc, d.bd)
|
||||
d.d.errorf("bool - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
|
||||
return
|
||||
}
|
||||
d.bdRead = false
|
||||
|
@ -573,8 +620,11 @@ func (d *bincDecDriver) DecodeBool() (b bool) {
|
|||
}
|
||||
|
||||
func (d *bincDecDriver) ReadMapStart() (length int) {
|
||||
if !d.bdRead {
|
||||
d.readNextBd()
|
||||
}
|
||||
if d.vd != bincVdMap {
|
||||
d.d.errorf("Invalid d.vd for map. Expecting 0x%x. Got: 0x%x", bincVdMap, d.vd)
|
||||
d.d.errorf("map - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
|
||||
return
|
||||
}
|
||||
length = d.decLen()
|
||||
|
@ -583,8 +633,11 @@ func (d *bincDecDriver) ReadMapStart() (length int) {
|
|||
}
|
||||
|
||||
func (d *bincDecDriver) ReadArrayStart() (length int) {
|
||||
if !d.bdRead {
|
||||
d.readNextBd()
|
||||
}
|
||||
if d.vd != bincVdArray {
|
||||
d.d.errorf("Invalid d.vd for array. Expecting 0x%x. Got: 0x%x", bincVdArray, d.vd)
|
||||
d.d.errorf("array - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
|
||||
return
|
||||
}
|
||||
length = d.decLen()
|
||||
|
@ -615,7 +668,8 @@ func (d *bincDecDriver) decLenNumber() (v uint64) {
|
|||
return
|
||||
}
|
||||
|
||||
func (d *bincDecDriver) decStringAndBytes(bs []byte, withString, zerocopy bool) (bs2 []byte, s string) {
|
||||
func (d *bincDecDriver) decStringAndBytes(bs []byte, withString, zerocopy bool) (
|
||||
bs2 []byte, s string) {
|
||||
if !d.bdRead {
|
||||
d.readNextBd()
|
||||
}
|
||||
|
@ -623,7 +677,7 @@ func (d *bincDecDriver) decStringAndBytes(bs []byte, withString, zerocopy bool)
|
|||
d.bdRead = false
|
||||
return
|
||||
}
|
||||
var slen int = -1
|
||||
var slen = -1
|
||||
// var ok bool
|
||||
switch d.vd {
|
||||
case bincVdString, bincVdByteArray:
|
||||
|
@ -632,12 +686,12 @@ func (d *bincDecDriver) decStringAndBytes(bs []byte, withString, zerocopy bool)
|
|||
if d.br {
|
||||
bs2 = d.r.readx(slen)
|
||||
} else if len(bs) == 0 {
|
||||
bs2 = decByteSlice(d.r, slen, d.b[:])
|
||||
bs2 = decByteSlice(d.r, slen, d.d.h.MaxInitLen, d.b[:])
|
||||
} else {
|
||||
bs2 = decByteSlice(d.r, slen, bs)
|
||||
bs2 = decByteSlice(d.r, slen, d.d.h.MaxInitLen, bs)
|
||||
}
|
||||
} else {
|
||||
bs2 = decByteSlice(d.r, slen, bs)
|
||||
bs2 = decByteSlice(d.r, slen, d.d.h.MaxInitLen, bs)
|
||||
}
|
||||
if withString {
|
||||
s = string(bs2)
|
||||
|
@ -689,15 +743,14 @@ func (d *bincDecDriver) decStringAndBytes(bs []byte, withString, zerocopy bool)
|
|||
// since using symbols, do not store any part of
|
||||
// the parameter bs in the map, as it might be a shared buffer.
|
||||
// bs2 = decByteSlice(d.r, slen, bs)
|
||||
bs2 = decByteSlice(d.r, slen, nil)
|
||||
bs2 = decByteSlice(d.r, slen, d.d.h.MaxInitLen, nil)
|
||||
if withString {
|
||||
s = string(bs2)
|
||||
}
|
||||
d.s = append(d.s, bincDecSymbol{i: symbol, s: s, b: bs2})
|
||||
}
|
||||
default:
|
||||
d.d.errorf("Invalid d.vd. Expecting string:0x%x, bytearray:0x%x or symbol: 0x%x. Got: 0x%x",
|
||||
bincVdString, bincVdByteArray, bincVdSymbol, d.vd)
|
||||
d.d.errorf("string/bytes - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
|
||||
return
|
||||
}
|
||||
d.bdRead = false
|
||||
|
@ -705,18 +758,19 @@ func (d *bincDecDriver) decStringAndBytes(bs []byte, withString, zerocopy bool)
|
|||
}
|
||||
|
||||
func (d *bincDecDriver) DecodeString() (s string) {
|
||||
// DecodeBytes does not accomodate symbols, whose impl stores string version in map.
|
||||
// DecodeBytes does not accommodate symbols, whose impl stores string version in map.
|
||||
// Use decStringAndBytes directly.
|
||||
// return string(d.DecodeBytes(d.b[:], true, true))
|
||||
_, s = d.decStringAndBytes(d.b[:], true, true)
|
||||
return
|
||||
}
|
||||
|
||||
func (d *bincDecDriver) DecodeBytes(bs []byte, isstring, zerocopy bool) (bsOut []byte) {
|
||||
if isstring {
|
||||
bsOut, _ = d.decStringAndBytes(bs, false, zerocopy)
|
||||
return
|
||||
}
|
||||
func (d *bincDecDriver) DecodeStringAsBytes() (s []byte) {
|
||||
s, _ = d.decStringAndBytes(d.b[:], false, true)
|
||||
return
|
||||
}
|
||||
|
||||
func (d *bincDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
|
||||
if !d.bdRead {
|
||||
d.readNextBd()
|
||||
}
|
||||
|
@ -724,12 +778,16 @@ func (d *bincDecDriver) DecodeBytes(bs []byte, isstring, zerocopy bool) (bsOut [
|
|||
d.bdRead = false
|
||||
return nil
|
||||
}
|
||||
// check if an "array" of uint8's (see ContainerType for how to infer if an array)
|
||||
if d.vd == bincVdArray {
|
||||
bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d)
|
||||
return
|
||||
}
|
||||
var clen int
|
||||
if d.vd == bincVdString || d.vd == bincVdByteArray {
|
||||
clen = d.decLen()
|
||||
} else {
|
||||
d.d.errorf("Invalid d.vd for bytes. Expecting string:0x%x or bytearray:0x%x. Got: 0x%x",
|
||||
bincVdString, bincVdByteArray, d.vd)
|
||||
d.d.errorf("bytes - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
|
||||
return
|
||||
}
|
||||
d.bdRead = false
|
||||
|
@ -740,12 +798,12 @@ func (d *bincDecDriver) DecodeBytes(bs []byte, isstring, zerocopy bool) (bsOut [
|
|||
bs = d.b[:]
|
||||
}
|
||||
}
|
||||
return decByteSlice(d.r, clen, bs)
|
||||
return decByteSlice(d.r, clen, d.d.h.MaxInitLen, bs)
|
||||
}
|
||||
|
||||
func (d *bincDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) {
|
||||
if xtag > 0xff {
|
||||
d.d.errorf("decodeExt: tag must be <= 0xff; got: %v", xtag)
|
||||
d.d.errorf("ext: tag must be <= 0xff; got: %v", xtag)
|
||||
return
|
||||
}
|
||||
realxtag1, xbs := d.decodeExtV(ext != nil, uint8(xtag))
|
||||
|
@ -768,14 +826,14 @@ func (d *bincDecDriver) decodeExtV(verifyTag bool, tag byte) (xtag byte, xbs []b
|
|||
l := d.decLen()
|
||||
xtag = d.r.readn1()
|
||||
if verifyTag && xtag != tag {
|
||||
d.d.errorf("Wrong extension tag. Got %b. Expecting: %v", xtag, tag)
|
||||
d.d.errorf("wrong extension tag - got %b, expecting: %v", xtag, tag)
|
||||
return
|
||||
}
|
||||
xbs = d.r.readx(l)
|
||||
} else if d.vd == bincVdByteArray {
|
||||
xbs = d.DecodeBytes(nil, false, true)
|
||||
xbs = d.DecodeBytes(nil, true)
|
||||
} else {
|
||||
d.d.errorf("Invalid d.vd for extensions (Expecting extensions or byte array). Got: 0x%x", d.vd)
|
||||
d.d.errorf("ext - expecting extensions or byte array - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
|
||||
return
|
||||
}
|
||||
d.bdRead = false
|
||||
|
@ -787,7 +845,7 @@ func (d *bincDecDriver) DecodeNaked() {
|
|||
d.readNextBd()
|
||||
}
|
||||
|
||||
n := &d.d.n
|
||||
n := d.d.n
|
||||
var decodeFurther bool
|
||||
|
||||
switch d.vd {
|
||||
|
@ -820,7 +878,7 @@ func (d *bincDecDriver) DecodeNaked() {
|
|||
n.v = valueTypeInt
|
||||
n.i = int64(-1) // int8(-1)
|
||||
default:
|
||||
d.d.errorf("decodeNaked: Unrecognized special value 0x%x", d.vs)
|
||||
d.d.errorf("cannot infer value - unrecognized special value from descriptor %x-%x/%s", d.vd, d.vs, bincdesc(d.vd, d.vs))
|
||||
}
|
||||
case bincVdSmallInt:
|
||||
n.v = valueTypeUint
|
||||
|
@ -842,10 +900,10 @@ func (d *bincDecDriver) DecodeNaked() {
|
|||
n.s = d.DecodeString()
|
||||
case bincVdByteArray:
|
||||
n.v = valueTypeBytes
|
||||
n.l = d.DecodeBytes(nil, false, false)
|
||||
n.l = d.DecodeBytes(nil, false)
|
||||
case bincVdTimestamp:
|
||||
n.v = valueTypeTimestamp
|
||||
tt, err := decodeTime(d.r.readx(int(d.vs)))
|
||||
n.v = valueTypeTime
|
||||
tt, err := bincDecodeTime(d.r.readx(int(d.vs)))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -862,7 +920,7 @@ func (d *bincDecDriver) DecodeNaked() {
|
|||
n.v = valueTypeMap
|
||||
decodeFurther = true
|
||||
default:
|
||||
d.d.errorf("decodeNaked: Unrecognized d.vd: 0x%x", d.vd)
|
||||
d.d.errorf("cannot infer value - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
|
||||
}
|
||||
|
||||
if !decodeFurther {
|
||||
|
@ -892,31 +950,219 @@ func (d *bincDecDriver) DecodeNaked() {
|
|||
type BincHandle struct {
|
||||
BasicHandle
|
||||
binaryEncodingType
|
||||
noElemSeparators
|
||||
|
||||
// AsSymbols defines what should be encoded as symbols.
|
||||
//
|
||||
// Encoding as symbols can reduce the encoded size significantly.
|
||||
//
|
||||
// However, during decoding, each string to be encoded as a symbol must
|
||||
// be checked to see if it has been seen before. Consequently, encoding time
|
||||
// will increase if using symbols, because string comparisons has a clear cost.
|
||||
//
|
||||
// Values:
|
||||
// - 0: default: library uses best judgement
|
||||
// - 1: use symbols
|
||||
// - 2: do not use symbols
|
||||
AsSymbols uint8
|
||||
|
||||
// AsSymbols: may later on introduce more options ...
|
||||
// - m: map keys
|
||||
// - s: struct fields
|
||||
// - n: none
|
||||
// - a: all: same as m, s, ...
|
||||
|
||||
// _ [1]uint64 // padding
|
||||
}
|
||||
|
||||
// Name returns the name of the handle: binc
|
||||
func (h *BincHandle) Name() string { return "binc" }
|
||||
|
||||
// SetBytesExt sets an extension
|
||||
func (h *BincHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) {
|
||||
return h.SetExt(rt, tag, &setExtWrapper{b: ext})
|
||||
return h.SetExt(rt, tag, &extWrapper{ext, interfaceExtFailer{}})
|
||||
}
|
||||
|
||||
func (h *BincHandle) newEncDriver(e *Encoder) encDriver {
|
||||
return &bincEncDriver{e: e, w: e.w}
|
||||
return &bincEncDriver{e: e, h: h, w: e.w}
|
||||
}
|
||||
|
||||
func (h *BincHandle) newDecDriver(d *Decoder) decDriver {
|
||||
return &bincDecDriver{d: d, r: d.r, h: h, br: d.bytes}
|
||||
return &bincDecDriver{d: d, h: h, r: d.r, br: d.bytes}
|
||||
}
|
||||
|
||||
func (e *bincEncDriver) reset() {
|
||||
e.w = e.e.w
|
||||
e.s = 0
|
||||
e.c = 0
|
||||
e.m = nil
|
||||
}
|
||||
|
||||
func (d *bincDecDriver) reset() {
|
||||
d.r = d.d.r
|
||||
d.r, d.br = d.d.r, d.d.bytes
|
||||
d.s = nil
|
||||
d.bd, d.bdRead, d.vd, d.vs = 0, false, 0, 0
|
||||
}
|
||||
|
||||
// var timeDigits = [...]byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
|
||||
|
||||
// EncodeTime encodes a time.Time as a []byte, including
|
||||
// information on the instant in time and UTC offset.
|
||||
//
|
||||
// Format Description
|
||||
//
|
||||
// A timestamp is composed of 3 components:
|
||||
//
|
||||
// - secs: signed integer representing seconds since unix epoch
|
||||
// - nsces: unsigned integer representing fractional seconds as a
|
||||
// nanosecond offset within secs, in the range 0 <= nsecs < 1e9
|
||||
// - tz: signed integer representing timezone offset in minutes east of UTC,
|
||||
// and a dst (daylight savings time) flag
|
||||
//
|
||||
// When encoding a timestamp, the first byte is the descriptor, which
|
||||
// defines which components are encoded and how many bytes are used to
|
||||
// encode secs and nsecs components. *If secs/nsecs is 0 or tz is UTC, it
|
||||
// is not encoded in the byte array explicitly*.
|
||||
//
|
||||
// Descriptor 8 bits are of the form `A B C DDD EE`:
|
||||
// A: Is secs component encoded? 1 = true
|
||||
// B: Is nsecs component encoded? 1 = true
|
||||
// C: Is tz component encoded? 1 = true
|
||||
// DDD: Number of extra bytes for secs (range 0-7).
|
||||
// If A = 1, secs encoded in DDD+1 bytes.
|
||||
// If A = 0, secs is not encoded, and is assumed to be 0.
|
||||
// If A = 1, then we need at least 1 byte to encode secs.
|
||||
// DDD says the number of extra bytes beyond that 1.
|
||||
// E.g. if DDD=0, then secs is represented in 1 byte.
|
||||
// if DDD=2, then secs is represented in 3 bytes.
|
||||
// EE: Number of extra bytes for nsecs (range 0-3).
|
||||
// If B = 1, nsecs encoded in EE+1 bytes (similar to secs/DDD above)
|
||||
//
|
||||
// Following the descriptor bytes, subsequent bytes are:
|
||||
//
|
||||
// secs component encoded in `DDD + 1` bytes (if A == 1)
|
||||
// nsecs component encoded in `EE + 1` bytes (if B == 1)
|
||||
// tz component encoded in 2 bytes (if C == 1)
|
||||
//
|
||||
// secs and nsecs components are integers encoded in a BigEndian
|
||||
// 2-complement encoding format.
|
||||
//
|
||||
// tz component is encoded as 2 bytes (16 bits). Most significant bit 15 to
|
||||
// Least significant bit 0 are described below:
|
||||
//
|
||||
// Timezone offset has a range of -12:00 to +14:00 (ie -720 to +840 minutes).
|
||||
// Bit 15 = have\_dst: set to 1 if we set the dst flag.
|
||||
// Bit 14 = dst\_on: set to 1 if dst is in effect at the time, or 0 if not.
|
||||
// Bits 13..0 = timezone offset in minutes. It is a signed integer in Big Endian format.
|
||||
//
|
||||
func bincEncodeTime(t time.Time) []byte {
|
||||
//t := rv.Interface().(time.Time)
|
||||
tsecs, tnsecs := t.Unix(), t.Nanosecond()
|
||||
var (
|
||||
bd byte
|
||||
btmp [8]byte
|
||||
bs [16]byte
|
||||
i int = 1
|
||||
)
|
||||
l := t.Location()
|
||||
if l == time.UTC {
|
||||
l = nil
|
||||
}
|
||||
if tsecs != 0 {
|
||||
bd = bd | 0x80
|
||||
bigen.PutUint64(btmp[:], uint64(tsecs))
|
||||
f := pruneSignExt(btmp[:], tsecs >= 0)
|
||||
bd = bd | (byte(7-f) << 2)
|
||||
copy(bs[i:], btmp[f:])
|
||||
i = i + (8 - f)
|
||||
}
|
||||
if tnsecs != 0 {
|
||||
bd = bd | 0x40
|
||||
bigen.PutUint32(btmp[:4], uint32(tnsecs))
|
||||
f := pruneSignExt(btmp[:4], true)
|
||||
bd = bd | byte(3-f)
|
||||
copy(bs[i:], btmp[f:4])
|
||||
i = i + (4 - f)
|
||||
}
|
||||
if l != nil {
|
||||
bd = bd | 0x20
|
||||
// Note that Go Libs do not give access to dst flag.
|
||||
_, zoneOffset := t.Zone()
|
||||
//zoneName, zoneOffset := t.Zone()
|
||||
zoneOffset /= 60
|
||||
z := uint16(zoneOffset)
|
||||
bigen.PutUint16(btmp[:2], z)
|
||||
// clear dst flags
|
||||
bs[i] = btmp[0] & 0x3f
|
||||
bs[i+1] = btmp[1]
|
||||
i = i + 2
|
||||
}
|
||||
bs[0] = bd
|
||||
return bs[0:i]
|
||||
}
|
||||
|
||||
// bincDecodeTime decodes a []byte into a time.Time.
|
||||
func bincDecodeTime(bs []byte) (tt time.Time, err error) {
|
||||
bd := bs[0]
|
||||
var (
|
||||
tsec int64
|
||||
tnsec uint32
|
||||
tz uint16
|
||||
i byte = 1
|
||||
i2 byte
|
||||
n byte
|
||||
)
|
||||
if bd&(1<<7) != 0 {
|
||||
var btmp [8]byte
|
||||
n = ((bd >> 2) & 0x7) + 1
|
||||
i2 = i + n
|
||||
copy(btmp[8-n:], bs[i:i2])
|
||||
//if first bit of bs[i] is set, then fill btmp[0..8-n] with 0xff (ie sign extend it)
|
||||
if bs[i]&(1<<7) != 0 {
|
||||
copy(btmp[0:8-n], bsAll0xff)
|
||||
//for j,k := byte(0), 8-n; j < k; j++ { btmp[j] = 0xff }
|
||||
}
|
||||
i = i2
|
||||
tsec = int64(bigen.Uint64(btmp[:]))
|
||||
}
|
||||
if bd&(1<<6) != 0 {
|
||||
var btmp [4]byte
|
||||
n = (bd & 0x3) + 1
|
||||
i2 = i + n
|
||||
copy(btmp[4-n:], bs[i:i2])
|
||||
i = i2
|
||||
tnsec = bigen.Uint32(btmp[:])
|
||||
}
|
||||
if bd&(1<<5) == 0 {
|
||||
tt = time.Unix(tsec, int64(tnsec)).UTC()
|
||||
return
|
||||
}
|
||||
// In stdlib time.Parse, when a date is parsed without a zone name, it uses "" as zone name.
|
||||
// However, we need name here, so it can be shown when time is printed.
|
||||
// Zone name is in form: UTC-08:00.
|
||||
// Note that Go Libs do not give access to dst flag, so we ignore dst bits
|
||||
|
||||
i2 = i + 2
|
||||
tz = bigen.Uint16(bs[i:i2])
|
||||
// i = i2
|
||||
// sign extend sign bit into top 2 MSB (which were dst bits):
|
||||
if tz&(1<<13) == 0 { // positive
|
||||
tz = tz & 0x3fff //clear 2 MSBs: dst bits
|
||||
} else { // negative
|
||||
tz = tz | 0xc000 //set 2 MSBs: dst bits
|
||||
}
|
||||
tzint := int16(tz)
|
||||
if tzint == 0 {
|
||||
tt = time.Unix(tsec, int64(tnsec)).UTC()
|
||||
} else {
|
||||
// For Go Time, do not use a descriptive timezone.
|
||||
// It's unnecessary, and makes it harder to do a reflect.DeepEqual.
|
||||
// The Offset already tells what the offset should be, if not on UTC and unknown zone name.
|
||||
// var zoneName = timeLocUTCName(tzint)
|
||||
tt = time.Unix(tsec, int64(tnsec)).In(time.FixedZone("", int(tzint)*60))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var _ decDriver = (*bincDecDriver)(nil)
|
||||
var _ encDriver = (*bincEncDriver)(nil)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue