From 8b0ea560279a5bf4479555d3924c763ddeecfcad Mon Sep 17 00:00:00 2001 From: kim Date: Mon, 30 Jun 2025 15:19:09 +0200 Subject: [chore] update go dependencies (#4304) - github.com/KimMachineGun/automemlimit v0.7.2 => v0.7.3 - github.com/gin-contrib/cors v1.7.5 => v1.7.6 - github.com/minio/minio-go/v7 v7.0.92 => v7.0.94 - github.com/spf13/cast v1.8.0 => v1.9.2 - github.com/uptrace/bun{,/*} v1.2.11 => v1.2.14 - golang.org/x/image v0.27.0 => v0.28.0 - golang.org/x/net v0.40.0 => v0.41.0 - code.superseriousbusiness.org/go-swagger v0.31.0-gts-go1.23-fix => v0.32.3-gts-go1.23-fix Reviewed-on: https://codeberg.org/superseriousbusiness/gotosocial/pulls/4304 Co-authored-by: kim Co-committed-by: kim --- vendor/github.com/ugorji/go/codec/msgpack.go | 946 +++++++++++---------------- 1 file changed, 364 insertions(+), 582 deletions(-) (limited to 'vendor/github.com/ugorji/go/codec/msgpack.go') diff --git a/vendor/github.com/ugorji/go/codec/msgpack.go b/vendor/github.com/ugorji/go/codec/msgpack.go index c0861df5e..ed8ca99a6 100644 --- a/vendor/github.com/ugorji/go/codec/msgpack.go +++ b/vendor/github.com/ugorji/go/codec/msgpack.go @@ -1,3 +1,5 @@ +//go:build notmono || codec.notmono + // Copyright (c) 2012-2020 Ugorji Nwoke. All rights reserved. // Use of this source code is governed by a MIT license found in the LICENSE file. @@ -18,247 +20,106 @@ For compatibility with behaviour of msgpack-c reference implementation: package codec import ( - "fmt" "io" "math" - "net/rpc" "reflect" "time" "unicode/utf8" ) -const ( - mpPosFixNumMin byte = 0x00 - mpPosFixNumMax byte = 0x7f - mpFixMapMin byte = 0x80 - mpFixMapMax byte = 0x8f - mpFixArrayMin byte = 0x90 - mpFixArrayMax byte = 0x9f - mpFixStrMin byte = 0xa0 - mpFixStrMax byte = 0xbf - mpNil byte = 0xc0 - _ byte = 0xc1 - mpFalse byte = 0xc2 - mpTrue byte = 0xc3 - mpFloat byte = 0xca - mpDouble byte = 0xcb - mpUint8 byte = 0xcc - mpUint16 byte = 0xcd - mpUint32 byte = 0xce - mpUint64 byte = 0xcf - mpInt8 byte = 0xd0 - mpInt16 byte = 0xd1 - mpInt32 byte = 0xd2 - mpInt64 byte = 0xd3 - - // extensions below - mpBin8 byte = 0xc4 - mpBin16 byte = 0xc5 - mpBin32 byte = 0xc6 - mpExt8 byte = 0xc7 - mpExt16 byte = 0xc8 - mpExt32 byte = 0xc9 - mpFixExt1 byte = 0xd4 - mpFixExt2 byte = 0xd5 - mpFixExt4 byte = 0xd6 - mpFixExt8 byte = 0xd7 - mpFixExt16 byte = 0xd8 - - mpStr8 byte = 0xd9 // new - mpStr16 byte = 0xda - mpStr32 byte = 0xdb - - mpArray16 byte = 0xdc - mpArray32 byte = 0xdd - - mpMap16 byte = 0xde - mpMap32 byte = 0xdf - - mpNegFixNumMin byte = 0xe0 - mpNegFixNumMax byte = 0xff -) - -var mpTimeExtTag int8 = -1 -var mpTimeExtTagU = uint8(mpTimeExtTag) - -var mpdescNames = map[byte]string{ - mpNil: "nil", - mpFalse: "false", - mpTrue: "true", - mpFloat: "float", - mpDouble: "float", - mpUint8: "uuint", - mpUint16: "uint", - mpUint32: "uint", - mpUint64: "uint", - mpInt8: "int", - mpInt16: "int", - mpInt32: "int", - mpInt64: "int", - - mpStr8: "string|bytes", - mpStr16: "string|bytes", - mpStr32: "string|bytes", - - mpBin8: "bytes", - mpBin16: "bytes", - mpBin32: "bytes", - - mpArray16: "array", - mpArray32: "array", - - mpMap16: "map", - mpMap32: "map", -} - -func mpdesc(bd byte) (s string) { - s = mpdescNames[bd] - if s == "" { - switch { - case bd >= mpPosFixNumMin && bd <= mpPosFixNumMax, - bd >= mpNegFixNumMin && bd <= mpNegFixNumMax: - s = "int" - case bd >= mpFixStrMin && bd <= mpFixStrMax: - s = "string|bytes" - case bd >= mpFixArrayMin && bd <= mpFixArrayMax: - s = "array" - case bd >= mpFixMapMin && bd <= mpFixMapMax: - s = "map" - case bd >= mpFixExt1 && bd <= mpFixExt16, - bd >= mpExt8 && bd <= mpExt32: - s = "ext" - default: - s = "unknown" - } - } - return -} - -// MsgpackSpecRpcMultiArgs is a special type which signifies to the MsgpackSpecRpcCodec -// that the backend RPC service takes multiple arguments, which have been arranged -// in sequence in the slice. -// -// The Codec then passes it AS-IS to the rpc service (without wrapping it in an -// array of 1 element). -type MsgpackSpecRpcMultiArgs []interface{} - -// A MsgpackContainer type specifies the different types of msgpackContainers. -type msgpackContainerType struct { - fixCutoff, bFixMin, b8, b16, b32 byte - // hasFixMin, has8, has8Always bool -} - -var ( - msgpackContainerRawLegacy = msgpackContainerType{ - 32, mpFixStrMin, 0, mpStr16, mpStr32, - } - msgpackContainerStr = msgpackContainerType{ - 32, mpFixStrMin, mpStr8, mpStr16, mpStr32, // true, true, false, - } - msgpackContainerBin = msgpackContainerType{ - 0, 0, mpBin8, mpBin16, mpBin32, // false, true, true, - } - msgpackContainerList = msgpackContainerType{ - 16, mpFixArrayMin, 0, mpArray16, mpArray32, // true, false, false, - } - msgpackContainerMap = msgpackContainerType{ - 16, mpFixMapMin, 0, mpMap16, mpMap32, // true, false, false, - } -) - //--------------------------------------------- -type msgpackEncDriver struct { +type msgpackEncDriver[T encWriter] struct { noBuiltInTypes encDriverNoopContainerWriter encDriverNoState + encDriverContainerNoTrackerT + encInit2er + h *MsgpackHandle + e *encoderBase + w T // x [8]byte - e Encoder } -func (e *msgpackEncDriver) encoder() *Encoder { - return &e.e +func (e *msgpackEncDriver[T]) EncodeNil() { + e.w.writen1(mpNil) } -func (e *msgpackEncDriver) EncodeNil() { - e.e.encWr.writen1(mpNil) -} - -func (e *msgpackEncDriver) EncodeInt(i int64) { +func (e *msgpackEncDriver[T]) EncodeInt(i int64) { if e.h.PositiveIntUnsigned && i >= 0 { e.EncodeUint(uint64(i)) } else if i > math.MaxInt8 { if i <= math.MaxInt16 { - e.e.encWr.writen1(mpInt16) - bigen.writeUint16(e.e.w(), uint16(i)) + e.w.writen1(mpInt16) + e.w.writen2(bigen.PutUint16(uint16(i))) } else if i <= math.MaxInt32 { - e.e.encWr.writen1(mpInt32) - bigen.writeUint32(e.e.w(), uint32(i)) + e.w.writen1(mpInt32) + e.w.writen4(bigen.PutUint32(uint32(i))) } else { - e.e.encWr.writen1(mpInt64) - bigen.writeUint64(e.e.w(), uint64(i)) + e.w.writen1(mpInt64) + e.w.writen8(bigen.PutUint64(uint64(i))) } } else if i >= -32 { if e.h.NoFixedNum { - e.e.encWr.writen2(mpInt8, byte(i)) + e.w.writen2(mpInt8, byte(i)) } else { - e.e.encWr.writen1(byte(i)) + e.w.writen1(byte(i)) } } else if i >= math.MinInt8 { - e.e.encWr.writen2(mpInt8, byte(i)) + e.w.writen2(mpInt8, byte(i)) } else if i >= math.MinInt16 { - e.e.encWr.writen1(mpInt16) - bigen.writeUint16(e.e.w(), uint16(i)) + e.w.writen1(mpInt16) + e.w.writen2(bigen.PutUint16(uint16(i))) } else if i >= math.MinInt32 { - e.e.encWr.writen1(mpInt32) - bigen.writeUint32(e.e.w(), uint32(i)) + e.w.writen1(mpInt32) + e.w.writen4(bigen.PutUint32(uint32(i))) } else { - e.e.encWr.writen1(mpInt64) - bigen.writeUint64(e.e.w(), uint64(i)) + e.w.writen1(mpInt64) + e.w.writen8(bigen.PutUint64(uint64(i))) } } -func (e *msgpackEncDriver) EncodeUint(i uint64) { +func (e *msgpackEncDriver[T]) EncodeUint(i uint64) { if i <= math.MaxInt8 { if e.h.NoFixedNum { - e.e.encWr.writen2(mpUint8, byte(i)) + e.w.writen2(mpUint8, byte(i)) } else { - e.e.encWr.writen1(byte(i)) + e.w.writen1(byte(i)) } } else if i <= math.MaxUint8 { - e.e.encWr.writen2(mpUint8, byte(i)) + e.w.writen2(mpUint8, byte(i)) } else if i <= math.MaxUint16 { - e.e.encWr.writen1(mpUint16) - bigen.writeUint16(e.e.w(), uint16(i)) + e.w.writen1(mpUint16) + e.w.writen2(bigen.PutUint16(uint16(i))) } else if i <= math.MaxUint32 { - e.e.encWr.writen1(mpUint32) - bigen.writeUint32(e.e.w(), uint32(i)) + e.w.writen1(mpUint32) + e.w.writen4(bigen.PutUint32(uint32(i))) } else { - e.e.encWr.writen1(mpUint64) - bigen.writeUint64(e.e.w(), uint64(i)) + e.w.writen1(mpUint64) + e.w.writen8(bigen.PutUint64(uint64(i))) } } -func (e *msgpackEncDriver) EncodeBool(b bool) { +func (e *msgpackEncDriver[T]) EncodeBool(b bool) { if b { - e.e.encWr.writen1(mpTrue) + e.w.writen1(mpTrue) } else { - e.e.encWr.writen1(mpFalse) + e.w.writen1(mpFalse) } } -func (e *msgpackEncDriver) EncodeFloat32(f float32) { - e.e.encWr.writen1(mpFloat) - bigen.writeUint32(e.e.w(), math.Float32bits(f)) +func (e *msgpackEncDriver[T]) EncodeFloat32(f float32) { + e.w.writen1(mpFloat) + e.w.writen4(bigen.PutUint32(math.Float32bits(f))) } -func (e *msgpackEncDriver) EncodeFloat64(f float64) { - e.e.encWr.writen1(mpDouble) - bigen.writeUint64(e.e.w(), math.Float64bits(f)) +func (e *msgpackEncDriver[T]) EncodeFloat64(f float64) { + e.w.writen1(mpDouble) + e.w.writen8(bigen.PutUint64(math.Float64bits(f))) } -func (e *msgpackEncDriver) EncodeTime(t time.Time) { +func (e *msgpackEncDriver[T]) EncodeTime(t time.Time) { if t.IsZero() { e.EncodeNil() return @@ -282,33 +143,33 @@ func (e *msgpackEncDriver) EncodeTime(t time.Time) { } switch l { case 4: - bigen.writeUint32(e.e.w(), uint32(data64)) + e.w.writen4(bigen.PutUint32(uint32(data64))) case 8: - bigen.writeUint64(e.e.w(), data64) + e.w.writen8(bigen.PutUint64(data64)) case 12: - bigen.writeUint32(e.e.w(), uint32(nsec)) - bigen.writeUint64(e.e.w(), uint64(sec)) + e.w.writen4(bigen.PutUint32(uint32(nsec))) + e.w.writen8(bigen.PutUint64(uint64(sec))) } } -func (e *msgpackEncDriver) EncodeExt(v interface{}, basetype reflect.Type, xtag uint64, ext Ext) { +func (e *msgpackEncDriver[T]) EncodeExt(v interface{}, basetype reflect.Type, xtag uint64, ext Ext) { var bs0, bs []byte if ext == SelfExt { bs0 = e.e.blist.get(1024) bs = bs0 - e.e.sideEncode(v, basetype, &bs) + sideEncode(e.h, &e.h.sideEncPool, func(se encoderI) { oneOffEncode(se, v, &bs, basetype, true) }) } else { bs = ext.WriteExt(v) } if bs == nil { - e.EncodeNil() + e.writeNilBytes() goto END } if e.h.WriteExt { e.encodeExtPreamble(uint8(xtag), len(bs)) - e.e.encWr.writeb(bs) + e.w.writeb(bs) } else { - e.EncodeStringBytesRaw(bs) + e.EncodeBytes(bs) } END: if ext == SelfExt { @@ -319,45 +180,55 @@ END: } } -func (e *msgpackEncDriver) EncodeRawExt(re *RawExt) { +func (e *msgpackEncDriver[T]) EncodeRawExt(re *RawExt) { e.encodeExtPreamble(uint8(re.Tag), len(re.Data)) - e.e.encWr.writeb(re.Data) + e.w.writeb(re.Data) } -func (e *msgpackEncDriver) encodeExtPreamble(xtag byte, l int) { +func (e *msgpackEncDriver[T]) encodeExtPreamble(xtag byte, l int) { if l == 1 { - e.e.encWr.writen2(mpFixExt1, xtag) + e.w.writen2(mpFixExt1, xtag) } else if l == 2 { - e.e.encWr.writen2(mpFixExt2, xtag) + e.w.writen2(mpFixExt2, xtag) } else if l == 4 { - e.e.encWr.writen2(mpFixExt4, xtag) + e.w.writen2(mpFixExt4, xtag) } else if l == 8 { - e.e.encWr.writen2(mpFixExt8, xtag) + e.w.writen2(mpFixExt8, xtag) } else if l == 16 { - e.e.encWr.writen2(mpFixExt16, xtag) + e.w.writen2(mpFixExt16, xtag) } else if l < 256 { - e.e.encWr.writen2(mpExt8, byte(l)) - e.e.encWr.writen1(xtag) + e.w.writen2(mpExt8, byte(l)) + e.w.writen1(xtag) } else if l < 65536 { - e.e.encWr.writen1(mpExt16) - bigen.writeUint16(e.e.w(), uint16(l)) - e.e.encWr.writen1(xtag) + e.w.writen1(mpExt16) + e.w.writen2(bigen.PutUint16(uint16(l))) + e.w.writen1(xtag) } else { - e.e.encWr.writen1(mpExt32) - bigen.writeUint32(e.e.w(), uint32(l)) - e.e.encWr.writen1(xtag) + e.w.writen1(mpExt32) + e.w.writen4(bigen.PutUint32(uint32(l))) + e.w.writen1(xtag) } } -func (e *msgpackEncDriver) WriteArrayStart(length int) { +func (e *msgpackEncDriver[T]) WriteArrayStart(length int) { e.writeContainerLen(msgpackContainerList, length) } -func (e *msgpackEncDriver) WriteMapStart(length int) { +func (e *msgpackEncDriver[T]) WriteMapStart(length int) { e.writeContainerLen(msgpackContainerMap, length) } -func (e *msgpackEncDriver) EncodeString(s string) { +func (e *msgpackEncDriver[T]) WriteArrayEmpty() { + // e.WriteArrayStart(0) = e.writeContainerLen(msgpackContainerList, 0) + e.w.writen1(mpFixArrayMin) +} + +func (e *msgpackEncDriver[T]) WriteMapEmpty() { + // e.WriteMapStart(0) = e.writeContainerLen(msgpackContainerMap, 0) + e.w.writen1(mpFixMapMin) +} + +func (e *msgpackEncDriver[T]) EncodeString(s string) { var ct msgpackContainerType if e.h.WriteExt { if e.h.StringToRaw { @@ -370,53 +241,78 @@ func (e *msgpackEncDriver) EncodeString(s string) { } e.writeContainerLen(ct, len(s)) if len(s) > 0 { - e.e.encWr.writestr(s) + e.w.writestr(s) } } -func (e *msgpackEncDriver) EncodeStringBytesRaw(bs []byte) { - if bs == nil { - e.EncodeNil() - return - } +func (e *msgpackEncDriver[T]) EncodeStringNoEscape4Json(v string) { e.EncodeString(v) } + +func (e *msgpackEncDriver[T]) EncodeStringBytesRaw(bs []byte) { if e.h.WriteExt { e.writeContainerLen(msgpackContainerBin, len(bs)) } else { e.writeContainerLen(msgpackContainerRawLegacy, len(bs)) } if len(bs) > 0 { - e.e.encWr.writeb(bs) + e.w.writeb(bs) + } +} + +func (e *msgpackEncDriver[T]) EncodeBytes(v []byte) { + if v == nil { + e.writeNilBytes() + return + } + e.EncodeStringBytesRaw(v) +} + +func (e *msgpackEncDriver[T]) writeNilOr(v byte) { + if !e.h.NilCollectionToZeroLength { + v = mpNil } + e.w.writen1(v) } -func (e *msgpackEncDriver) writeContainerLen(ct msgpackContainerType, l int) { +func (e *msgpackEncDriver[T]) writeNilArray() { + e.writeNilOr(mpFixArrayMin) +} + +func (e *msgpackEncDriver[T]) writeNilMap() { + e.writeNilOr(mpFixMapMin) +} + +func (e *msgpackEncDriver[T]) writeNilBytes() { + e.writeNilOr(mpFixStrMin) +} + +func (e *msgpackEncDriver[T]) writeContainerLen(ct msgpackContainerType, l int) { if ct.fixCutoff > 0 && l < int(ct.fixCutoff) { - e.e.encWr.writen1(ct.bFixMin | byte(l)) + e.w.writen1(ct.bFixMin | byte(l)) } else if ct.b8 > 0 && l < 256 { - e.e.encWr.writen2(ct.b8, uint8(l)) + e.w.writen2(ct.b8, uint8(l)) } else if l < 65536 { - e.e.encWr.writen1(ct.b16) - bigen.writeUint16(e.e.w(), uint16(l)) + e.w.writen1(ct.b16) + e.w.writen2(bigen.PutUint16(uint16(l))) } else { - e.e.encWr.writen1(ct.b32) - bigen.writeUint32(e.e.w(), uint32(l)) + e.w.writen1(ct.b32) + e.w.writen4(bigen.PutUint32(uint32(l))) } } //--------------------------------------------- -type msgpackDecDriver struct { +type msgpackDecDriver[T decReader] struct { decDriverNoopContainerReader decDriverNoopNumberHelper + decInit2er + h *MsgpackHandle + d *decoderBase + r T + bdAndBdread - _ bool + // bytes bool noBuiltInTypes - d Decoder -} - -func (d *msgpackDecDriver) decoder() *Decoder { - return &d.d } // Note: This returns either a primitive (int, bool, etc) for non-containers, @@ -424,7 +320,7 @@ func (d *msgpackDecDriver) decoder() *Decoder { // It is called when a nil interface{} is passed, leaving it up to the DecDriver // to introspect the stream and decide how best to decode. // It deciphers the value by looking at the stream first. -func (d *msgpackDecDriver) DecodeNaked() { +func (d *msgpackDecDriver[T]) DecodeNaked() { if !d.bdRead { d.readNextBd() } @@ -445,36 +341,36 @@ func (d *msgpackDecDriver) DecodeNaked() { case mpFloat: n.v = valueTypeFloat - n.f = float64(math.Float32frombits(bigen.Uint32(d.d.decRd.readn4()))) + n.f = float64(math.Float32frombits(bigen.Uint32(d.r.readn4()))) case mpDouble: n.v = valueTypeFloat - n.f = math.Float64frombits(bigen.Uint64(d.d.decRd.readn8())) + n.f = math.Float64frombits(bigen.Uint64(d.r.readn8())) case mpUint8: n.v = valueTypeUint - n.u = uint64(d.d.decRd.readn1()) + n.u = uint64(d.r.readn1()) case mpUint16: n.v = valueTypeUint - n.u = uint64(bigen.Uint16(d.d.decRd.readn2())) + n.u = uint64(bigen.Uint16(d.r.readn2())) case mpUint32: n.v = valueTypeUint - n.u = uint64(bigen.Uint32(d.d.decRd.readn4())) + n.u = uint64(bigen.Uint32(d.r.readn4())) case mpUint64: n.v = valueTypeUint - n.u = uint64(bigen.Uint64(d.d.decRd.readn8())) + n.u = uint64(bigen.Uint64(d.r.readn8())) case mpInt8: n.v = valueTypeInt - n.i = int64(int8(d.d.decRd.readn1())) + n.i = int64(int8(d.r.readn1())) case mpInt16: n.v = valueTypeInt - n.i = int64(int16(bigen.Uint16(d.d.decRd.readn2()))) + n.i = int64(int16(bigen.Uint16(d.r.readn2()))) case mpInt32: n.v = valueTypeInt - n.i = int64(int32(bigen.Uint32(d.d.decRd.readn4()))) + n.i = int64(int32(bigen.Uint32(d.r.readn4()))) case mpInt64: n.v = valueTypeInt - n.i = int64(int64(bigen.Uint64(d.d.decRd.readn8()))) + n.i = int64(int64(bigen.Uint64(d.r.readn8()))) default: switch { @@ -487,7 +383,7 @@ func (d *msgpackDecDriver) DecodeNaked() { n.v = valueTypeInt n.i = int64(int8(bd)) case bd == mpStr8, bd == mpStr16, bd == mpStr32, bd >= mpFixStrMin && bd <= mpFixStrMax: - d.d.fauxUnionReadRawBytes(d.h.WriteExt) + d.d.fauxUnionReadRawBytes(d, d.h.WriteExt, d.h.RawToString) //, d.h.ZeroCopy) // if d.h.WriteExt || d.h.RawToString { // n.v = valueTypeString // n.s = d.d.stringZC(d.DecodeStringAsBytes()) @@ -496,7 +392,7 @@ func (d *msgpackDecDriver) DecodeNaked() { // n.l = d.DecodeBytes([]byte{}) // } case bd == mpBin8, bd == mpBin16, bd == mpBin32: - d.d.fauxUnionReadRawBytes(false) + d.d.fauxUnionReadRawBytes(d, false, d.h.RawToString) //, d.h.ZeroCopy) case bd == mpArray16, bd == mpArray32, bd >= mpFixArrayMin && bd <= mpFixArrayMax: n.v = valueTypeArray decodeFurther = true @@ -506,17 +402,15 @@ func (d *msgpackDecDriver) DecodeNaked() { case bd >= mpFixExt1 && bd <= mpFixExt16, bd >= mpExt8 && bd <= mpExt32: n.v = valueTypeExt clen := d.readExtLen() - n.u = uint64(d.d.decRd.readn1()) + n.u = uint64(d.r.readn1()) if n.u == uint64(mpTimeExtTagU) { n.v = valueTypeTime n.t = d.decodeTime(clen) - } else if d.d.bytes { - n.l = d.d.decRd.rb.readx(uint(clen)) } else { - n.l = decByteSlice(d.d.r(), clen, d.d.h.MaxInitLen, d.d.b[:]) + n.l = d.r.readx(uint(clen)) } default: - d.d.errorf("cannot infer value: %s: Ox%x/%d/%s", msgBadDesc, bd, bd, mpdesc(bd)) + halt.errorf("cannot infer value: %s: Ox%x/%d/%s", msgBadDesc, bd, bd, mpdesc(bd)) } } if !decodeFurther { @@ -528,32 +422,18 @@ func (d *msgpackDecDriver) DecodeNaked() { } } -func (d *msgpackDecDriver) nextValueBytes(v0 []byte) (v []byte) { +func (d *msgpackDecDriver[T]) nextValueBytes() (v []byte) { if !d.bdRead { d.readNextBd() } - v = v0 - var h = decNextValueBytesHelper{d: &d.d} - var cursor = d.d.rb.c - 1 - h.append1(&v, d.bd) - v = d.nextValueBytesBdReadR(v) + d.r.startRecording() + d.nextValueBytesBdReadR() + v = d.r.stopRecording() d.bdRead = false - h.bytesRdV(&v, cursor) return } -func (d *msgpackDecDriver) nextValueBytesR(v0 []byte) (v []byte) { - d.readNextBd() - v = v0 - var h = decNextValueBytesHelper{d: &d.d} - h.append1(&v, d.bd) - return d.nextValueBytesBdReadR(v) -} - -func (d *msgpackDecDriver) nextValueBytesBdReadR(v0 []byte) (v []byte) { - v = v0 - var h = decNextValueBytesHelper{d: &d.d} - +func (d *msgpackDecDriver[T]) nextValueBytesBdReadR() { bd := d.bd var clen uint @@ -561,88 +441,84 @@ func (d *msgpackDecDriver) nextValueBytesBdReadR(v0 []byte) (v []byte) { switch bd { case mpNil, mpFalse, mpTrue: // pass case mpUint8, mpInt8: - h.append1(&v, d.d.decRd.readn1()) + d.r.readn1() case mpUint16, mpInt16: - h.appendN(&v, d.d.decRd.readx(2)...) + d.r.skip(2) case mpFloat, mpUint32, mpInt32: - h.appendN(&v, d.d.decRd.readx(4)...) + d.r.skip(4) case mpDouble, mpUint64, mpInt64: - h.appendN(&v, d.d.decRd.readx(8)...) + d.r.skip(8) case mpStr8, mpBin8: - clen = uint(d.d.decRd.readn1()) - h.append1(&v, byte(clen)) - h.appendN(&v, d.d.decRd.readx(clen)...) + clen = uint(d.r.readn1()) + d.r.skip(clen) case mpStr16, mpBin16: - x := d.d.decRd.readn2() - h.appendN(&v, x[:]...) + x := d.r.readn2() clen = uint(bigen.Uint16(x)) - h.appendN(&v, d.d.decRd.readx(clen)...) + d.r.skip(clen) case mpStr32, mpBin32: - x := d.d.decRd.readn4() - h.appendN(&v, x[:]...) + x := d.r.readn4() clen = uint(bigen.Uint32(x)) - h.appendN(&v, d.d.decRd.readx(clen)...) + d.r.skip(clen) case mpFixExt1: - h.append1(&v, d.d.decRd.readn1()) // tag - h.append1(&v, d.d.decRd.readn1()) + d.r.readn1() // tag + d.r.readn1() case mpFixExt2: - h.append1(&v, d.d.decRd.readn1()) // tag - h.appendN(&v, d.d.decRd.readx(2)...) + d.r.readn1() // tag + d.r.skip(2) case mpFixExt4: - h.append1(&v, d.d.decRd.readn1()) // tag - h.appendN(&v, d.d.decRd.readx(4)...) + d.r.readn1() // tag + d.r.skip(4) case mpFixExt8: - h.append1(&v, d.d.decRd.readn1()) // tag - h.appendN(&v, d.d.decRd.readx(8)...) + d.r.readn1() // tag + d.r.skip(8) case mpFixExt16: - h.append1(&v, d.d.decRd.readn1()) // tag - h.appendN(&v, d.d.decRd.readx(16)...) + d.r.readn1() // tag + d.r.skip(16) case mpExt8: - clen = uint(d.d.decRd.readn1()) - h.append1(&v, uint8(clen)) - h.append1(&v, d.d.decRd.readn1()) // tag - h.appendN(&v, d.d.decRd.readx(clen)...) + clen = uint(d.r.readn1()) + d.r.readn1() // tag + d.r.skip(clen) case mpExt16: - x := d.d.decRd.readn2() + x := d.r.readn2() clen = uint(bigen.Uint16(x)) - h.appendN(&v, x[:]...) - h.append1(&v, d.d.decRd.readn1()) // tag - h.appendN(&v, d.d.decRd.readx(clen)...) + d.r.readn1() // tag + d.r.skip(clen) case mpExt32: - x := d.d.decRd.readn4() + x := d.r.readn4() clen = uint(bigen.Uint32(x)) - h.appendN(&v, x[:]...) - h.append1(&v, d.d.decRd.readn1()) // tag - h.appendN(&v, d.d.decRd.readx(clen)...) + d.r.readn1() // tag + d.r.skip(clen) case mpArray16: - x := d.d.decRd.readn2() + x := d.r.readn2() clen = uint(bigen.Uint16(x)) - h.appendN(&v, x[:]...) for i := uint(0); i < clen; i++ { - v = d.nextValueBytesR(v) + d.readNextBd() + d.nextValueBytesBdReadR() } case mpArray32: - x := d.d.decRd.readn4() + x := d.r.readn4() clen = uint(bigen.Uint32(x)) - h.appendN(&v, x[:]...) for i := uint(0); i < clen; i++ { - v = d.nextValueBytesR(v) + d.readNextBd() + d.nextValueBytesBdReadR() } case mpMap16: - x := d.d.decRd.readn2() + x := d.r.readn2() clen = uint(bigen.Uint16(x)) - h.appendN(&v, x[:]...) for i := uint(0); i < clen; i++ { - v = d.nextValueBytesR(v) - v = d.nextValueBytesR(v) + d.readNextBd() + d.nextValueBytesBdReadR() + d.readNextBd() + d.nextValueBytesBdReadR() } case mpMap32: - x := d.d.decRd.readn4() + x := d.r.readn4() clen = uint(bigen.Uint32(x)) - h.appendN(&v, x[:]...) for i := uint(0); i < clen; i++ { - v = d.nextValueBytesR(v) - v = d.nextValueBytesR(v) + d.readNextBd() + d.nextValueBytesBdReadR() + d.readNextBd() + d.nextValueBytesBdReadR() } default: switch { @@ -650,65 +526,68 @@ func (d *msgpackDecDriver) nextValueBytesBdReadR(v0 []byte) (v []byte) { case bd >= mpNegFixNumMin && bd <= mpNegFixNumMax: // pass case bd >= mpFixStrMin && bd <= mpFixStrMax: clen = uint(mpFixStrMin ^ bd) - h.appendN(&v, d.d.decRd.readx(clen)...) + d.r.skip(clen) case bd >= mpFixArrayMin && bd <= mpFixArrayMax: clen = uint(mpFixArrayMin ^ bd) for i := uint(0); i < clen; i++ { - v = d.nextValueBytesR(v) + d.readNextBd() + d.nextValueBytesBdReadR() } case bd >= mpFixMapMin && bd <= mpFixMapMax: clen = uint(mpFixMapMin ^ bd) for i := uint(0); i < clen; i++ { - v = d.nextValueBytesR(v) - v = d.nextValueBytesR(v) + d.readNextBd() + d.nextValueBytesBdReadR() + d.readNextBd() + d.nextValueBytesBdReadR() } default: - d.d.errorf("nextValueBytes: cannot infer value: %s: Ox%x/%d/%s", msgBadDesc, bd, bd, mpdesc(bd)) + halt.errorf("nextValueBytes: cannot infer value: %s: Ox%x/%d/%s", msgBadDesc, bd, bd, mpdesc(bd)) } } return } -func (d *msgpackDecDriver) decFloat4Int32() (f float32) { - fbits := bigen.Uint32(d.d.decRd.readn4()) +func (d *msgpackDecDriver[T]) decFloat4Int32() (f float32) { + fbits := bigen.Uint32(d.r.readn4()) f = math.Float32frombits(fbits) if !noFrac32(fbits) { - d.d.errorf("assigning integer value from float32 with a fraction: %v", f) + halt.errorf("assigning integer value from float32 with a fraction: %v", f) } return } -func (d *msgpackDecDriver) decFloat4Int64() (f float64) { - fbits := bigen.Uint64(d.d.decRd.readn8()) +func (d *msgpackDecDriver[T]) decFloat4Int64() (f float64) { + fbits := bigen.Uint64(d.r.readn8()) f = math.Float64frombits(fbits) if !noFrac64(fbits) { - d.d.errorf("assigning integer value from float64 with a fraction: %v", f) + halt.errorf("assigning integer value from float64 with a fraction: %v", f) } return } // int can be decoded from msgpack type: intXXX or uintXXX -func (d *msgpackDecDriver) DecodeInt64() (i int64) { +func (d *msgpackDecDriver[T]) DecodeInt64() (i int64) { if d.advanceNil() { return } switch d.bd { case mpUint8: - i = int64(uint64(d.d.decRd.readn1())) + i = int64(uint64(d.r.readn1())) case mpUint16: - i = int64(uint64(bigen.Uint16(d.d.decRd.readn2()))) + i = int64(uint64(bigen.Uint16(d.r.readn2()))) case mpUint32: - i = int64(uint64(bigen.Uint32(d.d.decRd.readn4()))) + i = int64(uint64(bigen.Uint32(d.r.readn4()))) case mpUint64: - i = int64(bigen.Uint64(d.d.decRd.readn8())) + i = int64(bigen.Uint64(d.r.readn8())) case mpInt8: - i = int64(int8(d.d.decRd.readn1())) + i = int64(int8(d.r.readn1())) case mpInt16: - i = int64(int16(bigen.Uint16(d.d.decRd.readn2()))) + i = int64(int16(bigen.Uint16(d.r.readn2()))) case mpInt32: - i = int64(int32(bigen.Uint32(d.d.decRd.readn4()))) + i = int64(int32(bigen.Uint32(d.r.readn4()))) case mpInt64: - i = int64(bigen.Uint64(d.d.decRd.readn8())) + i = int64(bigen.Uint64(d.r.readn8())) case mpFloat: i = int64(d.decFloat4Int32()) case mpDouble: @@ -720,7 +599,7 @@ func (d *msgpackDecDriver) DecodeInt64() (i int64) { case d.bd >= mpNegFixNumMin && d.bd <= mpNegFixNumMax: i = int64(int8(d.bd)) default: - d.d.errorf("cannot decode signed integer: %s: %x/%s", msgBadDesc, d.bd, mpdesc(d.bd)) + halt.errorf("cannot decode signed integer: %s: %x/%s", msgBadDesc, d.bd, mpdesc(d.bd)) } } d.bdRead = false @@ -728,63 +607,63 @@ func (d *msgpackDecDriver) DecodeInt64() (i int64) { } // uint can be decoded from msgpack type: intXXX or uintXXX -func (d *msgpackDecDriver) DecodeUint64() (ui uint64) { +func (d *msgpackDecDriver[T]) DecodeUint64() (ui uint64) { if d.advanceNil() { return } switch d.bd { case mpUint8: - ui = uint64(d.d.decRd.readn1()) + ui = uint64(d.r.readn1()) case mpUint16: - ui = uint64(bigen.Uint16(d.d.decRd.readn2())) + ui = uint64(bigen.Uint16(d.r.readn2())) case mpUint32: - ui = uint64(bigen.Uint32(d.d.decRd.readn4())) + ui = uint64(bigen.Uint32(d.r.readn4())) case mpUint64: - ui = bigen.Uint64(d.d.decRd.readn8()) + ui = bigen.Uint64(d.r.readn8()) case mpInt8: - if i := int64(int8(d.d.decRd.readn1())); i >= 0 { + if i := int64(int8(d.r.readn1())); i >= 0 { ui = uint64(i) } else { - d.d.errorf("assigning negative signed value: %v, to unsigned type", i) + halt.errorf("assigning negative signed value: %v, to unsigned type", i) } case mpInt16: - if i := int64(int16(bigen.Uint16(d.d.decRd.readn2()))); i >= 0 { + if i := int64(int16(bigen.Uint16(d.r.readn2()))); i >= 0 { ui = uint64(i) } else { - d.d.errorf("assigning negative signed value: %v, to unsigned type", i) + halt.errorf("assigning negative signed value: %v, to unsigned type", i) } case mpInt32: - if i := int64(int32(bigen.Uint32(d.d.decRd.readn4()))); i >= 0 { + if i := int64(int32(bigen.Uint32(d.r.readn4()))); i >= 0 { ui = uint64(i) } else { - d.d.errorf("assigning negative signed value: %v, to unsigned type", i) + halt.errorf("assigning negative signed value: %v, to unsigned type", i) } case mpInt64: - if i := int64(bigen.Uint64(d.d.decRd.readn8())); i >= 0 { + if i := int64(bigen.Uint64(d.r.readn8())); i >= 0 { ui = uint64(i) } else { - d.d.errorf("assigning negative signed value: %v, to unsigned type", i) + halt.errorf("assigning negative signed value: %v, to unsigned type", i) } case mpFloat: if f := d.decFloat4Int32(); f >= 0 { ui = uint64(f) } else { - d.d.errorf("assigning negative float value: %v, to unsigned type", f) + halt.errorf("assigning negative float value: %v, to unsigned type", f) } case mpDouble: if f := d.decFloat4Int64(); f >= 0 { ui = uint64(f) } else { - d.d.errorf("assigning negative float value: %v, to unsigned type", f) + halt.errorf("assigning negative float value: %v, to unsigned type", f) } default: switch { case d.bd >= mpPosFixNumMin && d.bd <= mpPosFixNumMax: ui = uint64(d.bd) case d.bd >= mpNegFixNumMin && d.bd <= mpNegFixNumMax: - d.d.errorf("assigning negative signed value: %v, to unsigned type", int(d.bd)) + halt.errorf("assigning negative signed value: %v, to unsigned type", int(d.bd)) default: - d.d.errorf("cannot decode unsigned integer: %s: %x/%s", msgBadDesc, d.bd, mpdesc(d.bd)) + halt.errorf("cannot decode unsigned integer: %s: %x/%s", msgBadDesc, d.bd, mpdesc(d.bd)) } } d.bdRead = false @@ -792,14 +671,14 @@ func (d *msgpackDecDriver) DecodeUint64() (ui uint64) { } // float can either be decoded from msgpack type: float, double or intX -func (d *msgpackDecDriver) DecodeFloat64() (f float64) { +func (d *msgpackDecDriver[T]) DecodeFloat64() (f float64) { if d.advanceNil() { return } if d.bd == mpFloat { - f = float64(math.Float32frombits(bigen.Uint32(d.d.decRd.readn4()))) + f = float64(math.Float32frombits(bigen.Uint32(d.r.readn4()))) } else if d.bd == mpDouble { - f = math.Float64frombits(bigen.Uint64(d.d.decRd.readn8())) + f = math.Float64frombits(bigen.Uint64(d.r.readn8())) } else { f = float64(d.DecodeInt64()) } @@ -808,7 +687,7 @@ func (d *msgpackDecDriver) DecodeFloat64() (f float64) { } // bool can be decoded from bool, fixnum 0 or 1. -func (d *msgpackDecDriver) DecodeBool() (b bool) { +func (d *msgpackDecDriver[T]) DecodeBool() (b bool) { if d.advanceNil() { return } @@ -817,18 +696,18 @@ func (d *msgpackDecDriver) DecodeBool() (b bool) { } else if d.bd == mpTrue || d.bd == 1 { b = true } else { - d.d.errorf("cannot decode bool: %s: %x/%s", msgBadDesc, d.bd, mpdesc(d.bd)) + halt.errorf("cannot decode bool: %s: %x/%s", msgBadDesc, d.bd, mpdesc(d.bd)) } d.bdRead = false return } -func (d *msgpackDecDriver) DecodeBytes(bs []byte) (bsOut []byte) { - d.d.decByteState = decByteStateNone +func (d *msgpackDecDriver[T]) DecodeBytes() (bs []byte, state dBytesAttachState) { if d.advanceNil() { return } + var cond bool bd := d.bd var clen int if bd == mpBin8 || bd == mpBin16 || bd == mpBin32 { @@ -838,58 +717,43 @@ func (d *msgpackDecDriver) DecodeBytes(bs []byte) (bsOut []byte) { clen = d.readContainerLen(msgpackContainerStr) // string/raw } else if bd == mpArray16 || bd == mpArray32 || (bd >= mpFixArrayMin && bd <= mpFixArrayMax) { - // check if an "array" of uint8's - if bs == nil { - d.d.decByteState = decByteStateReuseBuf - bs = d.d.b[:] - } - // bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d) slen := d.ReadArrayStart() - var changed bool - if bs, changed = usableByteSlice(bs, slen); changed { - d.d.decByteState = decByteStateNone - } + bs, cond = usableByteSlice(d.d.buf, slen) for i := 0; i < len(bs); i++ { bs[i] = uint8(chkOvf.UintV(d.DecodeUint64(), 8)) } for i := len(bs); i < slen; i++ { bs = append(bs, uint8(chkOvf.UintV(d.DecodeUint64(), 8))) } - return bs + if cond { + d.d.buf = bs + } + state = dBytesAttachBuffer + return } else { - d.d.errorf("invalid byte descriptor for decoding bytes, got: 0x%x", d.bd) + halt.errorf("invalid byte descriptor for decoding bytes, got: 0x%x", d.bd) } d.bdRead = false - if d.d.zerocopy() { - d.d.decByteState = decByteStateZerocopy - return d.d.decRd.rb.readx(uint(clen)) - } - if bs == nil { - d.d.decByteState = decByteStateReuseBuf - bs = d.d.b[:] - } - return decByteSlice(d.d.r(), clen, d.h.MaxInitLen, bs) + bs, cond = d.r.readxb(uint(clen)) + state = d.d.attachState(cond) + return } -func (d *msgpackDecDriver) DecodeStringAsBytes() (s []byte) { - s = d.DecodeBytes(nil) - if d.h.ValidateUnicode && !utf8.Valid(s) { - d.d.errorf("DecodeStringAsBytes: invalid UTF-8: %s", s) +func (d *msgpackDecDriver[T]) DecodeStringAsBytes() (out []byte, state dBytesAttachState) { + out, state = d.DecodeBytes() + if d.h.ValidateUnicode && !utf8.Valid(out) { + halt.errorf("DecodeStringAsBytes: invalid UTF-8: %s", out) } return } -func (d *msgpackDecDriver) descBd() string { - return sprintf("%v (%s)", d.bd, mpdesc(d.bd)) -} - -func (d *msgpackDecDriver) readNextBd() { - d.bd = d.d.decRd.readn1() +func (d *msgpackDecDriver[T]) readNextBd() { + d.bd = d.r.readn1() d.bdRead = true } -func (d *msgpackDecDriver) advanceNil() (null bool) { +func (d *msgpackDecDriver[T]) advanceNil() (null bool) { if !d.bdRead { d.readNextBd() } @@ -900,11 +764,11 @@ func (d *msgpackDecDriver) advanceNil() (null bool) { return } -func (d *msgpackDecDriver) TryNil() (v bool) { +func (d *msgpackDecDriver[T]) TryNil() (v bool) { return d.advanceNil() } -func (d *msgpackDecDriver) ContainerType() (vt valueType) { +func (d *msgpackDecDriver[T]) ContainerType() (vt valueType) { if !d.bdRead { d.readNextBd() } @@ -928,38 +792,38 @@ func (d *msgpackDecDriver) ContainerType() (vt valueType) { return valueTypeUnset } -func (d *msgpackDecDriver) readContainerLen(ct msgpackContainerType) (clen int) { +func (d *msgpackDecDriver[T]) readContainerLen(ct msgpackContainerType) (clen int) { bd := d.bd if bd == ct.b8 { - clen = int(d.d.decRd.readn1()) + clen = int(d.r.readn1()) } else if bd == ct.b16 { - clen = int(bigen.Uint16(d.d.decRd.readn2())) + clen = int(bigen.Uint16(d.r.readn2())) } else if bd == ct.b32 { - clen = int(bigen.Uint32(d.d.decRd.readn4())) + clen = int(bigen.Uint32(d.r.readn4())) } else if (ct.bFixMin & bd) == ct.bFixMin { clen = int(ct.bFixMin ^ bd) } else { - d.d.errorf("cannot read container length: %s: hex: %x, decimal: %d", msgBadDesc, bd, bd) + halt.errorf("cannot read container length: %s: hex: %x, decimal: %d", msgBadDesc, bd, bd) } d.bdRead = false return } -func (d *msgpackDecDriver) ReadMapStart() int { +func (d *msgpackDecDriver[T]) ReadMapStart() int { if d.advanceNil() { return containerLenNil } return d.readContainerLen(msgpackContainerMap) } -func (d *msgpackDecDriver) ReadArrayStart() int { +func (d *msgpackDecDriver[T]) ReadArrayStart() int { if d.advanceNil() { return containerLenNil } return d.readContainerLen(msgpackContainerList) } -func (d *msgpackDecDriver) readExtLen() (clen int) { +func (d *msgpackDecDriver[T]) readExtLen() (clen int) { switch d.bd { case mpFixExt1: clen = 1 @@ -972,18 +836,18 @@ func (d *msgpackDecDriver) readExtLen() (clen int) { case mpFixExt16: clen = 16 case mpExt8: - clen = int(d.d.decRd.readn1()) + clen = int(d.r.readn1()) case mpExt16: - clen = int(bigen.Uint16(d.d.decRd.readn2())) + clen = int(bigen.Uint16(d.r.readn2())) case mpExt32: - clen = int(bigen.Uint32(d.d.decRd.readn4())) + clen = int(bigen.Uint32(d.r.readn4())) default: - d.d.errorf("decoding ext bytes: found unexpected byte: %x", d.bd) + halt.errorf("decoding ext bytes: found unexpected byte: %x", d.bd) } return } -func (d *msgpackDecDriver) DecodeTime() (t time.Time) { +func (d *msgpackDecDriver[T]) DecodeTime() (t time.Time) { // decode time from string bytes or ext if d.advanceNil() { return @@ -998,240 +862,158 @@ func (d *msgpackDecDriver) DecodeTime() (t time.Time) { } else { // expect to see mpFixExt4,-1 OR mpFixExt8,-1 OR mpExt8,12,-1 d.bdRead = false - b2 := d.d.decRd.readn1() + b2 := d.r.readn1() if d.bd == mpFixExt4 && b2 == mpTimeExtTagU { clen = 4 } else if d.bd == mpFixExt8 && b2 == mpTimeExtTagU { clen = 8 - } else if d.bd == mpExt8 && b2 == 12 && d.d.decRd.readn1() == mpTimeExtTagU { + } else if d.bd == mpExt8 && b2 == 12 && d.r.readn1() == mpTimeExtTagU { clen = 12 } else { - d.d.errorf("invalid stream for decoding time as extension: got 0x%x, 0x%x", d.bd, b2) + halt.errorf("invalid stream for decoding time as extension: got 0x%x, 0x%x", d.bd, b2) } } return d.decodeTime(clen) } -func (d *msgpackDecDriver) decodeTime(clen int) (t time.Time) { +func (d *msgpackDecDriver[T]) decodeTime(clen int) (t time.Time) { d.bdRead = false switch clen { case 4: - t = time.Unix(int64(bigen.Uint32(d.d.decRd.readn4())), 0).UTC() + t = time.Unix(int64(bigen.Uint32(d.r.readn4())), 0).UTC() case 8: - tv := bigen.Uint64(d.d.decRd.readn8()) + tv := bigen.Uint64(d.r.readn8()) t = time.Unix(int64(tv&0x00000003ffffffff), int64(tv>>34)).UTC() case 12: - nsec := bigen.Uint32(d.d.decRd.readn4()) - sec := bigen.Uint64(d.d.decRd.readn8()) + nsec := bigen.Uint32(d.r.readn4()) + sec := bigen.Uint64(d.r.readn8()) t = time.Unix(int64(sec), int64(nsec)).UTC() default: - d.d.errorf("invalid length of bytes for decoding time - expecting 4 or 8 or 12, got %d", clen) + halt.errorf("invalid length of bytes for decoding time - expecting 4 or 8 or 12, got %d", clen) } return } -func (d *msgpackDecDriver) DecodeExt(rv interface{}, basetype reflect.Type, xtag uint64, ext Ext) { - if xtag > 0xff { - d.d.errorf("ext: tag must be <= 0xff; got: %v", xtag) - } - if d.advanceNil() { +func (d *msgpackDecDriver[T]) DecodeExt(rv interface{}, basetype reflect.Type, xtag uint64, ext Ext) { + xbs, _, _, ok := d.decodeExtV(ext != nil, xtag) + if !ok { return } - xbs, realxtag1, zerocopy := d.decodeExtV(ext != nil, uint8(xtag)) - realxtag := uint64(realxtag1) - if ext == nil { - re := rv.(*RawExt) - re.Tag = realxtag - re.setData(xbs, zerocopy) - } else if ext == SelfExt { - d.d.sideDecode(rv, basetype, xbs) + if ext == SelfExt { + sideDecode(d.h, &d.h.sideDecPool, func(sd decoderI) { oneOffDecode(sd, rv, xbs, basetype, true) }) } else { ext.ReadExt(rv, xbs) } } -func (d *msgpackDecDriver) decodeExtV(verifyTag bool, tag byte) (xbs []byte, xtag byte, zerocopy bool) { +func (d *msgpackDecDriver[T]) DecodeRawExt(re *RawExt) { + xbs, realxtag, state, ok := d.decodeExtV(false, 0) + if !ok { + return + } + re.Tag = uint64(realxtag) + re.setData(xbs, state >= dBytesAttachViewZerocopy) +} + +func (d *msgpackDecDriver[T]) decodeExtV(verifyTag bool, xtagIn uint64) (xbs []byte, xtag byte, bstate dBytesAttachState, ok bool) { + if xtagIn > 0xff { + halt.errorf("ext: tag must be <= 0xff; got: %v", xtagIn) + } + if d.advanceNil() { + return + } + tag := uint8(xtagIn) xbd := d.bd if xbd == mpBin8 || xbd == mpBin16 || xbd == mpBin32 { - xbs = d.DecodeBytes(nil) + xbs, bstate = d.DecodeBytes() } else if xbd == mpStr8 || xbd == mpStr16 || xbd == mpStr32 || (xbd >= mpFixStrMin && xbd <= mpFixStrMax) { - xbs = d.DecodeStringAsBytes() + xbs, bstate = d.DecodeStringAsBytes() } else { clen := d.readExtLen() - xtag = d.d.decRd.readn1() + xtag = d.r.readn1() if verifyTag && xtag != tag { - d.d.errorf("wrong extension tag - got %b, expecting %v", xtag, tag) - } - if d.d.bytes { - xbs = d.d.decRd.rb.readx(uint(clen)) - zerocopy = true - } else { - xbs = decByteSlice(d.d.r(), clen, d.d.h.MaxInitLen, d.d.b[:]) + halt.errorf("wrong extension tag - got %b, expecting %v", xtag, tag) } + xbs, ok = d.r.readxb(uint(clen)) + bstate = d.d.attachState(ok) + // zerocopy = d.d.bytes } d.bdRead = false + ok = true return } -//-------------------------------------------------- - -// MsgpackHandle is a Handle for the Msgpack Schema-Free Encoding Format. -type MsgpackHandle struct { - binaryEncodingType - BasicHandle - - // NoFixedNum says to output all signed integers as 2-bytes, never as 1-byte fixednum. - NoFixedNum bool - - // WriteExt controls whether the new spec is honored. - // - // With WriteExt=true, we can encode configured extensions with extension tags - // and encode string/[]byte/extensions in a way compatible with the new spec - // but incompatible with the old spec. - // - // For compatibility with the old spec, set WriteExt=false. - // - // With WriteExt=false: - // configured extensions are serialized as raw bytes (not msgpack extensions). - // reserved byte descriptors like Str8 and those enabling the new msgpack Binary type - // are not encoded. - WriteExt bool - - // PositiveIntUnsigned says to encode positive integers as unsigned. - PositiveIntUnsigned bool -} - -// Name returns the name of the handle: msgpack -func (h *MsgpackHandle) Name() string { return "msgpack" } - -func (h *MsgpackHandle) desc(bd byte) string { return mpdesc(bd) } - -func (h *MsgpackHandle) newEncDriver() encDriver { - var e = &msgpackEncDriver{h: h} - e.e.e = e - e.e.init(h) - e.reset() - return e -} - -func (h *MsgpackHandle) newDecDriver() decDriver { - d := &msgpackDecDriver{h: h} - d.d.d = d - d.d.init(h) - d.reset() - return d -} - -//-------------------------------------------------- +// ---- +// +// The following below are similar across all format files (except for the format name). +// +// We keep them together here, so that we can easily copy and compare. -type msgpackSpecRpcCodec struct { - rpcCodec -} +// ---- -// /////////////// Spec RPC Codec /////////////////// -func (c *msgpackSpecRpcCodec) WriteRequest(r *rpc.Request, body interface{}) error { - // WriteRequest can write to both a Go service, and other services that do - // not abide by the 1 argument rule of a Go service. - // We discriminate based on if the body is a MsgpackSpecRpcMultiArgs - var bodyArr []interface{} - if m, ok := body.(MsgpackSpecRpcMultiArgs); ok { - bodyArr = ([]interface{})(m) +func (d *msgpackEncDriver[T]) init(hh Handle, shared *encoderBase, enc encoderI) (fp interface{}) { + callMake(&d.w) + d.h = hh.(*MsgpackHandle) + d.e = shared + if shared.bytes { + fp = msgpackFpEncBytes } else { - bodyArr = []interface{}{body} + fp = msgpackFpEncIO } - r2 := []interface{}{0, uint32(r.Seq), r.ServiceMethod, bodyArr} - return c.write(r2) + // d.w.init() + d.init2(enc) + return } -func (c *msgpackSpecRpcCodec) WriteResponse(r *rpc.Response, body interface{}) error { - var moe interface{} - if r.Error != "" { - moe = r.Error - } - if moe != nil && body != nil { - body = nil - } - r2 := []interface{}{1, uint32(r.Seq), moe, body} - return c.write(r2) -} +func (e *msgpackEncDriver[T]) writeBytesAsis(b []byte) { e.w.writeb(b) } -func (c *msgpackSpecRpcCodec) ReadResponseHeader(r *rpc.Response) error { - return c.parseCustomHeader(1, &r.Seq, &r.Error) -} +// func (e *msgpackEncDriver[T]) writeStringAsisDblQuoted(v string) { e.w.writeqstr(v) } -func (c *msgpackSpecRpcCodec) ReadRequestHeader(r *rpc.Request) error { - return c.parseCustomHeader(0, &r.Seq, &r.ServiceMethod) -} +func (e *msgpackEncDriver[T]) writerEnd() { e.w.end() } -func (c *msgpackSpecRpcCodec) ReadRequestBody(body interface{}) error { - if body == nil { // read and discard - return c.read(nil) - } - bodyArr := []interface{}{body} - return c.read(&bodyArr) +func (e *msgpackEncDriver[T]) resetOutBytes(out *[]byte) { + e.w.resetBytes(*out, out) } -func (c *msgpackSpecRpcCodec) parseCustomHeader(expectTypeByte byte, msgid *uint64, methodOrError *string) (err error) { - if cls := c.cls.load(); cls.closed { - return io.ErrUnexpectedEOF - } - - // We read the response header by hand - // so that the body can be decoded on its own from the stream at a later time. - - const fia byte = 0x94 //four item array descriptor value +func (e *msgpackEncDriver[T]) resetOutIO(out io.Writer) { + e.w.resetIO(out, e.h.WriterBufferSize, &e.e.blist) +} - var ba [1]byte - var n int - for { - n, err = c.r.Read(ba[:]) - if err != nil { - return - } - if n == 1 { - break - } - } +// ---- - var b = ba[0] - if b != fia { - err = fmt.Errorf("not array - %s %x/%s", msgBadDesc, b, mpdesc(b)) +func (d *msgpackDecDriver[T]) init(hh Handle, shared *decoderBase, dec decoderI) (fp interface{}) { + callMake(&d.r) + d.h = hh.(*MsgpackHandle) + d.d = shared + if shared.bytes { + fp = msgpackFpDecBytes } else { - err = c.read(&b) - if err == nil { - if b != expectTypeByte { - err = fmt.Errorf("%s - expecting %v but got %x/%s", msgBadDesc, expectTypeByte, b, mpdesc(b)) - } else { - err = c.read(msgid) - if err == nil { - err = c.read(methodOrError) - } - } - } + fp = msgpackFpDecIO } + // d.r.init() + d.init2(dec) return } -//-------------------------------------------------- - -// msgpackSpecRpc is the implementation of Rpc that uses custom communication protocol -// as defined in the msgpack spec at https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md -type msgpackSpecRpc struct{} +func (d *msgpackDecDriver[T]) NumBytesRead() int { + return int(d.r.numread()) +} -// MsgpackSpecRpc implements Rpc using the communication protocol defined in -// the msgpack spec at https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md . -// -// See GoRpc documentation, for information on buffering for better performance. -var MsgpackSpecRpc msgpackSpecRpc +func (d *msgpackDecDriver[T]) resetInBytes(in []byte) { + d.r.resetBytes(in) +} -func (x msgpackSpecRpc) ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec { - return &msgpackSpecRpcCodec{newRPCCodec(conn, h)} +func (d *msgpackDecDriver[T]) resetInIO(r io.Reader) { + d.r.resetIO(r, d.h.ReaderBufferSize, d.h.MaxInitLen, &d.d.blist) } -func (x msgpackSpecRpc) ClientCodec(conn io.ReadWriteCloser, h Handle) rpc.ClientCodec { - return &msgpackSpecRpcCodec{newRPCCodec(conn, h)} +// ---- (custom stanza) + +func (d *msgpackDecDriver[T]) descBd() string { + return sprintf("%v (%s)", d.bd, mpdesc(d.bd)) } -var _ decDriver = (*msgpackDecDriver)(nil) -var _ encDriver = (*msgpackEncDriver)(nil) +func (d *msgpackDecDriver[T]) DecodeFloat32() (f float32) { + return float32(chkOvf.Float32V(d.DecodeFloat64())) +} -- cgit v1.2.3