diff --git a/go.mod b/go.mod index 32363b994..4cfdc24ee 100644 --- a/go.mod +++ b/go.mod @@ -34,7 +34,7 @@ require ( github.com/stretchr/testify v1.11.1 github.com/tebeka/strftime v0.1.5 github.com/tevino/abool v1.2.0 - github.com/tinylib/msgp v1.4.0 + github.com/tinylib/msgp v1.6.1 github.com/valyala/fastjson v1.6.4 github.com/wangjohn/quickselect v0.0.0-20161129230411-ed8402a42d5f go.uber.org/zap v1.27.0 diff --git a/go.sum b/go.sum index d0445f0fa..fad9e0172 100644 --- a/go.sum +++ b/go.sum @@ -180,8 +180,8 @@ github.com/tebeka/strftime v0.1.5 h1:1NQKN1NiQgkqd/2moD6ySP/5CoZQsKa1d3ZhJ44Jpmg github.com/tebeka/strftime v0.1.5/go.mod h1:29/OidkoWHdEKZqzyDLUyC+LmgDgdHo4WAFCDT7D/Ig= github.com/tevino/abool v1.2.0 h1:heAkClL8H6w+mK5md9dzsuohKeXHUpY7Vw0ZCKW+huA= github.com/tevino/abool v1.2.0/go.mod h1:qc66Pna1RiIsPa7O4Egxxs9OqkuxDX55zznh9K07Tzg= -github.com/tinylib/msgp v1.4.0 h1:SYOeDRiydzOw9kSiwdYp9UcBgPFtLU2WDHaJXyHruf8= -github.com/tinylib/msgp v1.4.0/go.mod h1:cvjFkb4RiC8qSBOPMGPSzSAx47nAsfhLVTCZZNuHv5o= +github.com/tinylib/msgp v1.6.1 h1:ESRv8eL3u+DNHUoSAAQRE50Hm162zqAnBoGv9PzScPY= +github.com/tinylib/msgp v1.6.1/go.mod h1:RSp0LW9oSxFut3KzESt5Voq4GVWyS+PSulT77roAqEA= github.com/valyala/fastjson v1.6.4 h1:uAUNq9Z6ymTgGhcm0UynUAB6tlbakBrz6CQFax3BXVQ= github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY= github.com/wangjohn/quickselect v0.0.0-20161129230411-ed8402a42d5f h1:9DDCDwOyEy/gId+IEMrFHLuQ5R/WV0KNxWLler8X2OY= diff --git a/vendor/github.com/tinylib/msgp/msgp/advise_linux.go b/vendor/github.com/tinylib/msgp/msgp/advise_linux.go index d2a66857b..b7c30d3e9 100644 --- a/vendor/github.com/tinylib/msgp/msgp/advise_linux.go +++ b/vendor/github.com/tinylib/msgp/msgp/advise_linux.go @@ -1,5 +1,4 @@ //go:build linux && !appengine && !tinygo -// +build linux,!appengine,!tinygo package msgp diff --git a/vendor/github.com/tinylib/msgp/msgp/advise_other.go b/vendor/github.com/tinylib/msgp/msgp/advise_other.go index 07f524af7..0017cfb91 100644 --- a/vendor/github.com/tinylib/msgp/msgp/advise_other.go +++ b/vendor/github.com/tinylib/msgp/msgp/advise_other.go @@ -1,5 +1,4 @@ //go:build (!linux && !tinygo && !windows) || appengine -// +build !linux,!tinygo,!windows appengine package msgp diff --git a/vendor/github.com/tinylib/msgp/msgp/autoshim.go b/vendor/github.com/tinylib/msgp/msgp/autoshim.go index 7d5b4cabf..a73406886 100644 --- a/vendor/github.com/tinylib/msgp/msgp/autoshim.go +++ b/vendor/github.com/tinylib/msgp/msgp/autoshim.go @@ -33,7 +33,7 @@ func (a AutoShim) ParseUint32(s string) (uint32, error) { // ParseUint64 converts a string to a uint64. func (a AutoShim) ParseUint64(s string) (uint64, error) { v, err := strconv.ParseUint(s, 10, 64) - return uint64(v), err + return v, err } // ParseInt converts a string to an int. @@ -63,7 +63,7 @@ func (a AutoShim) ParseInt32(s string) (int32, error) { // ParseInt64 converts a string to an int64. func (a AutoShim) ParseInt64(s string) (int64, error) { v, err := strconv.ParseInt(s, 10, 64) - return int64(v), err + return v, err } // ParseBool converts a string to a bool. diff --git a/vendor/github.com/tinylib/msgp/msgp/defs.go b/vendor/github.com/tinylib/msgp/msgp/defs.go index 47a8c1834..f622bf1e1 100644 --- a/vendor/github.com/tinylib/msgp/msgp/defs.go +++ b/vendor/github.com/tinylib/msgp/msgp/defs.go @@ -26,6 +26,27 @@ // the wiki at http://github.com/tinylib/msgp package msgp +// RT is the runtime interface for all types that can be encoded and decoded. +type RT interface { + Decodable + Encodable + Sizer + Unmarshaler + Marshaler +} + +// PtrTo is the runtime interface for all types that can be encoded and decoded. +type PtrTo[T any] interface { + ~*T +} + +// RTFor is the runtime interface for all types that can be encoded and decoded. +// Use for generic types. +type RTFor[T any] interface { + PtrTo[T] + RT +} + const ( last4 = 0x0f first4 = 0xf0 diff --git a/vendor/github.com/tinylib/msgp/msgp/edit.go b/vendor/github.com/tinylib/msgp/msgp/edit.go index b473a6f66..e5d86f936 100644 --- a/vendor/github.com/tinylib/msgp/msgp/edit.go +++ b/vendor/github.com/tinylib/msgp/msgp/edit.go @@ -58,7 +58,7 @@ func HasKey(key string, raw []byte) bool { return false } var field []byte - for i := uint32(0); i < sz; i++ { + for range sz { field, bts, err = ReadStringZC(bts) if err != nil { return false diff --git a/vendor/github.com/tinylib/msgp/msgp/elsize_default.go b/vendor/github.com/tinylib/msgp/msgp/elsize_default.go index e7e8b547a..d68c6bb26 100644 --- a/vendor/github.com/tinylib/msgp/msgp/elsize_default.go +++ b/vendor/github.com/tinylib/msgp/msgp/elsize_default.go @@ -1,5 +1,4 @@ //go:build !tinygo -// +build !tinygo package msgp @@ -10,7 +9,7 @@ package msgp var sizes [256]bytespec func init() { - for i := 0; i < 256; i++ { + for i := range 256 { sizes[i] = calcBytespec(byte(i)) } } diff --git a/vendor/github.com/tinylib/msgp/msgp/elsize_tinygo.go b/vendor/github.com/tinylib/msgp/msgp/elsize_tinygo.go index 041f4ad69..b1c11f96a 100644 --- a/vendor/github.com/tinylib/msgp/msgp/elsize_tinygo.go +++ b/vendor/github.com/tinylib/msgp/msgp/elsize_tinygo.go @@ -1,5 +1,4 @@ //go:build tinygo -// +build tinygo package msgp diff --git a/vendor/github.com/tinylib/msgp/msgp/errors.go b/vendor/github.com/tinylib/msgp/msgp/errors.go index e2261b760..ce4220736 100644 --- a/vendor/github.com/tinylib/msgp/msgp/errors.go +++ b/vendor/github.com/tinylib/msgp/msgp/errors.go @@ -77,7 +77,7 @@ func Resumable(e error) bool { // // ErrShortBytes is not wrapped with any context due to backward compatibility // issues with the public API. -func WrapError(err error, ctx ...interface{}) error { +func WrapError(err error, ctx ...any) error { switch e := err.(type) { case errShort: return e @@ -391,8 +391,8 @@ l: // loop through string bytes (not UTF-8 characters) } // anything else is \x sb = append(sb, `\x`...) - sb = append(sb, lowerhex[byte(b)>>4]) - sb = append(sb, lowerhex[byte(b)&0xF]) + sb = append(sb, lowerhex[b>>4]) + sb = append(sb, lowerhex[b&0xF]) continue l } } diff --git a/vendor/github.com/tinylib/msgp/msgp/errors_default.go b/vendor/github.com/tinylib/msgp/msgp/errors_default.go index e45c00a8b..b9dc0d994 100644 --- a/vendor/github.com/tinylib/msgp/msgp/errors_default.go +++ b/vendor/github.com/tinylib/msgp/msgp/errors_default.go @@ -1,5 +1,4 @@ //go:build !tinygo -// +build !tinygo package msgp @@ -9,7 +8,7 @@ import ( ) // ctxString converts the incoming interface{} slice into a single string. -func ctxString(ctx []interface{}) string { +func ctxString(ctx []any) string { out := "" for idx, cv := range ctx { if idx > 0 { diff --git a/vendor/github.com/tinylib/msgp/msgp/errors_tinygo.go b/vendor/github.com/tinylib/msgp/msgp/errors_tinygo.go index 8691cd387..18f44c5f6 100644 --- a/vendor/github.com/tinylib/msgp/msgp/errors_tinygo.go +++ b/vendor/github.com/tinylib/msgp/msgp/errors_tinygo.go @@ -1,5 +1,4 @@ //go:build tinygo -// +build tinygo package msgp diff --git a/vendor/github.com/tinylib/msgp/msgp/extension.go b/vendor/github.com/tinylib/msgp/msgp/extension.go index b92af8fbb..2ec255240 100644 --- a/vendor/github.com/tinylib/msgp/msgp/extension.go +++ b/vendor/github.com/tinylib/msgp/msgp/extension.go @@ -181,7 +181,7 @@ func (mw *Writer) writeExtensionHeader(length int, extType int8) error { return err } mw.buf[o] = mext8 - mw.buf[o+1] = byte(uint8(length)) + mw.buf[o+1] = byte(length) mw.buf[o+2] = byte(extType) case length < math.MaxUint16: o, err := mw.require(4) @@ -342,7 +342,7 @@ func (m *Reader) peekExtensionHeader() (offset int, length int, extType int8, er } offset = 3 extType = int8(p[2]) - length = int(uint8(p[1])) + length = int(p[1]) case mext16: p, err = m.R.Peek(4) @@ -461,7 +461,7 @@ func AppendExtension(b []byte, e Extension) ([]byte, error) { case l < math.MaxUint8: o, n = ensure(b, l+3) o[n] = mext8 - o[n+1] = byte(uint8(l)) + o[n+1] = byte(l) o[n+2] = byte(e.ExtensionType()) n += 3 case l < math.MaxUint16: @@ -534,7 +534,7 @@ func readExt(b []byte) (typ int8, remain []byte, data []byte, err error) { sz = 16 off = 2 case mext8: - sz = int(uint8(b[1])) + sz = int(b[1]) typ = int8(b[2]) off = 3 if sz == 0 { diff --git a/vendor/github.com/tinylib/msgp/msgp/file.go b/vendor/github.com/tinylib/msgp/msgp/file.go index a6d91ede1..f12bea3d9 100644 --- a/vendor/github.com/tinylib/msgp/msgp/file.go +++ b/vendor/github.com/tinylib/msgp/msgp/file.go @@ -1,7 +1,4 @@ //go:build (linux || darwin || dragonfly || freebsd || illumos || netbsd || openbsd) && !appengine && !tinygo -// +build linux darwin dragonfly freebsd illumos netbsd openbsd -// +build !appengine -// +build !tinygo package msgp diff --git a/vendor/github.com/tinylib/msgp/msgp/file_port.go b/vendor/github.com/tinylib/msgp/msgp/file_port.go index dac0dba3f..b7de634cb 100644 --- a/vendor/github.com/tinylib/msgp/msgp/file_port.go +++ b/vendor/github.com/tinylib/msgp/msgp/file_port.go @@ -1,5 +1,4 @@ //go:build windows || appengine || tinygo -// +build windows appengine tinygo package msgp diff --git a/vendor/github.com/tinylib/msgp/msgp/integers.go b/vendor/github.com/tinylib/msgp/msgp/integers.go index d07a5fba7..fabe6c237 100644 --- a/vendor/github.com/tinylib/msgp/msgp/integers.go +++ b/vendor/github.com/tinylib/msgp/msgp/integers.go @@ -133,11 +133,11 @@ func putMuint8(b []byte, u uint8) { _ = b[1] // bounds check elimination b[0] = muint8 - b[1] = byte(u) + b[1] = u } func getMuint8(b []byte) uint8 { - return uint8(b[1]) + return b[1] } func getUnix(b []byte) (sec int64, nsec int32) { @@ -161,7 +161,7 @@ func prefixu8(b []byte, pre byte, sz uint8) { _ = b[1] // bounds check elimination b[0] = pre - b[1] = byte(sz) + b[1] = sz } // write prefix and big-endian uint16 diff --git a/vendor/github.com/tinylib/msgp/msgp/iter.go b/vendor/github.com/tinylib/msgp/msgp/iter.go new file mode 100644 index 000000000..a7c3b030e --- /dev/null +++ b/vendor/github.com/tinylib/msgp/msgp/iter.go @@ -0,0 +1,386 @@ +package msgp + +import ( + "cmp" + "fmt" + "iter" + "maps" + "math" + "slices" +) + +// ReadArray returns an iterator that can be used to iterate over the elements +// of an array in the MessagePack data while being read by the provided Reader. +// The type parameter V specifies the type of the elements in the array. +// The returned iterator implements the iter.Seq[V] interface, +// allowing for sequential access to the array elements. +// The iterator will always stop after one error has been encountered. +func ReadArray[T any](m *Reader, readFn func() (T, error)) iter.Seq2[T, error] { + return func(yield func(T, error) bool) { + // Check if nil + if m.IsNil() { + m.ReadNil() + return + } + // Regular array. + var empty T + length, err := m.ReadArrayHeader() + if err != nil { + yield(empty, fmt.Errorf("cannot read array header: %w", err)) + return + } + for range length { + var v T + v, err = readFn() + if !yield(v, err) || err != nil { + return + } + } + } +} + +// WriteArray writes an array to the provided Writer. +// The writeFn parameter specifies the function to use to write each element of the array. +func WriteArray[T any](w *Writer, a []T, writeFn func(T) error) error { + // Check if nil + if a == nil { + return w.WriteNil() + } + if uint64(len(a)) > math.MaxUint32 { + return fmt.Errorf("array too large to encode: %d elements", len(a)) + } + // Write array header + err := w.WriteArrayHeader(uint32(len(a))) + if err != nil { + return err + } + // Write elements + for _, v := range a { + err = writeFn(v) + if err != nil { + return err + } + } + return nil +} + +// ReadMap returns an iterator that can be used to iterate over the elements +// of a map in the MessagePack data while being read by the provided Reader. +// The type parameters K and V specify the types of the keys and values in the map. +// The returned iterator implements the iter.Seq2[K, V] interface, +// allowing for sequential access to the map elements. +// The returned function can be used to read any error that +// occurred during iteration when iteration is done. +func ReadMap[K, V any](m *Reader, readKey func() (K, error), readVal func() (V, error)) (iter.Seq2[K, V], func() error) { + var err error + return func(yield func(K, V) bool) { + var sz uint32 + if m.IsNil() { + err = m.ReadNil() + return + } + sz, err = m.ReadMapHeader() + if err != nil { + err = fmt.Errorf("cannot read map header: %w", err) + return + } + + for range sz { + var k K + k, err = readKey() + if err != nil { + err = fmt.Errorf("cannot read key: %w", err) + return + } + var v V + v, err = readVal() + if err != nil { + err = fmt.Errorf("cannot read value: %w", err) + return + } + if !yield(k, v) { + return + } + } + }, func() error { return err } +} + +// WriteMap writes a map to the provided Writer. +// The writeKey and writeVal parameters specify the functions +// to use to write each key and value of the map. +func WriteMap[K comparable, V any](w *Writer, m map[K]V, writeKey func(K) error, writeVal func(V) error) error { + if m == nil { + return w.WriteNil() + } + if uint64(len(m)) > math.MaxUint32 { + return fmt.Errorf("map too large to encode: %d elements", len(m)) + } + + // Write map header + err := w.WriteMapHeader(uint32(len(m))) + if err != nil { + return err + } + // Write elements + for k, v := range m { + err = writeKey(k) + if err != nil { + return err + } + err = writeVal(v) + if err != nil { + return err + } + } + return nil +} + +// WriteMapSorted writes a map to the provided Writer. +// The keys of the map are sorted before writing. +// This provides deterministic output, but will allocate to sort the keys. +// The writeKey and writeVal parameters specify the functions +// to use to write each key and value of the map. +func WriteMapSorted[K cmp.Ordered, V any](w *Writer, m map[K]V, writeKey func(K) error, writeVal func(V) error) error { + if m == nil { + return w.WriteNil() + } + if uint64(len(m)) > math.MaxUint32 { + return fmt.Errorf("map too large to encode: %d elements", len(m)) + } + + // Write map header + err := w.WriteMapHeader(uint32(len(m))) + if err != nil { + return err + } + // Write elements + for _, k := range slices.Sorted(maps.Keys(m)) { + err = writeKey(k) + if err != nil { + return err + } + err = writeVal(m[k]) + if err != nil { + return err + } + } + return nil +} + +// ReadArrayBytes returns an iterator that can be used to iterate over the elements +// of an array in the MessagePack data while being read by the provided Reader. +// The type parameter V specifies the type of the elements in the array. +// After the iterator is exhausted, the remaining bytes in the buffer +// and any error can be read by calling the returned function. +func ReadArrayBytes[T any](b []byte, readFn func([]byte) (T, []byte, error)) (iter.Seq[T], func() (remain []byte, err error)) { + if IsNil(b) { + b, err := ReadNilBytes(b) + return func(yield func(T) bool) {}, func() ([]byte, error) { return b, err } + } + sz, b, err := ReadArrayHeaderBytes(b) + if err != nil || sz == 0 { + return func(yield func(T) bool) {}, func() ([]byte, error) { return b, err } + } + return func(yield func(T) bool) { + for range sz { + var v T + v, b, err = readFn(b) + if err != nil || !yield(v) { + return + } + } + }, func() ([]byte, error) { + return b, err + } +} + +// AppendArray writes an array to the provided buffer. +// The writeFn parameter specifies the function to use to write each element of the array. +// The returned buffer contains the encoded array. +// The function panics if the array is larger than math.MaxUint32 elements. +func AppendArray[T any](b []byte, a []T, writeFn func(b []byte, v T) []byte) []byte { + if a == nil { + return AppendNil(b) + } + if uint64(len(a)) > math.MaxUint32 { + panic(fmt.Sprintf("array too large to encode: %d elements", len(a))) + } + b = AppendArrayHeader(b, uint32(len(a))) + for _, v := range a { + b = writeFn(b, v) + } + return b +} + +// ReadMapBytes returns an iterator over key/value +// pairs from a MessagePack map encoded in b. +// The iterator yields K,V pairs, and this function also returns +// a closure to get the remaining bytes and any error. +func ReadMapBytes[K any, V any](b []byte, + readK func([]byte) (K, []byte, error), + readV func([]byte) (V, []byte, error)) (iter.Seq2[K, V], func() (remain []byte, err error)) { + var err error + var sz uint32 + if IsNil(b) { + b, err = ReadNilBytes(b) + return func(yield func(K, V) bool) {}, func() ([]byte, error) { return b, err } + } + sz, b, err = ReadMapHeaderBytes(b) + if err != nil || sz == 0 { + return func(yield func(K, V) bool) {}, func() ([]byte, error) { return b, err } + } + + return func(yield func(K, V) bool) { + for range sz { + var k K + k, b, err = readK(b) + if err != nil { + err = fmt.Errorf("cannot read map key: %w", err) + return + } + var v V + v, b, err = readV(b) + if err != nil { + err = fmt.Errorf("cannot read map value: %w", err) + return + } + if !yield(k, v) { + return + } + } + }, func() ([]byte, error) { return b, err } +} + +// AppendMap writes a map to the provided buffer. +// The writeK and writeV parameters specify the functions to use to write each key and value of the map. +// The returned buffer contains the encoded map. +// The function panics if the map is larger than math.MaxUint32 elements. +func AppendMap[K comparable, V any](b []byte, m map[K]V, + writeK func(b []byte, k K) []byte, + writeV func(b []byte, v V) []byte) []byte { + if m == nil { + return AppendNil(b) + } + if uint64(len(m)) > math.MaxUint32 { + panic(fmt.Sprintf("map too large to encode: %d elements", len(m))) + } + b = AppendMapHeader(b, uint32(len(m))) + for k, v := range m { + b = writeK(b, k) + b = writeV(b, v) + } + return b +} + +// AppendMapSorted writes a map to the provided buffer. +// Keys are sorted before writing. +// This provides deterministic output, but will allocate to sort the keys. +// The writeK and writeV parameters specify the functions to use to write each key and value of the map. +// The returned buffer contains the encoded map. +// The function panics if the map is larger than math.MaxUint32 elements. +func AppendMapSorted[K cmp.Ordered, V any](b []byte, m map[K]V, + writeK func(b []byte, k K) []byte, + writeV func(b []byte, v V) []byte) []byte { + if m == nil { + return AppendNil(b) + } + if uint64(len(m)) > math.MaxUint32 { + panic(fmt.Sprintf("map too large to encode: %d elements", len(m))) + } + b = AppendMapHeader(b, uint32(len(m))) + for _, k := range slices.Sorted(maps.Keys(m)) { + b = writeK(b, k) + b = writeV(b, m[k]) + } + return b +} + +// DecodePtr is a convenience type for decoding into a pointer. +type DecodePtr[T any] interface { + *T + Decodable +} + +// DecoderFrom allows augmenting any type with a DecodeMsg method into a method +// that reads from Reader and returns a T. +// Provide an instance of T. This value isn't used. +// See ReadArray/ReadMap "struct" examples for usage. +func DecoderFrom[T any, PT DecodePtr[T]](r *Reader, _ T) func() (T, error) { + return func() (T, error) { + var t T + tPtr := PT(&t) + err := tPtr.DecodeMsg(r) + return t, err + } +} + +// FlexibleEncoder is a constraint for types where either T or *T implements Encodable +type FlexibleEncoder[T any] interface { + Encodable + *T +} + +// EncoderTo allows augmenting any type with an EncodeMsg +// method into a method that writes to Writer on each call. +// Provide an instance of T. This value isn't used. +// See ReadArray or ReadMap "struct" examples for usage. +func EncoderTo[T any, _ FlexibleEncoder[T]](w *Writer, _ T) func(T) error { + return func(t T) error { + // Check if T implements Marshaler + if marshaler, ok := any(t).(Encodable); ok { + return marshaler.EncodeMsg(w) + } + // Check if *T implements Marshaler + if ptrMarshaler, ok := any(&t).(Encodable); ok { + return ptrMarshaler.EncodeMsg(w) + } + // The compiler should have asserted this. + panic("type does not implement Marshaler") + } +} + +// UnmarshalPtr is a convenience type for unmarshaling into a pointer. +type UnmarshalPtr[T any] interface { + *T + Unmarshaler +} + +// DecoderFromBytes allows augmenting any type with an UnmarshalMsg +// method into a method that reads from []byte and returns a T. +// Provide an instance of T. This value isn't used. +// See ReadArrayBytes or ReadMapBytes "struct" examples for usage. +func DecoderFromBytes[T any, PT UnmarshalPtr[T]](_ T) func([]byte) (T, []byte, error) { + return func(b []byte) (T, []byte, error) { + var t T + tPtr := PT(&t) + b, err := tPtr.UnmarshalMsg(b) + return t, b, err + } +} + +// FlexibleMarshaler is a constraint for types where either T or *T implements Marshaler +type FlexibleMarshaler[T any] interface { + Marshaler + *T // Include *T in the interface +} + +// EncoderToBytes allows augmenting any type with a MarshalMsg method into a method +// that reads from T and returns a []byte. +// Provide an instance of T. This value isn't used. +// See ReadArrayBytes or ReadMapBytes "struct" examples for usage. +func EncoderToBytes[T any, _ FlexibleMarshaler[T]](_ T) func([]byte, T) []byte { + return func(b []byte, t T) []byte { + // Check if T implements Marshaler + if marshaler, ok := any(t).(Marshaler); ok { + b, _ = marshaler.MarshalMsg(b) + return b + } + // Check if *T implements Marshaler + if ptrMarshaler, ok := any(&t).(Marshaler); ok { + b, _ = ptrMarshaler.MarshalMsg(b) + return b + } + // The compiler should have asserted this. + panic("type does not implement Marshaler") + } +} diff --git a/vendor/github.com/tinylib/msgp/msgp/json.go b/vendor/github.com/tinylib/msgp/msgp/json.go index e5c450b51..896d690ba 100644 --- a/vendor/github.com/tinylib/msgp/msgp/json.go +++ b/vendor/github.com/tinylib/msgp/msgp/json.go @@ -364,7 +364,7 @@ func rwString(dst jsWriter, src *Reader) (n int, err error) { if err != nil { return } - read = int(uint8(p[1])) + read = int(p[1]) case mstr16: p, err = src.R.Next(3) if err != nil { diff --git a/vendor/github.com/tinylib/msgp/msgp/json_bytes.go b/vendor/github.com/tinylib/msgp/msgp/json_bytes.go index d4fbda631..7efd162f1 100644 --- a/vendor/github.com/tinylib/msgp/msgp/json_bytes.go +++ b/vendor/github.com/tinylib/msgp/msgp/json_bytes.go @@ -91,7 +91,7 @@ func rwArrayBytes(w jsWriter, msg []byte, scratch []byte, depth int) ([]byte, [] if err != nil { return msg, scratch, err } - for i := uint32(0); i < sz; i++ { + for i := range sz { if i != 0 { err = w.WriteByte(',') if err != nil { @@ -119,7 +119,7 @@ func rwMapBytes(w jsWriter, msg []byte, scratch []byte, depth int) ([]byte, []by if err != nil { return msg, scratch, err } - for i := uint32(0); i < sz; i++ { + for i := range sz { if i != 0 { err = w.WriteByte(',') if err != nil { diff --git a/vendor/github.com/tinylib/msgp/msgp/number.go b/vendor/github.com/tinylib/msgp/msgp/number.go index edfe328b4..0bd3f3196 100644 --- a/vendor/github.com/tinylib/msgp/msgp/number.go +++ b/vendor/github.com/tinylib/msgp/msgp/number.go @@ -2,6 +2,7 @@ package msgp import ( "math" + "math/bits" "strconv" ) @@ -77,7 +78,7 @@ func (n *Number) Uint() (uint64, bool) { } // Float casts the number to a float64, and -// returns whether or not that was the underlying +// returns whether that was the underlying // type (either a float64 or a float32). func (n *Number) Float() (float64, bool) { switch n.typ { @@ -182,7 +183,7 @@ func (n *Number) MarshalMsg(b []byte) ([]byte, error) { case IntType: return AppendInt64(b, int64(n.bits)), nil case UintType: - return AppendUint64(b, uint64(n.bits)), nil + return AppendUint64(b, n.bits), nil case Float64Type: return AppendFloat64(b, math.Float64frombits(n.bits)), nil case Float32Type: @@ -208,6 +209,129 @@ func (n *Number) EncodeMsg(w *Writer) error { } } +// CoerceInt attempts to coerce the value of +// the number into a signed integer and returns +// whether it was successful. +// "Success" implies that no precision in the value of +// the number was lost, which means that the number was an integer or +// a floating point that mapped exactly to an integer without rounding. +func (n *Number) CoerceInt() (int64, bool) { + switch n.typ { + case InvalidType, IntType: + // InvalidType just means un-initialized. + return int64(n.bits), true + case UintType: + return int64(n.bits), n.bits <= math.MaxInt64 + case Float32Type: + f := math.Float32frombits(uint32(n.bits)) + if n.isExactInt() && f <= math.MaxInt64 && f >= math.MinInt64 { + return int64(f), true + } + if n.bits == 0 || n.bits == 1<<31 { + return 0, true + } + case Float64Type: + f := math.Float64frombits(n.bits) + if n.isExactInt() && f <= math.MaxInt64 && f >= math.MinInt64 { + return int64(f), true + } + return 0, n.bits == 0 || n.bits == 1<<63 + } + return 0, false +} + +// CoerceUInt attempts to coerce the value of +// the number into an unsigned integer and returns +// whether it was successful. +// "Success" implies that no precision in the value of +// the number was lost, which means that the number was an integer or +// a floating point that mapped exactly to an integer without rounding. +func (n *Number) CoerceUInt() (uint64, bool) { + switch n.typ { + case InvalidType, IntType: + // InvalidType just means un-initialized. + if int64(n.bits) >= 0 { + return n.bits, true + } + case UintType: + return n.bits, true + case Float32Type: + f := math.Float32frombits(uint32(n.bits)) + if f >= 0 && f <= math.MaxUint64 && n.isExactInt() { + return uint64(f), true + } + if n.bits == 0 || n.bits == 1<<31 { + return 0, true + } + case Float64Type: + f := math.Float64frombits(n.bits) + if f >= 0 && f <= math.MaxUint64 && n.isExactInt() { + return uint64(f), true + } + return 0, n.bits == 0 || n.bits == 1<<63 + } + return 0, false +} + +// isExactInt will return true if the number represents an integer value. +// NaN, Inf returns false. +func (n *Number) isExactInt() bool { + var eBits int // Exponent bits + var mBits int // Mantissa bits + + switch n.typ { + case InvalidType, IntType, UintType: + return true + case Float32Type: + eBits = 8 + mBits = 23 + case Float64Type: + eBits = 11 + mBits = 52 + default: + return false + } + // Calculate float parts + exp := int(n.bits>>mBits) & ((1 << eBits) - 1) + mant := n.bits & ((1 << mBits) - 1) + if exp == 0 && mant == 0 { + // Handle zero value. + return true + } + + exp -= (1 << (eBits - 1)) - 1 + if exp < 0 || exp == 1<<(eBits-1) { + // Negative exponent is never integer (except zero handled above) + // Handles NaN (exp all 1s) + return false + } + + if exp >= mBits { + // If we have more exponent than mantissa bits it is always an integer. + return true + } + // Check if all bits below the exponent are zero. + return bits.TrailingZeros64(mant) >= mBits-exp +} + +// CoerceFloat returns the number as a float64. +// If the number is an integer, it will be +// converted to a float64 with the closest representation. +func (n *Number) CoerceFloat() float64 { + switch n.typ { + case IntType: + return float64(int64(n.bits)) + case UintType: + return float64(n.bits) + case Float32Type: + return float64(math.Float32frombits(uint32(n.bits))) + case Float64Type: + return math.Float64frombits(n.bits) + default: + return 0.0 + } +} + // Msgsize implements msgp.Sizer func (n *Number) Msgsize() int { switch n.typ { diff --git a/vendor/github.com/tinylib/msgp/msgp/purego.go b/vendor/github.com/tinylib/msgp/msgp/purego.go index fe8723412..03525aca5 100644 --- a/vendor/github.com/tinylib/msgp/msgp/purego.go +++ b/vendor/github.com/tinylib/msgp/msgp/purego.go @@ -1,5 +1,4 @@ //go:build (purego && !unsafe) || appengine -// +build purego,!unsafe appengine package msgp diff --git a/vendor/github.com/tinylib/msgp/msgp/read.go b/vendor/github.com/tinylib/msgp/msgp/read.go index 409dbcec5..264933ad0 100644 --- a/vendor/github.com/tinylib/msgp/msgp/read.go +++ b/vendor/github.com/tinylib/msgp/msgp/read.go @@ -1,8 +1,10 @@ package msgp import ( + "encoding" "encoding/binary" "encoding/json" + "fmt" "io" "math" "strconv" @@ -13,7 +15,7 @@ import ( ) // where we keep old *Readers -var readerPool = sync.Pool{New: func() interface{} { return &Reader{} }} +var readerPool = sync.Pool{New: func() any { return &Reader{} }} // Type is a MessagePack wire type, // including this package's built-in @@ -175,7 +177,7 @@ func (m *Reader) CopyNext(w io.Writer) (int64, error) { // Opportunistic optimization: if we can fit the whole thing in the m.R // buffer, then just get a pointer to that, and pass it to w.Write, // avoiding an allocation. - if int(sz) <= m.R.BufferSize() { + if int(sz) >= 0 && int(sz) <= m.R.BufferSize() { var nn int var buf []byte buf, err = m.R.Next(int(sz)) @@ -207,7 +209,7 @@ func (m *Reader) CopyNext(w io.Writer) (int64, error) { defer done() } // for maps and slices, read elements - for x := uintptr(0); x < o; x++ { + for range o { var n2 int64 n2, err = m.CopyNext(w) if err != nil { @@ -582,7 +584,7 @@ func (m *Reader) ReadFloat64() (f float64, err error) { var p []byte p, err = m.R.Peek(9) if err != nil { - // we'll allow a coversion from float32 to float64, + // we'll allow a conversion from float32 to float64, // since we don't lose any precision if err == io.EOF && len(p) > 0 && p[0] == mfloat32 { ef, err := m.ReadFloat32() @@ -870,7 +872,7 @@ func (m *Reader) ReadUint64() (u uint64, err error) { if err != nil { return } - v := int64(getMint64(p)) + v := getMint64(p) if v < 0 { err = UintBelowZero{Value: v} return @@ -1038,7 +1040,7 @@ func (m *Reader) ReadBytesHeader() (sz uint32, err error) { if err != nil { return } - sz = uint32(big.Uint32(p[1:])) + sz = big.Uint32(p[1:]) return default: err = badPrefix(BinType, lead) @@ -1110,7 +1112,7 @@ func (m *Reader) ReadStringAsBytes(scratch []byte) (b []byte, err error) { if err != nil { return } - read = int64(uint8(p[1])) + read = int64(p[1]) case mstr16: p, err = m.R.Next(3) if err != nil { @@ -1205,7 +1207,7 @@ func (m *Reader) ReadString() (s string, err error) { if err != nil { return } - read = int64(uint8(p[1])) + read = int64(p[1]) case mstr16: p, err = m.R.Next(3) if err != nil { @@ -1302,7 +1304,7 @@ func (m *Reader) ReadComplex128() (f complex128, err error) { // ReadMapStrIntf reads a MessagePack map into a map[string]interface{}. // (You must pass a non-nil map into the function.) -func (m *Reader) ReadMapStrIntf(mp map[string]interface{}) (err error) { +func (m *Reader) ReadMapStrIntf(mp map[string]any) (err error) { var sz uint32 sz, err = m.ReadMapHeader() if err != nil { @@ -1317,7 +1319,7 @@ func (m *Reader) ReadMapStrIntf(mp map[string]interface{}) (err error) { } for i := uint32(0); i < sz; i++ { var key string - var val interface{} + var val any key, err = m.ReadString() if err != nil { return @@ -1447,7 +1449,7 @@ func (m *Reader) ReadJSONNumber() (n json.Number, err error) { // Arrays are decoded as []interface{}, and maps are decoded // as map[string]interface{}. Integers are decoded as int64 // and unsigned integers are decoded as uint64. -func (m *Reader) ReadIntf() (i interface{}, err error) { +func (m *Reader) ReadIntf() (i any, err error) { var t Type t, err = m.NextType() if err != nil { @@ -1517,7 +1519,7 @@ func (m *Reader) ReadIntf() (i interface{}, err error) { defer done() } - mp := make(map[string]interface{}) + mp := make(map[string]any) err = m.ReadMapStrIntf(mp) i = mp return @@ -1553,7 +1555,7 @@ func (m *Reader) ReadIntf() (i interface{}, err error) { return } - out := make([]interface{}, int(sz)) + out := make([]any, int(sz)) for j := range out { out[j], err = m.ReadIntf() if err != nil { @@ -1567,3 +1569,51 @@ func (m *Reader) ReadIntf() (i interface{}, err error) { return nil, fatal // unreachable } } + +// ReadBinaryUnmarshal reads a binary-encoded object from the reader and unmarshals it into dst. +func (m *Reader) ReadBinaryUnmarshal(dst encoding.BinaryUnmarshaler) (err error) { + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("msgp: panic during UnmarshalBinary: %v", r) + } + }() + tmp := bytesPool.Get().([]byte) + defer bytesPool.Put(tmp) //nolint:staticcheck + tmp, err = m.ReadBytes(tmp[:0]) + if err != nil { + return + } + return dst.UnmarshalBinary(tmp) +} + +// ReadTextUnmarshal reads a text-encoded bin array from the reader and unmarshals it into dst. +func (m *Reader) ReadTextUnmarshal(dst encoding.TextUnmarshaler) (err error) { + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("msgp: panic during UnmarshalText: %v", r) + } + }() + tmp := bytesPool.Get().([]byte) + defer bytesPool.Put(tmp) //nolint:staticcheck + tmp, err = m.ReadBytes(tmp[:0]) + if err != nil { + return + } + return dst.UnmarshalText(tmp) +} + +// ReadTextUnmarshalString reads a text-encoded string from the reader and unmarshals it into dst. +func (m *Reader) ReadTextUnmarshalString(dst encoding.TextUnmarshaler) (err error) { + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("msgp: panic during UnmarshalText: %v", r) + } + }() + tmp := bytesPool.Get().([]byte) + defer bytesPool.Put(tmp) //nolint:staticcheck + tmp, err = m.ReadStringAsBytes(tmp[:0]) + if err != nil { + return + } + return dst.UnmarshalText(tmp) +} diff --git a/vendor/github.com/tinylib/msgp/msgp/read_bytes.go b/vendor/github.com/tinylib/msgp/msgp/read_bytes.go index 176e14e3f..3d439a215 100644 --- a/vendor/github.com/tinylib/msgp/msgp/read_bytes.go +++ b/vendor/github.com/tinylib/msgp/msgp/read_bytes.go @@ -1138,11 +1138,11 @@ func ReadTimeBytes(b []byte) (t time.Time, o []byte, err error) { // ReadMapStrIntfBytes reads a map[string]interface{} // out of 'b' and returns the map and remaining bytes. // If 'old' is non-nil, the values will be read into that map. -func ReadMapStrIntfBytes(b []byte, old map[string]interface{}) (v map[string]interface{}, o []byte, err error) { +func ReadMapStrIntfBytes(b []byte, old map[string]any) (v map[string]any, o []byte, err error) { return readMapStrIntfBytesDepth(b, old, 0) } -func readMapStrIntfBytesDepth(b []byte, old map[string]interface{}, depth int) (v map[string]interface{}, o []byte, err error) { +func readMapStrIntfBytesDepth(b []byte, old map[string]any, depth int) (v map[string]any, o []byte, err error) { if depth >= recursionLimit { err = ErrRecursion return @@ -1166,7 +1166,7 @@ func readMapStrIntfBytesDepth(b []byte, old map[string]interface{}, depth int) ( } v = old } else { - v = make(map[string]interface{}, int(sz)) + v = make(map[string]any, int(sz)) } for z := uint32(0); z < sz; z++ { @@ -1179,7 +1179,7 @@ func readMapStrIntfBytesDepth(b []byte, old map[string]interface{}, depth int) ( if err != nil { return } - var val interface{} + var val any val, o, err = readIntfBytesDepth(o, depth) if err != nil { return @@ -1192,11 +1192,11 @@ func readMapStrIntfBytesDepth(b []byte, old map[string]interface{}, depth int) ( // ReadIntfBytes attempts to read // the next object out of 'b' as a raw interface{} and // return the remaining bytes. -func ReadIntfBytes(b []byte) (i interface{}, o []byte, err error) { +func ReadIntfBytes(b []byte) (i any, o []byte, err error) { return readIntfBytesDepth(b, 0) } -func readIntfBytesDepth(b []byte, depth int) (i interface{}, o []byte, err error) { +func readIntfBytesDepth(b []byte, depth int) (i any, o []byte, err error) { if depth >= recursionLimit { err = ErrRecursion return @@ -1224,7 +1224,7 @@ func readIntfBytesDepth(b []byte, depth int) (i interface{}, o []byte, err error err = ErrShortBytes return } - j := make([]interface{}, int(sz)) + j := make([]any, int(sz)) i = j for d := range j { j[d], o, err = readIntfBytesDepth(o, depth+1) @@ -1283,7 +1283,7 @@ func readIntfBytesDepth(b []byte, depth int) (i interface{}, o []byte, err error } // last resort is a raw extension e := RawExtension{} - e.Type = int8(t) + e.Type = t o, err = ReadExtensionBytes(b, &e) i = &e return diff --git a/vendor/github.com/tinylib/msgp/msgp/size.go b/vendor/github.com/tinylib/msgp/msgp/size.go index 585a67fdb..b81b94e69 100644 --- a/vendor/github.com/tinylib/msgp/msgp/size.go +++ b/vendor/github.com/tinylib/msgp/msgp/size.go @@ -37,4 +37,13 @@ const ( BytesPrefixSize = 5 StringPrefixSize = 5 ExtensionPrefixSize = 6 + + // We cannot determine the exact size of the marshalled bytes, + // so we assume 32 bytes + BinaryMarshalerSize = BytesPrefixSize + 32 + BinaryAppenderSize + TextMarshalerBinSize + TextAppenderBinSize + TextMarshalerStringSize = StringPrefixSize + 32 + TextAppenderStringSize ) diff --git a/vendor/github.com/tinylib/msgp/msgp/unsafe.go b/vendor/github.com/tinylib/msgp/msgp/unsafe.go index 7d36bfb1e..3a83eacda 100644 --- a/vendor/github.com/tinylib/msgp/msgp/unsafe.go +++ b/vendor/github.com/tinylib/msgp/msgp/unsafe.go @@ -1,5 +1,4 @@ //go:build (!purego && !appengine) || (!appengine && purego && unsafe) -// +build !purego,!appengine !appengine,purego,unsafe package msgp diff --git a/vendor/github.com/tinylib/msgp/msgp/write.go b/vendor/github.com/tinylib/msgp/msgp/write.go index 352350f90..55192222c 100644 --- a/vendor/github.com/tinylib/msgp/msgp/write.go +++ b/vendor/github.com/tinylib/msgp/msgp/write.go @@ -1,9 +1,11 @@ package msgp import ( + "encoding" "encoding/binary" "encoding/json" "errors" + "fmt" "io" "math" "reflect" @@ -33,7 +35,7 @@ var ( btsType = reflect.TypeOf(([]byte)(nil)) writerPool = sync.Pool{ - New: func() interface{} { + New: func() any { return &Writer{buf: make([]byte, 2048)} }, } @@ -430,7 +432,7 @@ func (mw *Writer) WriteUint64(u uint64) error { } // WriteByte is analogous to WriteUint8 -func (mw *Writer) WriteByte(u byte) error { return mw.WriteUint8(uint8(u)) } +func (mw *Writer) WriteByte(u byte) error { return mw.WriteUint8(u) } // WriteUint8 writes a uint8 to the writer func (mw *Writer) WriteUint8(u uint8) error { return mw.WriteUint64(uint64(u)) } @@ -446,6 +448,9 @@ func (mw *Writer) WriteUint(u uint) error { return mw.WriteUint64(uint64(u)) } // WriteBytes writes binary as 'bin' to the writer func (mw *Writer) WriteBytes(b []byte) error { + if uint64(len(b)) > math.MaxUint32 { + return ErrLimitExceeded + } sz := uint32(len(b)) var err error switch { @@ -488,6 +493,10 @@ func (mw *Writer) WriteBool(b bool) error { // WriteString writes a messagepack string to the writer. // (This is NOT an implementation of io.StringWriter) func (mw *Writer) WriteString(s string) error { + if uint64(len(s)) > math.MaxUint32 { + return ErrLimitExceeded + } + sz := uint32(len(s)) var err error switch { @@ -526,6 +535,9 @@ func (mw *Writer) WriteStringHeader(sz uint32) error { // WriteStringFromBytes writes a 'str' object // from a []byte. func (mw *Writer) WriteStringFromBytes(str []byte) error { + if uint64(len(str)) > math.MaxUint32 { + return ErrLimitExceeded + } sz := uint32(len(str)) var err error switch { @@ -591,7 +603,7 @@ func (mw *Writer) WriteMapStrStr(mp map[string]string) (err error) { } // WriteMapStrIntf writes a map[string]interface to the writer -func (mw *Writer) WriteMapStrIntf(mp map[string]interface{}) (err error) { +func (mw *Writer) WriteMapStrIntf(mp map[string]any) (err error) { err = mw.WriteMapHeader(uint32(len(mp))) if err != nil { return @@ -703,7 +715,7 @@ func (mw *Writer) WriteJSONNumber(n json.Number) error { // - A pointer to a supported type // - A type that satisfies the msgp.Encodable interface // - A type that satisfies the msgp.Extension interface -func (mw *Writer) WriteIntf(v interface{}) error { +func (mw *Writer) WriteIntf(v any) error { if v == nil { return mw.WriteNil() } @@ -754,7 +766,7 @@ func (mw *Writer) WriteIntf(v interface{}) error { return mw.WriteBytes(v) case map[string]string: return mw.WriteMapStrStr(v) - case map[string]interface{}: + case map[string]any: return mw.WriteMapStrIntf(v) case time.Time: return mw.WriteTime(v) @@ -817,7 +829,7 @@ func (mw *Writer) writeSlice(v reflect.Value) (err error) { if err != nil { return } - for i := uint32(0); i < sz; i++ { + for i := range sz { err = mw.WriteIntf(v.Index(int(i)).Interface()) if err != nil { return @@ -840,7 +852,7 @@ func isSupported(k reflect.Kind) bool { // value of 'i'. If the underlying value is not // a simple builtin (or []byte), GuessSize defaults // to 512. -func GuessSize(i interface{}) int { +func GuessSize(i any) int { if i == nil { return NilSize } @@ -868,7 +880,7 @@ func GuessSize(i interface{}) int { return Complex128Size case bool: return BoolSize - case map[string]interface{}: + case map[string]any: s := MapHeaderSize for key, val := range i { s += StringPrefixSize + len(key) + GuessSize(val) @@ -884,3 +896,57 @@ func GuessSize(i interface{}) int { return 512 } } + +// Temporary buffer for reading/writing binary data. +var bytesPool = sync.Pool{New: func() any { return make([]byte, 0, 1024) }} + +// WriteBinaryAppender will write the bytes from the given +// encoding.BinaryAppender as a bin array. +func (mw *Writer) WriteBinaryAppender(b encoding.BinaryAppender) (err error) { + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("msgp: panic during AppendBinary: %v", r) + } + }() + dst := bytesPool.Get().([]byte) + defer bytesPool.Put(dst) //nolint:staticcheck + dst, err = b.AppendBinary(dst[:0]) + if err != nil { + return err + } + return mw.WriteBytes(dst) +} + +// WriteTextAppender will write the bytes from the given +// encoding.TextAppender as a bin array. +func (mw *Writer) WriteTextAppender(b encoding.TextAppender) (err error) { + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("msgp: panic during AppendText: %v", r) + } + }() + dst := bytesPool.Get().([]byte) + defer bytesPool.Put(dst) //nolint:staticcheck + dst, err = b.AppendText(dst[:0]) + if err != nil { + return err + } + return mw.WriteBytes(dst) +} + +// WriteTextAppenderString will write the bytes from the given +// encoding.TextAppender as a string. +func (mw *Writer) WriteTextAppenderString(b encoding.TextAppender) (err error) { + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("msgp: panic during AppendText: %v", r) + } + }() + dst := bytesPool.Get().([]byte) + defer bytesPool.Put(dst) //nolint:staticcheck + dst, err = b.AppendText(dst[:0]) + if err != nil { + return err + } + return mw.WriteStringFromBytes(dst) +} diff --git a/vendor/github.com/tinylib/msgp/msgp/write_bytes.go b/vendor/github.com/tinylib/msgp/msgp/write_bytes.go index 704501746..378f14f91 100644 --- a/vendor/github.com/tinylib/msgp/msgp/write_bytes.go +++ b/vendor/github.com/tinylib/msgp/msgp/write_bytes.go @@ -181,7 +181,7 @@ func AppendUint(b []byte, u uint) []byte { return AppendUint64(b, uint64(u)) } func AppendUint8(b []byte, u uint8) []byte { return AppendUint64(b, uint64(u)) } // AppendByte is analogous to AppendUint8 -func AppendByte(b []byte, u byte) []byte { return AppendUint8(b, uint8(u)) } +func AppendByte(b []byte, u byte) []byte { return AppendUint8(b, u) } // AppendUint16 appends a uint16 to the slice func AppendUint16(b []byte, u uint16) []byte { return AppendUint64(b, uint64(u)) } @@ -371,7 +371,7 @@ func AppendMapStrStr(b []byte, m map[string]string) []byte { // AppendMapStrIntf appends a map[string]interface{} to the slice // as a MessagePack map with 'str'-type keys. -func AppendMapStrIntf(b []byte, m map[string]interface{}) ([]byte, error) { +func AppendMapStrIntf(b []byte, m map[string]any) ([]byte, error) { sz := uint32(len(m)) b = AppendMapHeader(b, sz) var err error @@ -394,7 +394,7 @@ func AppendMapStrIntf(b []byte, m map[string]interface{}) ([]byte, error) { // - A *T, where T is another supported type // - A type that satisfies the msgp.Marshaler interface // - A type that satisfies the msgp.Extension interface -func AppendIntf(b []byte, i interface{}) ([]byte, error) { +func AppendIntf(b []byte, i any) ([]byte, error) { if i == nil { return AppendNil(b), nil } @@ -444,13 +444,13 @@ func AppendIntf(b []byte, i interface{}) ([]byte, error) { return AppendTime(b, i), nil case time.Duration: return AppendDuration(b, i), nil - case map[string]interface{}: + case map[string]any: return AppendMapStrIntf(b, i) case map[string]string: return AppendMapStrStr(b, i), nil case json.Number: return AppendJSONNumber(b, i) - case []interface{}: + case []any: b = AppendArrayHeader(b, uint32(len(i))) var err error for _, k := range i { @@ -483,7 +483,7 @@ func AppendIntf(b []byte, i interface{}) ([]byte, error) { case reflect.Array, reflect.Slice: l := v.Len() b = AppendArrayHeader(b, uint32(l)) - for i := 0; i < l; i++ { + for i := range l { b, err = AppendIntf(b, v.Index(i).Interface()) if err != nil { return b, err @@ -518,3 +518,49 @@ func AppendJSONNumber(b []byte, n json.Number) ([]byte, error) { } return b, err } + +// AppendBytesTwoPrefixed will add the length to a bin section written with +// 2 bytes of space saved for a bin8 header. +// If the sz cannot fit inside a bin8, the data will be moved to make space for the header. +func AppendBytesTwoPrefixed(b []byte, sz int) []byte { + off := len(b) - sz - 2 + switch { + case sz <= math.MaxUint8: + // Just write header... + prefixu8(b[off:], mbin8, uint8(sz)) + case sz <= math.MaxUint16: + // Scoot one + b = append(b, 0) + copy(b[off+1:], b[off:]) + prefixu16(b[off:], mbin16, uint16(sz)) + default: + // Scoot three + b = append(b, 0, 0, 0) + copy(b[off+3:], b[off:]) + prefixu32(b[off:], mbin32, uint32(sz)) + } + return b +} + +// AppendBytesStringTwoPrefixed will add the length to a string section written with +// 2 bytes of space saved for a str8 header. +// If the sz cannot fit inside a str8, the data will be moved to make space for the header. +func AppendBytesStringTwoPrefixed(b []byte, sz int) []byte { + off := len(b) - sz - 2 + switch { + case sz <= math.MaxUint8: + // Just write header... + prefixu8(b[off:], mstr8, uint8(sz)) + case sz <= math.MaxUint16: + // Scoot one + b = append(b, 0) + copy(b[off+1:], b[off:]) + prefixu16(b[off:], mstr16, uint16(sz)) + default: + // Scoot three + b = append(b, 0, 0, 0) + copy(b[off+3:], b[off:]) + prefixu32(b[off:], mstr32, uint32(sz)) + } + return b +} diff --git a/vendor/modules.txt b/vendor/modules.txt index aa6f0ffa0..0f21ebbd3 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -181,8 +181,8 @@ github.com/tebeka/strftime # github.com/tevino/abool v1.2.0 ## explicit; go 1.14 github.com/tevino/abool -# github.com/tinylib/msgp v1.4.0 -## explicit; go 1.22 +# github.com/tinylib/msgp v1.6.1 +## explicit; go 1.24 github.com/tinylib/msgp/msgp # github.com/valyala/fastjson v1.6.4 ## explicit; go 1.12