mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 13:12:25 -05:00 
			
		
		
		
	[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 <grufwub@gmail.com>
Co-committed-by: kim <grufwub@gmail.com>
	
	
This commit is contained in:
		
					parent
					
						
							
								7712885038
							
						
					
				
			
			
				commit
				
					
						8b0ea56027
					
				
			
		
					 294 changed files with 139999 additions and 21873 deletions
				
			
		
							
								
								
									
										944
									
								
								vendor/github.com/ugorji/go/codec/decode.base.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										944
									
								
								vendor/github.com/ugorji/go/codec/decode.base.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,944 @@ | |||
| // 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 | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue