summaryrefslogtreecommitdiff
path: root/vendor/github.com/ugorji/go/codec/decode.base.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/ugorji/go/codec/decode.base.go')
-rw-r--r--vendor/github.com/ugorji/go/codec/decode.base.go944
1 files changed, 0 insertions, 944 deletions
diff --git a/vendor/github.com/ugorji/go/codec/decode.base.go b/vendor/github.com/ugorji/go/codec/decode.base.go
deleted file mode 100644
index e82f40252..000000000
--- a/vendor/github.com/ugorji/go/codec/decode.base.go
+++ /dev/null
@@ -1,944 +0,0 @@
-// 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.
-
-package codec
-
-import (
- "errors"
- "io"
- "math"
- "reflect"
- "slices"
- "sync"
- "time"
-)
-
-func init() {
- for _, v := range []interface{}{
- (*string)(nil),
- (*bool)(nil),
- (*int)(nil),
- (*int8)(nil),
- (*int16)(nil),
- (*int32)(nil),
- (*int64)(nil),
- (*uint)(nil),
- (*uint8)(nil),
- (*uint16)(nil),
- (*uint32)(nil),
- (*uint64)(nil),
- (*uintptr)(nil),
- (*float32)(nil),
- (*float64)(nil),
- (*complex64)(nil),
- (*complex128)(nil),
- (*[]byte)(nil),
- ([]byte)(nil),
- (*time.Time)(nil),
- (*Raw)(nil),
- (*interface{})(nil),
- } {
- decBuiltinRtids = append(decBuiltinRtids, i2rtid(v))
- }
- slices.Sort(decBuiltinRtids)
-}
-
-const msgBadDesc = "unrecognized descriptor byte"
-
-var decBuiltinRtids []uintptr
-
-// decDriver calls (DecodeBytes and DecodeStringAsBytes) return a state
-// of the view they return, allowing consumers to handle appropriately.
-//
-// sequencing of this is intentional:
-// - mutable if <= dBytesAttachBuffer (buf | view | invalid)
-// - noCopy if >= dBytesAttachViewZerocopy
-type dBytesAttachState uint8
-
-const (
- dBytesAttachInvalid dBytesAttachState = iota
- dBytesAttachView // (bytes && !zerocopy && !buf)
- dBytesAttachBuffer // (buf)
- dBytesAttachViewZerocopy // (bytes && zerocopy && !buf)
- dBytesDetach // (!bytes && !buf)
-)
-
-type dBytesIntoState uint8
-
-const (
- dBytesIntoNoChange dBytesIntoState = iota
- dBytesIntoParamOut
- dBytesIntoParamOutSlice
- dBytesIntoNew
-)
-
-func (x dBytesAttachState) String() string {
- switch x {
- case dBytesAttachInvalid:
- return "invalid"
- case dBytesAttachView:
- return "view"
- case dBytesAttachBuffer:
- return "buffer"
- case dBytesAttachViewZerocopy:
- return "view-zerocopy"
- case dBytesDetach:
- return "detach"
- }
- return "unknown"
-}
-
-const (
- decDefMaxDepth = 1024 // maximum depth
- decDefChanCap = 64 // should be large, as cap cannot be expanded
- decScratchByteArrayLen = (4 + 3) * 8 // around cacheLineSize ie ~64, depending on Decoder size
-
- // MARKER: massage decScratchByteArrayLen to ensure xxxDecDriver structs fit within cacheLine*N
-
- // decFailNonEmptyIntf configures whether we error
- // when decoding naked into a non-empty interface.
- //
- // Typically, we cannot decode non-nil stream value into
- // nil interface with methods (e.g. io.Reader).
- // However, in some scenarios, this should be allowed:
- // - MapType
- // - SliceType
- // - Extensions
- //
- // Consequently, we should relax this. Put it behind a const flag for now.
- decFailNonEmptyIntf = false
-
- // decUseTransient says whether we should use the transient optimization.
- //
- // There's potential for GC corruption or memory overwrites if transient isn't
- // used carefully, so this flag helps turn it off quickly if needed.
- //
- // Use it everywhere needed so we can completely remove unused code blocks.
- decUseTransient = true
-)
-
-var (
- errNeedMapOrArrayDecodeToStruct = errors.New("only encoded map or array can decode into struct")
- errCannotDecodeIntoNil = errors.New("cannot decode into nil")
-
- errExpandSliceCannotChange = errors.New("expand slice: cannot change")
-
- errDecoderNotInitialized = errors.New("Decoder not initialized")
-
- errDecUnreadByteNothingToRead = errors.New("cannot unread - nothing has been read")
- errDecUnreadByteLastByteNotRead = errors.New("cannot unread - last byte has not been read")
- errDecUnreadByteUnknown = errors.New("cannot unread - reason unknown")
- errMaxDepthExceeded = errors.New("maximum decoding depth exceeded")
-)
-
-type decNotDecodeableReason uint8
-
-const (
- decNotDecodeableReasonUnknown decNotDecodeableReason = iota
- decNotDecodeableReasonBadKind
- decNotDecodeableReasonNonAddrValue
- decNotDecodeableReasonNilReference
-)
-
-type decDriverI interface {
-
- // this will check if the next token is a break.
- CheckBreak() bool
-
- // TryNil tries to decode as nil.
- // If a nil is in the stream, it consumes it and returns true.
- //
- // Note: if TryNil returns true, that must be handled.
- TryNil() bool
-
- // ContainerType returns one of: Bytes, String, Nil, Slice or Map.
- //
- // Return unSet if not known.
- //
- // Note: Implementations MUST fully consume sentinel container types, specifically Nil.
- ContainerType() (vt valueType)
-
- // DecodeNaked will decode primitives (number, bool, string, []byte) and RawExt.
- // For maps and arrays, it will not do the decoding in-band, but will signal
- // the decoder, so that is done later, by setting the fauxUnion.valueType field.
- //
- // Note: Numbers are decoded as int64, uint64, float64 only (no smaller sized number types).
- // for extensions, DecodeNaked must read the tag and the []byte if it exists.
- // if the []byte is not read, then kInterfaceNaked will treat it as a Handle
- // that stores the subsequent value in-band, and complete reading the RawExt.
- //
- // extensions should also use readx to decode them, for efficiency.
- // kInterface will extract the detached byte slice if it has to pass it outside its realm.
- DecodeNaked()
-
- DecodeInt64() (i int64)
- DecodeUint64() (ui uint64)
-
- DecodeFloat32() (f float32)
- DecodeFloat64() (f float64)
-
- DecodeBool() (b bool)
-
- // DecodeStringAsBytes returns the bytes representing a string.
- // It will return a view into scratch buffer or input []byte (if applicable).
- //
- // Note: This can also decode symbols, if supported.
- //
- // Users should consume it right away and not store it for later use.
- DecodeStringAsBytes() (v []byte, state dBytesAttachState)
-
- // DecodeBytes returns the bytes representing a binary value.
- // It will return a view into scratch buffer or input []byte (if applicable).
- DecodeBytes() (out []byte, state dBytesAttachState)
- // DecodeBytes(bs []byte, isstring, zerocopy bool) (bsOut []byte)
-
- // DecodeExt will decode into an extension.
- // ext is never nil.
- DecodeExt(v interface{}, basetype reflect.Type, xtag uint64, ext Ext)
- // decodeExt(verifyTag bool, tag byte) (xtag byte, xbs []byte)
-
- // DecodeRawExt will decode into a *RawExt
- DecodeRawExt(re *RawExt)
-
- DecodeTime() (t time.Time)
-
- // ReadArrayStart will return the length of the array.
- // If the format doesn't prefix the length, it returns containerLenUnknown.
- // If the expected array was a nil in the stream, it returns containerLenNil.
- ReadArrayStart() int
-
- // ReadMapStart will return the length of the array.
- // If the format doesn't prefix the length, it returns containerLenUnknown.
- // If the expected array was a nil in the stream, it returns containerLenNil.
- ReadMapStart() int
-
- decDriverContainerTracker
-
- reset()
-
- // atEndOfDecode()
-
- // nextValueBytes will return the bytes representing the next value in the stream.
- // It generally will include the last byte read, as that is a part of the next value
- // in the stream.
- nextValueBytes() []byte
-
- // descBd will describe the token descriptor that signifies what type was decoded
- descBd() string
-
- // isBytes() bool
-
- resetInBytes(in []byte)
- resetInIO(r io.Reader)
-
- NumBytesRead() int
-
- init(h Handle, shared *decoderBase, dec decoderI) (fp interface{})
-
- // driverStateManager
- decNegintPosintFloatNumber
-}
-
-type decInit2er struct{}
-
-func (decInit2er) init2(dec decoderI) {}
-
-type decDriverContainerTracker interface {
- ReadArrayElem(firstTime bool)
- ReadMapElemKey(firstTime bool)
- ReadMapElemValue()
- ReadArrayEnd()
- ReadMapEnd()
-}
-
-type decNegintPosintFloatNumber interface {
- decInteger() (ui uint64, neg, ok bool)
- decFloat() (f float64, ok bool)
-}
-
-type decDriverNoopNumberHelper struct{}
-
-func (x decDriverNoopNumberHelper) decInteger() (ui uint64, neg, ok bool) {
- panic("decInteger unsupported")
-}
-func (x decDriverNoopNumberHelper) decFloat() (f float64, ok bool) { panic("decFloat unsupported") }
-
-type decDriverNoopContainerReader struct{}
-
-func (x decDriverNoopContainerReader) ReadArrayStart() (v int) { panic("ReadArrayStart unsupported") }
-func (x decDriverNoopContainerReader) ReadMapStart() (v int) { panic("ReadMapStart unsupported") }
-func (x decDriverNoopContainerReader) ReadArrayEnd() {}
-func (x decDriverNoopContainerReader) ReadMapEnd() {}
-func (x decDriverNoopContainerReader) ReadArrayElem(firstTime bool) {}
-func (x decDriverNoopContainerReader) ReadMapElemKey(firstTime bool) {}
-func (x decDriverNoopContainerReader) ReadMapElemValue() {}
-func (x decDriverNoopContainerReader) CheckBreak() (v bool) { return }
-
-// ----
-
-type decFnInfo struct {
- ti *typeInfo
- xfFn Ext
- xfTag uint64
- addrD bool // decoding into a pointer is preferred
- addrDf bool // force: if addrD, then decode function MUST take a ptr
-}
-
-// DecodeOptions captures configuration options during decode.
-type DecodeOptions struct {
- // MapType specifies type to use during schema-less decoding of a map in the stream.
- // If nil (unset), we default to map[string]interface{} iff json handle and MapKeyAsString=true,
- // else map[interface{}]interface{}.
- MapType reflect.Type
-
- // SliceType specifies type to use during schema-less decoding of an array in the stream.
- // If nil (unset), we default to []interface{} for all formats.
- SliceType reflect.Type
-
- // MaxInitLen defines the maxinum initial length that we "make" a collection
- // (string, slice, map, chan). If 0 or negative, we default to a sensible value
- // based on the size of an element in the collection.
- //
- // For example, when decoding, a stream may say that it has 2^64 elements.
- // We should not auto-matically provision a slice of that size, to prevent Out-Of-Memory crash.
- // Instead, we provision up to MaxInitLen, fill that up, and start appending after that.
- MaxInitLen int
-
- // ReaderBufferSize is the size of the buffer used when reading.
- //
- // if > 0, we use a smart buffer internally for performance purposes.
- ReaderBufferSize int
-
- // MaxDepth defines the maximum depth when decoding nested
- // maps and slices. If 0 or negative, we default to a suitably large number (currently 1024).
- MaxDepth int16
-
- // If ErrorIfNoField, return an error when decoding a map
- // from a codec stream into a struct, and no matching struct field is found.
- ErrorIfNoField bool
-
- // If ErrorIfNoArrayExpand, return an error when decoding a slice/array that cannot be expanded.
- // For example, the stream contains an array of 8 items, but you are decoding into a [4]T array,
- // or you are decoding into a slice of length 4 which is non-addressable (and so cannot be set).
- ErrorIfNoArrayExpand bool
-
- // If SignedInteger, use the int64 during schema-less decoding of unsigned values (not uint64).
- SignedInteger bool
-
- // MapValueReset controls how we decode into a map value.
- //
- // By default, we MAY retrieve the mapping for a key, and then decode into that.
- // However, especially with big maps, that retrieval may be expensive and unnecessary
- // if the stream already contains all that is necessary to recreate the value.
- //
- // If true, we will never retrieve the previous mapping,
- // but rather decode into a new value and set that in the map.
- //
- // If false, we will retrieve the previous mapping if necessary e.g.
- // the previous mapping is a pointer, or is a struct or array with pre-set state,
- // or is an interface.
- MapValueReset bool
-
- // SliceElementReset: on decoding a slice, reset the element to a zero value first.
- //
- // concern: if the slice already contained some garbage, we will decode into that garbage.
- SliceElementReset bool
-
- // InterfaceReset controls how we decode into an interface.
- //
- // By default, when we see a field that is an interface{...},
- // or a map with interface{...} value, we will attempt decoding into the
- // "contained" value.
- //
- // However, this prevents us from reading a string into an interface{}
- // that formerly contained a number.
- //
- // If true, we will decode into a new "blank" value, and set that in the interface.
- // If false, we will decode into whatever is contained in the interface.
- InterfaceReset bool
-
- // InternString controls interning of strings during decoding.
- //
- // Some handles, e.g. json, typically will read map keys as strings.
- // If the set of keys are finite, it may help reduce allocation to
- // look them up from a map (than to allocate them afresh).
- //
- // Note: Handles will be smart when using the intern functionality.
- // Every string should not be interned.
- // An excellent use-case for interning is struct field names,
- // or map keys where key type is string.
- InternString bool
-
- // PreferArrayOverSlice controls whether to decode to an array or a slice.
- //
- // This only impacts decoding into a nil interface{}.
- //
- // Consequently, it has no effect on codecgen.
- //
- // *Note*: This only applies if using go1.5 and above,
- // as it requires reflect.ArrayOf support which was absent before go1.5.
- PreferArrayOverSlice bool
-
- // DeleteOnNilMapValue controls how to decode a nil value in the stream.
- //
- // If true, we will delete the mapping of the key.
- // Else, just set the mapping to the zero value of the type.
- //
- // Deprecated: This does NOTHING and is left behind for compiling compatibility.
- // This change is necessitated because 'nil' in a stream now consistently
- // means the zero value (ie reset the value to its zero state).
- DeleteOnNilMapValue bool
-
- // RawToString controls how raw bytes in a stream are decoded into a nil interface{}.
- // By default, they are decoded as []byte, but can be decoded as string (if configured).
- RawToString bool
-
- // ZeroCopy controls whether decoded values of []byte or string type
- // point into the input []byte parameter passed to a NewDecoderBytes/ResetBytes(...) call.
- //
- // To illustrate, if ZeroCopy and decoding from a []byte (not io.Writer),
- // then a []byte or string in the output result may just be a slice of (point into)
- // the input bytes.
- //
- // This optimization prevents unnecessary copying.
- //
- // However, it is made optional, as the caller MUST ensure that the input parameter []byte is
- // not modified after the Decode() happens, as any changes are mirrored in the decoded result.
- ZeroCopy bool
-
- // PreferPointerForStructOrArray controls whether a struct or array
- // is stored in a nil interface{}, or a pointer to it.
- //
- // This mostly impacts when we decode registered extensions.
- PreferPointerForStructOrArray bool
-
- // ValidateUnicode controls will cause decoding to fail if an expected unicode
- // string is well-formed but include invalid codepoints.
- //
- // This could have a performance impact.
- ValidateUnicode bool
-}
-
-// ----------------------------------------
-
-type decoderBase struct {
- perType decPerType
-
- h *BasicHandle
-
- rtidFn, rtidFnNoExt *atomicRtidFnSlice
-
- buf []byte
-
- // used for interning strings
- is internerMap
-
- err error
-
- // sd decoderI
-
- blist bytesFreeList
-
- mtr bool // is maptype a known type?
- str bool // is slicetype a known type?
- jsms bool // is json handle, and MapKeyAsString
-
- bytes bool // uses a bytes reader
- bufio bool // uses a ioDecReader with buffer size > 0
-
- // ---- cpu cache line boundary?
- // ---- writable fields during execution --- *try* to keep in sep cache line
- maxdepth int16
- depth int16
-
- // Extensions can call Decode() within a current Decode() call.
- // We need to know when the top level Decode() call returns,
- // so we can decide whether to Release() or not.
- calls uint16 // what depth in mustDecode are we in now.
-
- c containerState
-
- // decByteState
-
- n fauxUnion
-
- // b is an always-available scratch buffer used by Decoder and decDrivers.
- // By being always-available, it can be used for one-off things without
- // having to get from freelist, use, and return back to freelist.
- //
- // Use it for a narrow set of things e.g.
- // - binc uses it for parsing numbers, represented at 8 or less bytes
- // - uses as potential buffer for struct field names
- b [decScratchByteArrayLen]byte
-
- hh Handle
- // cache the mapTypeId and sliceTypeId for faster comparisons
- mtid uintptr
- stid uintptr
-}
-
-func (d *decoderBase) maxInitLen() uint {
- return uint(max(1024, d.h.MaxInitLen))
-}
-
-func (d *decoderBase) naked() *fauxUnion {
- return &d.n
-}
-
-func (d *decoderBase) fauxUnionReadRawBytes(dr decDriverI, asString, rawToString bool) { //, handleZeroCopy bool) {
- // fauxUnion is only used within DecodeNaked calls; consequently, we should try to intern.
- d.n.l, d.n.a = dr.DecodeBytes()
- if asString || rawToString {
- d.n.v = valueTypeString
- d.n.s = d.detach2Str(d.n.l, d.n.a)
- } else {
- d.n.v = valueTypeBytes
- d.n.l = d.detach2Bytes(d.n.l, d.n.a)
- }
-}
-
-// Return a fixed (detached) string representation of a []byte.
-//
-// Possibly get an interned version of a string,
-// iff InternString=true and decoding a map key.
-//
-// This should mostly be used for map keys, struct field names, etc
-// where the key type is string. This is because keys of a map/struct are
-// typically reused across many objects.
-func (d *decoderBase) detach2Str(v []byte, state dBytesAttachState) (s string) {
- // note: string([]byte) checks - and optimizes - for len 0 and len 1
- if len(v) <= 1 {
- s = string(v)
- } else if state >= dBytesAttachViewZerocopy { // !scratchBuf && d.bytes && d.h.ZeroCopy
- s = stringView(v)
- } else if d.is == nil || d.c != containerMapKey || len(v) > internMaxStrLen {
- s = string(v)
- } else {
- s = d.is.string(v)
- }
- return
-}
-
-func (d *decoderBase) usableStructFieldNameBytes(buf, v []byte, state dBytesAttachState) (out []byte) {
- // In JSON, mapElemValue reads a colon and spaces.
- // In bufio mode of ioDecReader, fillbuf could overwrite the read buffer
- // which readXXX() calls return sub-slices from.
- //
- // Consequently, we detach the bytes in this special case.
- //
- // Note: ioDecReader (non-bufio) and bytesDecReader do not have
- // this issue (as no fillbuf exists where bytes might be returned from).
- if d.bufio && d.h.jsonHandle && state < dBytesAttachViewZerocopy {
- if cap(buf) > len(v) {
- out = buf[:len(v)]
- } else if len(d.b) > len(v) {
- out = d.b[:len(v)]
- } else {
- out = make([]byte, len(v), max(64, len(v)))
- }
- copy(out, v)
- return
- }
- return v
-}
-
-func (d *decoderBase) detach2Bytes(in []byte, state dBytesAttachState) (out []byte) {
- if cap(in) == 0 || state >= dBytesAttachViewZerocopy {
- return in
- }
- if len(in) == 0 {
- return zeroByteSlice
- }
- out = make([]byte, len(in))
- copy(out, in)
- return out
-}
-
-func (d *decoderBase) attachState(usingBufFromReader bool) (r dBytesAttachState) {
- if usingBufFromReader {
- r = dBytesAttachBuffer
- } else if !d.bytes {
- r = dBytesDetach
- } else if d.h.ZeroCopy {
- r = dBytesAttachViewZerocopy
- } else {
- r = dBytesAttachView
- }
- return
-}
-
-func (d *decoderBase) mapStart(v int) int {
- if v != containerLenNil {
- d.depthIncr()
- d.c = containerMapStart
- }
- return v
-}
-
-func (d *decoderBase) HandleName() string {
- return d.hh.Name()
-}
-
-func (d *decoderBase) isBytes() bool {
- return d.bytes
-}
-
-type decoderI interface {
- Decode(v interface{}) (err error)
- HandleName() string
- MustDecode(v interface{})
- NumBytesRead() int
- Release() // deprecated
- Reset(r io.Reader)
- ResetBytes(in []byte)
- ResetString(s string)
-
- isBytes() bool
- wrapErr(v error, err *error)
- swallow()
-
- nextValueBytes() []byte // wrapper method, for use in tests
- // getDecDriver() decDriverI
-
- decode(v interface{})
- decodeAs(v interface{}, t reflect.Type, ext bool)
-
- interfaceExtConvertAndDecode(v interface{}, ext InterfaceExt)
-}
-
-var errDecNoResetBytesWithReader = errors.New("cannot reset an Decoder reading from []byte with a io.Reader")
-var errDecNoResetReaderWithBytes = errors.New("cannot reset an Decoder reading from io.Reader with a []byte")
-
-func setZero(iv interface{}) {
- rv, isnil := isNil(iv, false)
- if isnil {
- return
- }
- if !rv.IsValid() {
- rv = reflect.ValueOf(iv)
- }
- if isnilBitset.isset(byte(rv.Kind())) && rvIsNil(rv) {
- return
- }
- // var canDecode bool
- switch v := iv.(type) {
- case *string:
- *v = ""
- case *bool:
- *v = false
- case *int:
- *v = 0
- case *int8:
- *v = 0
- case *int16:
- *v = 0
- case *int32:
- *v = 0
- case *int64:
- *v = 0
- case *uint:
- *v = 0
- case *uint8:
- *v = 0
- case *uint16:
- *v = 0
- case *uint32:
- *v = 0
- case *uint64:
- *v = 0
- case *float32:
- *v = 0
- case *float64:
- *v = 0
- case *complex64:
- *v = 0
- case *complex128:
- *v = 0
- case *[]byte:
- *v = nil
- case *Raw:
- *v = nil
- case *time.Time:
- *v = time.Time{}
- case reflect.Value:
- decSetNonNilRV2Zero(v)
- default:
- if !fastpathDecodeSetZeroTypeSwitch(iv) {
- decSetNonNilRV2Zero(rv)
- }
- }
-}
-
-// decSetNonNilRV2Zero will set the non-nil value to its zero value.
-func decSetNonNilRV2Zero(v reflect.Value) {
- // If not decodeable (settable), we do not touch it.
- // We considered empty'ing it if not decodeable e.g.
- // - if chan, drain it
- // - if map, clear it
- // - if slice or array, zero all elements up to len
- //
- // However, we decided instead that we either will set the
- // whole value to the zero value, or leave AS IS.
-
- k := v.Kind()
- if k == reflect.Interface {
- decSetNonNilRV2Zero4Intf(v)
- } else if k == reflect.Ptr {
- decSetNonNilRV2Zero4Ptr(v)
- } else if v.CanSet() {
- rvSetDirectZero(v)
- }
-}
-
-func decSetNonNilRV2Zero4Ptr(v reflect.Value) {
- ve := v.Elem()
- if ve.CanSet() {
- rvSetZero(ve) // we can have a pointer to an interface
- } else if v.CanSet() {
- rvSetZero(v)
- }
-}
-
-func decSetNonNilRV2Zero4Intf(v reflect.Value) {
- ve := v.Elem()
- if ve.CanSet() {
- rvSetDirectZero(ve) // interfaces always have element as a non-interface
- } else if v.CanSet() {
- rvSetZero(v)
- }
-}
-
-func (d *decoderBase) arrayCannotExpand(sliceLen, streamLen int) {
- if d.h.ErrorIfNoArrayExpand {
- halt.errorf("cannot expand array len during decode from %v to %v", any(sliceLen), any(streamLen))
- }
-}
-
-//go:noinline
-func (d *decoderBase) haltAsNotDecodeable(rv reflect.Value) {
- if !rv.IsValid() {
- halt.onerror(errCannotDecodeIntoNil)
- }
- // check if an interface can be retrieved, before grabbing an interface
- if !rv.CanInterface() {
- halt.errorf("cannot decode into a value without an interface: %v", rv)
- }
- halt.errorf("cannot decode into value of kind: %v, %#v", rv.Kind(), rv2i(rv))
-}
-
-func (d *decoderBase) depthIncr() {
- d.depth++
- if d.depth >= d.maxdepth {
- halt.onerror(errMaxDepthExceeded)
- }
-}
-
-func (d *decoderBase) depthDecr() {
- d.depth--
-}
-
-func (d *decoderBase) arrayStart(v int) int {
- if v != containerLenNil {
- d.depthIncr()
- d.c = containerArrayStart
- }
- return v
-}
-
-func (d *decoderBase) oneShotAddrRV(rvt reflect.Type, rvk reflect.Kind) reflect.Value {
- // MARKER 2025: is this slow for calling oneShot?
- if decUseTransient && d.h.getTypeInfo4RT(baseRT(rvt)).flagCanTransient {
- return d.perType.TransientAddrK(rvt, rvk)
- }
- return rvZeroAddrK(rvt, rvk)
-}
-
-// decNegintPosintFloatNumberHelper is used for formats that are binary
-// and have distinct ways of storing positive integers vs negative integers
-// vs floats, which are uniquely identified by the byte descriptor.
-//
-// Currently, these formats are binc, cbor and simple.
-type decNegintPosintFloatNumberHelper struct {
- d decDriverI
-}
-
-func (x decNegintPosintFloatNumberHelper) uint64(ui uint64, neg, ok bool) uint64 {
- if ok && !neg {
- return ui
- }
- return x.uint64TryFloat(ok)
-}
-
-func (x decNegintPosintFloatNumberHelper) uint64TryFloat(neg bool) (ui uint64) {
- if neg { // neg = true
- halt.errorStr("assigning negative signed value to unsigned type")
- }
- f, ok := x.d.decFloat()
- if !(ok && f >= 0 && noFrac64(math.Float64bits(f))) {
- halt.errorStr2("invalid number loading uint64, with descriptor: ", x.d.descBd())
- }
- return uint64(f)
-}
-
-func (x decNegintPosintFloatNumberHelper) int64(ui uint64, neg, ok, cbor bool) (i int64) {
- if ok {
- return decNegintPosintFloatNumberHelperInt64v(ui, neg, cbor)
- }
- // return x.int64TryFloat()
- // }
- // func (x decNegintPosintFloatNumberHelper) int64TryFloat() (i int64) {
- f, ok := x.d.decFloat()
- if !(ok && noFrac64(math.Float64bits(f))) {
- halt.errorf("invalid number loading uint64 (%v), with descriptor: %s", f, x.d.descBd())
- }
- return int64(f)
-}
-
-func (x decNegintPosintFloatNumberHelper) float64(f float64, ok, cbor bool) float64 {
- if ok {
- return f
- }
- return x.float64TryInteger(cbor)
-}
-
-func (x decNegintPosintFloatNumberHelper) float64TryInteger(cbor bool) float64 {
- ui, neg, ok := x.d.decInteger()
- if !ok {
- halt.errorStr2("invalid descriptor for float: ", x.d.descBd())
- }
- return float64(decNegintPosintFloatNumberHelperInt64v(ui, neg, cbor))
-}
-
-func decNegintPosintFloatNumberHelperInt64v(ui uint64, neg, incrIfNeg bool) (i int64) {
- if neg && incrIfNeg {
- ui++
- }
- i = chkOvf.SignedIntV(ui)
- if neg {
- i = -i
- }
- return
-}
-
-// isDecodeable checks if value can be decoded into
-//
-// decode can take any reflect.Value that is a inherently addressable i.e.
-// - non-nil chan (we will SEND to it)
-// - non-nil slice (we will set its elements)
-// - non-nil map (we will put into it)
-// - non-nil pointer (we can "update" it)
-// - func: no
-// - interface: no
-// - array: if canAddr=true
-// - any other value pointer: if canAddr=true
-func isDecodeable(rv reflect.Value) (canDecode bool, reason decNotDecodeableReason) {
- switch rv.Kind() {
- case reflect.Ptr, reflect.Slice, reflect.Chan, reflect.Map:
- canDecode = !rvIsNil(rv)
- reason = decNotDecodeableReasonNilReference
- case reflect.Func, reflect.Interface, reflect.Invalid, reflect.UnsafePointer:
- reason = decNotDecodeableReasonBadKind
- default:
- canDecode = rv.CanAddr()
- reason = decNotDecodeableReasonNonAddrValue
- }
- return
-}
-
-// decInferLen will infer a sensible length, given the following:
-// - clen: length wanted.
-// - maxlen: max length to be returned.
-// if <= 0, it is unset, and we infer it based on the unit size
-// - unit: number of bytes for each element of the collection
-func decInferLen(clen int, maxlen, unit uint) (n uint) {
- // anecdotal testing showed increase in allocation with map length of 16.
- // We saw same typical alloc from 0-8, then a 20% increase at 16.
- // Thus, we set it to 8.
-
- const (
- minLenIfUnset = 8
- maxMem = 1024 * 1024 // 1 MB Memory
- )
-
- // handle when maxlen is not set i.e. <= 0
-
- // clen==0: use 0
- // maxlen<=0, clen<0: use default
- // maxlen> 0, clen<0: use default
- // maxlen<=0, clen>0: infer maxlen, and cap on it
- // maxlen> 0, clen>0: cap at maxlen
-
- if clen == 0 || clen == containerLenNil {
- return 0
- }
- if clen < 0 {
- // if unspecified, return 64 for bytes, ... 8 for uint64, ... and everything else
- return max(64/unit, minLenIfUnset)
- }
- if unit == 0 {
- return uint(clen)
- }
- if maxlen == 0 {
- maxlen = maxMem / unit
- }
- return min(uint(clen), maxlen)
-}
-
-type Decoder struct {
- decoderI
-}
-
-// NewDecoder returns a Decoder for decoding a stream of bytes from an io.Reader.
-//
-// For efficiency, Users are encouraged to configure ReaderBufferSize on the handle
-// OR pass in a memory buffered reader (eg bufio.Reader, bytes.Buffer).
-func NewDecoder(r io.Reader, h Handle) *Decoder {
- return &Decoder{h.newDecoder(r)}
-}
-
-// NewDecoderBytes returns a Decoder which efficiently decodes directly
-// from a byte slice with zero copying.
-func NewDecoderBytes(in []byte, h Handle) *Decoder {
- return &Decoder{h.newDecoderBytes(in)}
-}
-
-// NewDecoderString returns a Decoder which efficiently decodes directly
-// from a string with zero copying.
-//
-// It is a convenience function that calls NewDecoderBytes with a
-// []byte view into the string.
-//
-// This can be an efficient zero-copy if using default mode i.e. without codec.safe tag.
-func NewDecoderString(s string, h Handle) *Decoder {
- return NewDecoderBytes(bytesView(s), h)
-}
-
-// ----
-
-func sideDecode(h Handle, p *sync.Pool, fn func(decoderI)) {
- var s decoderI
- if usePoolForSideDecode {
- s = p.Get().(decoderI)
- defer p.Put(s)
- } else {
- // initialization cycle error
- // s = NewDecoderBytes(nil, h).decoderI
- s = p.New().(decoderI)
- }
- fn(s)
-}
-
-func oneOffDecode(sd decoderI, v interface{}, in []byte, basetype reflect.Type, ext bool) {
- sd.ResetBytes(in)
- sd.decodeAs(v, basetype, ext)
- // d.sideDecoder(xbs)
- // d.sideDecode(rv, basetype)
-}
-
-func bytesOKdbi(v []byte, _ dBytesIntoState) []byte {
- return v
-}
-
-func bytesOKs(bs []byte, _ dBytesAttachState) []byte {
- return bs
-}