mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-11-03 23:12:26 -06:00 
			
		
		
		
	[chore]: Bump github.com/gin-contrib/gzip from 1.0.1 to 1.1.0 (#3639)
Bumps [github.com/gin-contrib/gzip](https://github.com/gin-contrib/gzip) from 1.0.1 to 1.1.0. - [Release notes](https://github.com/gin-contrib/gzip/releases) - [Changelog](https://github.com/gin-contrib/gzip/blob/master/.goreleaser.yaml) - [Commits](https://github.com/gin-contrib/gzip/compare/v1.0.1...v1.1.0) --- updated-dependencies: - dependency-name: github.com/gin-contrib/gzip dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
		
					parent
					
						
							
								8cfae010a9
							
						
					
				
			
			
				commit
				
					
						4d423102c1
					
				
			
		
					 519 changed files with 156968 additions and 132058 deletions
				
			
		
							
								
								
									
										174
									
								
								vendor/github.com/bytedance/sonic/internal/decoder/optdec/compile_struct.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										174
									
								
								vendor/github.com/bytedance/sonic/internal/decoder/optdec/compile_struct.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,174 @@
 | 
			
		|||
package optdec
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"reflect"
 | 
			
		||||
 | 
			
		||||
	caching "github.com/bytedance/sonic/internal/optcaching"
 | 
			
		||||
	"github.com/bytedance/sonic/internal/rt"
 | 
			
		||||
	"github.com/bytedance/sonic/internal/resolver"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
    _MAX_FIELDS = 50        // cutoff at 50 fields struct
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (c *compiler) compileIntStringOption(vt reflect.Type) decFunc {
 | 
			
		||||
	switch vt.Size() {
 | 
			
		||||
	case 4:
 | 
			
		||||
		switch vt.Kind() {
 | 
			
		||||
		case reflect.Uint:
 | 
			
		||||
			fallthrough
 | 
			
		||||
		case reflect.Uintptr:
 | 
			
		||||
			return &u32StringDecoder{}
 | 
			
		||||
		case reflect.Int:
 | 
			
		||||
			return &i32StringDecoder{}
 | 
			
		||||
		}
 | 
			
		||||
	case 8:
 | 
			
		||||
		switch vt.Kind() {
 | 
			
		||||
		case reflect.Uint:
 | 
			
		||||
			fallthrough
 | 
			
		||||
		case reflect.Uintptr:
 | 
			
		||||
			return &u64StringDecoder{}
 | 
			
		||||
		case reflect.Int:
 | 
			
		||||
			return &i64StringDecoder{}
 | 
			
		||||
		}
 | 
			
		||||
	default:
 | 
			
		||||
		panic("not supported pointer size: " + fmt.Sprint(vt.Size()))
 | 
			
		||||
	}
 | 
			
		||||
	panic("unreachable")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func isInteger(vt reflect.Type) bool {
 | 
			
		||||
	switch vt.Kind() {
 | 
			
		||||
		case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint, reflect.Uintptr, reflect.Int: return true
 | 
			
		||||
		default: return false
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *compiler) assertStringOptTypes(vt reflect.Type) {
 | 
			
		||||
	if c.depth > _CompileMaxDepth {
 | 
			
		||||
		panic(*stackOverflow)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c.depth += 1
 | 
			
		||||
	defer func ()  {
 | 
			
		||||
		c.depth -= 1
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	if isInteger(vt) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch vt.Kind() {
 | 
			
		||||
	case reflect.String, reflect.Bool, reflect.Float32, reflect.Float64:
 | 
			
		||||
		return
 | 
			
		||||
	case reflect.Ptr: c.assertStringOptTypes(vt.Elem())
 | 
			
		||||
	default:
 | 
			
		||||
		panicForInvalidStrType(vt)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *compiler) compileFieldStringOption(vt reflect.Type) decFunc {
 | 
			
		||||
	c.assertStringOptTypes(vt)
 | 
			
		||||
	unmDec := c.tryCompilePtrUnmarshaler(vt, true)
 | 
			
		||||
	if unmDec != nil { 
 | 
			
		||||
		return unmDec
 | 
			
		||||
	} 
 | 
			
		||||
 | 
			
		||||
	switch vt.Kind() {
 | 
			
		||||
	case reflect.String:
 | 
			
		||||
		if vt == jsonNumberType {
 | 
			
		||||
			return &numberStringDecoder{}
 | 
			
		||||
		}
 | 
			
		||||
		return &strStringDecoder{}
 | 
			
		||||
	case reflect.Bool:
 | 
			
		||||
		return &boolStringDecoder{}
 | 
			
		||||
	case reflect.Int8:
 | 
			
		||||
		return &i8StringDecoder{}
 | 
			
		||||
	case reflect.Int16:
 | 
			
		||||
		return &i16StringDecoder{}
 | 
			
		||||
	case reflect.Int32:
 | 
			
		||||
		return &i32StringDecoder{}
 | 
			
		||||
	case reflect.Int64:
 | 
			
		||||
		return &i64StringDecoder{}
 | 
			
		||||
	case reflect.Uint8:
 | 
			
		||||
		return &u8StringDecoder{}
 | 
			
		||||
	case reflect.Uint16:
 | 
			
		||||
		return &u16StringDecoder{}
 | 
			
		||||
	case reflect.Uint32:
 | 
			
		||||
		return &u32StringDecoder{}
 | 
			
		||||
	case reflect.Uint64:
 | 
			
		||||
		return &u64StringDecoder{}
 | 
			
		||||
	case reflect.Float32:
 | 
			
		||||
		return &f32StringDecoder{}
 | 
			
		||||
	case reflect.Float64:
 | 
			
		||||
		return &f64StringDecoder{}
 | 
			
		||||
	case reflect.Uint:
 | 
			
		||||
		fallthrough
 | 
			
		||||
	case reflect.Uintptr:
 | 
			
		||||
		fallthrough
 | 
			
		||||
	case reflect.Int:
 | 
			
		||||
		return c.compileIntStringOption(vt)
 | 
			
		||||
	case reflect.Ptr:
 | 
			
		||||
		return &ptrStrDecoder{
 | 
			
		||||
			typ:   rt.UnpackType(vt.Elem()),
 | 
			
		||||
			deref: c.compileFieldStringOption(vt.Elem()),
 | 
			
		||||
		}
 | 
			
		||||
	default:
 | 
			
		||||
		panicForInvalidStrType(vt)
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *compiler) compileStruct(vt reflect.Type) decFunc {
 | 
			
		||||
	c.enter(vt)
 | 
			
		||||
	defer c.exit(vt)
 | 
			
		||||
	if c.namedPtr {
 | 
			
		||||
		c.namedPtr = false
 | 
			
		||||
		return c.compileStructBody(vt)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if c.depth >= c.opts.MaxInlineDepth + 1 || (c.counts > 0 &&  vt.NumField() >= _MAX_FIELDS) {
 | 
			
		||||
		return &recuriveDecoder{
 | 
			
		||||
			typ: rt.UnpackType(vt),
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		return c.compileStructBody(vt)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *compiler) compileStructBody(vt reflect.Type) decFunc {
 | 
			
		||||
	fv := resolver.ResolveStruct(vt)
 | 
			
		||||
	entries := make([]fieldEntry, 0, len(fv))
 | 
			
		||||
 | 
			
		||||
	for _, f := range fv {
 | 
			
		||||
		var dec decFunc
 | 
			
		||||
		/* dealt with field tag options */
 | 
			
		||||
		if f.Opts&resolver.F_stringize != 0 {
 | 
			
		||||
			dec = c.compileFieldStringOption(f.Type)
 | 
			
		||||
		} else {
 | 
			
		||||
			dec = c.compile(f.Type)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* deal with embedded pointer fields */
 | 
			
		||||
		if f.Path[0].Kind == resolver.F_deref {
 | 
			
		||||
			dec = &embeddedFieldPtrDecoder{
 | 
			
		||||
				field:    	f,
 | 
			
		||||
				fieldDec:   dec,
 | 
			
		||||
				fieldName:  f.Name,
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		entries = append(entries, fieldEntry{
 | 
			
		||||
			FieldMeta: f,
 | 
			
		||||
			fieldDec:  dec,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	return &structDecoder{
 | 
			
		||||
		fieldMap:  	caching.NewFieldLookup(fv),
 | 
			
		||||
		fields:     entries,
 | 
			
		||||
		structName: vt.Name(),
 | 
			
		||||
		typ: 		vt,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										449
									
								
								vendor/github.com/bytedance/sonic/internal/decoder/optdec/compiler.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										449
									
								
								vendor/github.com/bytedance/sonic/internal/decoder/optdec/compiler.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,449 @@
 | 
			
		|||
package optdec
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"reflect"
 | 
			
		||||
 | 
			
		||||
	"github.com/bytedance/sonic/option"
 | 
			
		||||
	"github.com/bytedance/sonic/internal/rt"
 | 
			
		||||
	"github.com/bytedance/sonic/internal/caching"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	programCache = caching.CreateProgramCache()
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func findOrCompile(vt *rt.GoType) (decFunc, error) {
 | 
			
		||||
	makeDecoder := func(vt *rt.GoType, _ ...interface{}) (interface{}, error) {
 | 
			
		||||
		ret, err := newCompiler().compileType(vt.Pack())
 | 
			
		||||
		return ret, err
 | 
			
		||||
	}
 | 
			
		||||
	if val := programCache.Get(vt); val != nil {
 | 
			
		||||
		return val.(decFunc), nil
 | 
			
		||||
	} else if ret, err := programCache.Compute(vt, makeDecoder); err == nil {
 | 
			
		||||
		return ret.(decFunc), nil
 | 
			
		||||
	} else {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type compiler struct {
 | 
			
		||||
	visited map[reflect.Type]bool
 | 
			
		||||
	depth   int
 | 
			
		||||
	counts  int
 | 
			
		||||
	opts 	option.CompileOptions
 | 
			
		||||
	namedPtr bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newCompiler() *compiler {
 | 
			
		||||
	return &compiler{
 | 
			
		||||
		visited: make(map[reflect.Type]bool),
 | 
			
		||||
		opts:  option.DefaultCompileOptions(),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (self *compiler) apply(opts option.CompileOptions) *compiler {
 | 
			
		||||
	self.opts = opts
 | 
			
		||||
	return self
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const _CompileMaxDepth = 4096
 | 
			
		||||
 | 
			
		||||
func (c *compiler) enter(vt reflect.Type) {
 | 
			
		||||
	c.visited[vt] = true
 | 
			
		||||
	c.depth += 1
 | 
			
		||||
 | 
			
		||||
	if c.depth > _CompileMaxDepth {
 | 
			
		||||
		panic(*stackOverflow)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *compiler) exit(vt reflect.Type) {
 | 
			
		||||
	c.visited[vt] = false
 | 
			
		||||
	c.depth -= 1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *compiler) compileInt(vt reflect.Type) decFunc {
 | 
			
		||||
	switch vt.Size() {
 | 
			
		||||
	case 4:
 | 
			
		||||
		switch vt.Kind() {
 | 
			
		||||
		case reflect.Uint:
 | 
			
		||||
			fallthrough
 | 
			
		||||
		case reflect.Uintptr:
 | 
			
		||||
			return &u32Decoder{}
 | 
			
		||||
		case reflect.Int:
 | 
			
		||||
			return &i32Decoder{}
 | 
			
		||||
		}
 | 
			
		||||
	case 8:
 | 
			
		||||
		switch vt.Kind() {
 | 
			
		||||
		case reflect.Uint:
 | 
			
		||||
			fallthrough
 | 
			
		||||
		case reflect.Uintptr:
 | 
			
		||||
			return &u64Decoder{}
 | 
			
		||||
		case reflect.Int:
 | 
			
		||||
			return &i64Decoder{}
 | 
			
		||||
		}
 | 
			
		||||
	default:
 | 
			
		||||
		panic("not supported pointer size: " + fmt.Sprint(vt.Size()))
 | 
			
		||||
	}
 | 
			
		||||
	panic("unreachable")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *compiler) rescue(ep *error) {
 | 
			
		||||
	if val := recover(); val != nil {
 | 
			
		||||
		if err, ok := val.(error); ok {
 | 
			
		||||
			*ep = err
 | 
			
		||||
		} else {
 | 
			
		||||
			panic(val)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *compiler) compileType(vt reflect.Type) (rt decFunc, err error) {
 | 
			
		||||
	defer c.rescue(&err)
 | 
			
		||||
	rt = c.compile(vt)
 | 
			
		||||
	return rt, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *compiler) compile(vt reflect.Type) decFunc {
 | 
			
		||||
	if c.visited[vt] {
 | 
			
		||||
		return &recuriveDecoder{
 | 
			
		||||
			typ: rt.UnpackType(vt),
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dec := c.tryCompilePtrUnmarshaler(vt, false)
 | 
			
		||||
	if dec != nil {
 | 
			
		||||
		return dec
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return c.compileBasic(vt)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *compiler) compileBasic(vt reflect.Type) decFunc {
 | 
			
		||||
	defer func() {
 | 
			
		||||
		c.counts += 1
 | 
			
		||||
	}()
 | 
			
		||||
	switch vt.Kind() {
 | 
			
		||||
	case reflect.Bool:
 | 
			
		||||
		return &boolDecoder{}
 | 
			
		||||
	case reflect.Int8:
 | 
			
		||||
		return &i8Decoder{}
 | 
			
		||||
	case reflect.Int16:
 | 
			
		||||
		return &i16Decoder{}
 | 
			
		||||
	case reflect.Int32:
 | 
			
		||||
		return &i32Decoder{}
 | 
			
		||||
	case reflect.Int64:
 | 
			
		||||
		return &i64Decoder{}
 | 
			
		||||
	case reflect.Uint8:
 | 
			
		||||
		return &u8Decoder{}
 | 
			
		||||
	case reflect.Uint16:
 | 
			
		||||
		return &u16Decoder{}
 | 
			
		||||
	case reflect.Uint32:
 | 
			
		||||
		return &u32Decoder{}
 | 
			
		||||
	case reflect.Uint64:
 | 
			
		||||
		return &u64Decoder{}
 | 
			
		||||
	case reflect.Float32:
 | 
			
		||||
		return &f32Decoder{}
 | 
			
		||||
	case reflect.Float64:
 | 
			
		||||
		return &f64Decoder{}
 | 
			
		||||
	case reflect.Uint:
 | 
			
		||||
		fallthrough
 | 
			
		||||
	case reflect.Uintptr:
 | 
			
		||||
		fallthrough
 | 
			
		||||
	case reflect.Int:
 | 
			
		||||
		return c.compileInt(vt)
 | 
			
		||||
	case reflect.String:
 | 
			
		||||
		return c.compileString(vt)
 | 
			
		||||
	case reflect.Array:
 | 
			
		||||
		return c.compileArray(vt)
 | 
			
		||||
	case reflect.Interface:
 | 
			
		||||
		return c.compileInterface(vt)
 | 
			
		||||
	case reflect.Map:
 | 
			
		||||
		return c.compileMap(vt)
 | 
			
		||||
	case reflect.Ptr:
 | 
			
		||||
		return c.compilePtr(vt)
 | 
			
		||||
	case reflect.Slice:
 | 
			
		||||
		return c.compileSlice(vt)
 | 
			
		||||
	case reflect.Struct:
 | 
			
		||||
		return c.compileStruct(vt)
 | 
			
		||||
	default:
 | 
			
		||||
		panic(&json.UnmarshalTypeError{Type: vt})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *compiler) compilePtr(vt reflect.Type) decFunc {
 | 
			
		||||
	c.enter(vt)
 | 
			
		||||
	defer c.exit(vt)
 | 
			
		||||
 | 
			
		||||
	// specail logic for Named Ptr, issue 379
 | 
			
		||||
	if reflect.PtrTo(vt.Elem()) != vt {
 | 
			
		||||
		c.namedPtr = true
 | 
			
		||||
		return &ptrDecoder{
 | 
			
		||||
			typ:   rt.UnpackType(vt.Elem()),
 | 
			
		||||
			deref: c.compileBasic(vt.Elem()),
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &ptrDecoder{
 | 
			
		||||
		typ:   rt.UnpackType(vt.Elem()),
 | 
			
		||||
		deref: c.compile(vt.Elem()),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *compiler) compileArray(vt reflect.Type) decFunc {
 | 
			
		||||
	c.enter(vt)
 | 
			
		||||
	defer c.exit(vt)
 | 
			
		||||
	return &arrayDecoder{
 | 
			
		||||
		len:      vt.Len(),
 | 
			
		||||
		elemType: rt.UnpackType(vt.Elem()),
 | 
			
		||||
		elemDec:  c.compile(vt.Elem()),
 | 
			
		||||
		typ: vt,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *compiler) compileString(vt reflect.Type) decFunc {
 | 
			
		||||
	if vt == jsonNumberType {
 | 
			
		||||
		return &numberDecoder{}
 | 
			
		||||
	}
 | 
			
		||||
	return &stringDecoder{}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *compiler) tryCompileSliceUnmarshaler(vt reflect.Type) decFunc {
 | 
			
		||||
	pt := reflect.PtrTo(vt.Elem())
 | 
			
		||||
	if pt.Implements(jsonUnmarshalerType) {
 | 
			
		||||
		return &sliceDecoder{
 | 
			
		||||
			elemType: rt.UnpackType(vt.Elem()),
 | 
			
		||||
			elemDec:  c.compile(vt.Elem()),
 | 
			
		||||
			typ: vt,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if pt.Implements(encodingTextUnmarshalerType) {
 | 
			
		||||
		return &sliceDecoder{
 | 
			
		||||
			elemType: rt.UnpackType(vt.Elem()),
 | 
			
		||||
			elemDec:  c.compile(vt.Elem()),
 | 
			
		||||
			typ: vt,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *compiler) compileSlice(vt reflect.Type) decFunc {
 | 
			
		||||
	c.enter(vt)
 | 
			
		||||
	defer c.exit(vt)
 | 
			
		||||
 | 
			
		||||
	// Some common slice, use a decoder, to avoid function calls
 | 
			
		||||
	et := rt.UnpackType(vt.Elem())
 | 
			
		||||
 | 
			
		||||
	/* first checking `[]byte` */
 | 
			
		||||
	if et.Kind() == reflect.Uint8 /* []byte */ {
 | 
			
		||||
		return c.compileSliceBytes(vt)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dec := c.tryCompileSliceUnmarshaler(vt)
 | 
			
		||||
	if dec != nil {
 | 
			
		||||
		return dec
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if vt == reflect.TypeOf([]interface{}{}) {
 | 
			
		||||
		return &sliceEfaceDecoder{}
 | 
			
		||||
	}
 | 
			
		||||
	if et.IsInt32() {
 | 
			
		||||
		return &sliceI32Decoder{}
 | 
			
		||||
	}
 | 
			
		||||
	if et.IsInt64() {
 | 
			
		||||
		return &sliceI64Decoder{}
 | 
			
		||||
	}
 | 
			
		||||
	if et.IsUint32() {
 | 
			
		||||
		return &sliceU32Decoder{}
 | 
			
		||||
	}
 | 
			
		||||
	if et.IsUint64() {
 | 
			
		||||
		return &sliceU64Decoder{}
 | 
			
		||||
	}
 | 
			
		||||
	if et.Kind() == reflect.String {
 | 
			
		||||
		return &sliceStringDecoder{}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &sliceDecoder{
 | 
			
		||||
		elemType: rt.UnpackType(vt.Elem()),
 | 
			
		||||
		elemDec:  c.compile(vt.Elem()),
 | 
			
		||||
		typ: vt,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *compiler) compileSliceBytes(vt reflect.Type) decFunc {
 | 
			
		||||
	ep := reflect.PtrTo(vt.Elem())
 | 
			
		||||
 | 
			
		||||
	if ep.Implements(jsonUnmarshalerType) {
 | 
			
		||||
		return &sliceBytesUnmarshalerDecoder{
 | 
			
		||||
			elemType: rt.UnpackType(vt.Elem()),
 | 
			
		||||
			elemDec:  c.compile(vt.Elem()),
 | 
			
		||||
			typ: vt,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ep.Implements(encodingTextUnmarshalerType) {
 | 
			
		||||
		return &sliceBytesUnmarshalerDecoder{
 | 
			
		||||
			elemType: rt.UnpackType(vt.Elem()),
 | 
			
		||||
			elemDec:  c.compile(vt.Elem()),
 | 
			
		||||
				typ: vt,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &sliceBytesDecoder{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *compiler) compileInterface(vt reflect.Type) decFunc {
 | 
			
		||||
	c.enter(vt)
 | 
			
		||||
	defer c.exit(vt)
 | 
			
		||||
	if vt.NumMethod() == 0 {
 | 
			
		||||
		return &efaceDecoder{}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if vt.Implements(jsonUnmarshalerType) {
 | 
			
		||||
		return &unmarshalJSONDecoder{
 | 
			
		||||
			typ: rt.UnpackType(vt),
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if vt.Implements(encodingTextUnmarshalerType) {
 | 
			
		||||
		return &unmarshalTextDecoder{
 | 
			
		||||
			typ: rt.UnpackType(vt),
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &ifaceDecoder{
 | 
			
		||||
		typ: rt.UnpackType(vt),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *compiler) compileMap(vt reflect.Type) decFunc {
 | 
			
		||||
	c.enter(vt)
 | 
			
		||||
	defer c.exit(vt)
 | 
			
		||||
	// check the key unmarshaler at first
 | 
			
		||||
	decKey := tryCompileKeyUnmarshaler(vt)
 | 
			
		||||
	if decKey != nil {
 | 
			
		||||
		return &mapDecoder{
 | 
			
		||||
			mapType: rt.MapType(rt.UnpackType(vt)),
 | 
			
		||||
			keyDec:  decKey,
 | 
			
		||||
			elemDec: c.compile(vt.Elem()),
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Most common map, use a decoder, to avoid function calls
 | 
			
		||||
	if vt == reflect.TypeOf(map[string]interface{}{}) {
 | 
			
		||||
		return &mapEfaceDecoder{}
 | 
			
		||||
	} else if vt == reflect.TypeOf(map[string]string{}) {
 | 
			
		||||
		return &mapStringDecoder{}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Some common integer map later
 | 
			
		||||
	mt := rt.MapType(rt.UnpackType(vt))
 | 
			
		||||
 | 
			
		||||
	if mt.Key.Kind() == reflect.String {
 | 
			
		||||
		return &mapStrKeyDecoder{
 | 
			
		||||
			mapType: mt,
 | 
			
		||||
			assign: rt.GetMapStrAssign(vt),
 | 
			
		||||
			elemDec: c.compile(vt.Elem()),
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if mt.Key.IsInt64() {
 | 
			
		||||
		return &mapI64KeyDecoder{
 | 
			
		||||
			mapType: mt,
 | 
			
		||||
			elemDec: c.compile(vt.Elem()),
 | 
			
		||||
			assign: rt.GetMap64Assign(vt),
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if mt.Key.IsInt32() {
 | 
			
		||||
		return &mapI32KeyDecoder{
 | 
			
		||||
			mapType: mt,
 | 
			
		||||
			elemDec: c.compile(vt.Elem()),
 | 
			
		||||
			assign: rt.GetMap32Assign(vt),
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if mt.Key.IsUint64() {
 | 
			
		||||
		return &mapU64KeyDecoder{
 | 
			
		||||
			mapType: mt,
 | 
			
		||||
			elemDec: c.compile(vt.Elem()),
 | 
			
		||||
			assign: rt.GetMap64Assign(vt),
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if mt.Key.IsUint32() {
 | 
			
		||||
		return &mapU32KeyDecoder{
 | 
			
		||||
			mapType: mt,
 | 
			
		||||
			elemDec: c.compile(vt.Elem()),
 | 
			
		||||
			assign: rt.GetMap32Assign(vt),
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Generic map
 | 
			
		||||
	return &mapDecoder{
 | 
			
		||||
		mapType: mt,
 | 
			
		||||
		keyDec:  c.compileMapKey(vt),
 | 
			
		||||
		elemDec: c.compile(vt.Elem()),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func tryCompileKeyUnmarshaler(vt reflect.Type) decKey {
 | 
			
		||||
	pt := reflect.PtrTo(vt.Key())
 | 
			
		||||
 | 
			
		||||
	/* check for `encoding.TextUnmarshaler` with pointer receiver */
 | 
			
		||||
	if pt.Implements(encodingTextUnmarshalerType) {
 | 
			
		||||
		return decodeKeyTextUnmarshaler
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* not support map key with `json.Unmarshaler` */
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *compiler) compileMapKey(vt reflect.Type) decKey {
 | 
			
		||||
	switch vt.Key().Kind() {
 | 
			
		||||
	case reflect.Int8:
 | 
			
		||||
		return decodeKeyI8
 | 
			
		||||
	case reflect.Int16:
 | 
			
		||||
		return decodeKeyI16
 | 
			
		||||
	case reflect.Uint8:
 | 
			
		||||
		return decodeKeyU8
 | 
			
		||||
	case reflect.Uint16:
 | 
			
		||||
		return decodeKeyU16
 | 
			
		||||
	default:
 | 
			
		||||
		panic(&json.UnmarshalTypeError{Type: vt})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// maybe vt is a named type, and not a pointer receiver, see issue 379  
 | 
			
		||||
func (c *compiler) tryCompilePtrUnmarshaler(vt reflect.Type, strOpt bool) decFunc {
 | 
			
		||||
	pt := reflect.PtrTo(vt)
 | 
			
		||||
 | 
			
		||||
	/* check for `json.Unmarshaler` with pointer receiver */
 | 
			
		||||
	if pt.Implements(jsonUnmarshalerType) {
 | 
			
		||||
		return &unmarshalJSONDecoder{
 | 
			
		||||
			typ: rt.UnpackType(pt),
 | 
			
		||||
			strOpt: strOpt,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* check for `encoding.TextMarshaler` with pointer receiver */
 | 
			
		||||
	if pt.Implements(encodingTextUnmarshalerType) {
 | 
			
		||||
		/* TextUnmarshal not support ,strig tag */
 | 
			
		||||
		if strOpt {
 | 
			
		||||
			panicForInvalidStrType(vt)
 | 
			
		||||
		}
 | 
			
		||||
		return &unmarshalTextDecoder{
 | 
			
		||||
			typ: rt.UnpackType(pt),
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func panicForInvalidStrType(vt reflect.Type) {
 | 
			
		||||
	panic(error_type(rt.UnpackType(vt)))
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										60
									
								
								vendor/github.com/bytedance/sonic/internal/decoder/optdec/const.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								vendor/github.com/bytedance/sonic/internal/decoder/optdec/const.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,60 @@
 | 
			
		|||
package optdec
 | 
			
		||||
 | 
			
		||||
import "math"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
Copied from sonic-rs
 | 
			
		||||
// JSON Value Type
 | 
			
		||||
const NULL: u64 = 0;
 | 
			
		||||
const BOOL: u64 = 2;
 | 
			
		||||
const FALSE: u64 = BOOL;
 | 
			
		||||
const TRUE: u64 = (1 << 3) | BOOL;
 | 
			
		||||
const NUMBER: u64 = 3;
 | 
			
		||||
const UINT: u64 = NUMBER;
 | 
			
		||||
const SINT: u64 = (1 << 3) | NUMBER;
 | 
			
		||||
const REAL: u64 = (2 << 3) | NUMBER;
 | 
			
		||||
const RAWNUMBER: u64 = (3 << 3) | NUMBER;
 | 
			
		||||
const STRING: u64 = 4;
 | 
			
		||||
const STRING_COMMON: u64 = STRING;
 | 
			
		||||
const STRING_HASESCAPED: u64 = (1 << 3) | STRING;
 | 
			
		||||
const OBJECT: u64 = 6;
 | 
			
		||||
const ARRAY: u64 = 7;
 | 
			
		||||
 | 
			
		||||
/// JSON Type Mask
 | 
			
		||||
const POS_MASK: u64 = (!0) << 32;
 | 
			
		||||
const POS_BITS: u64 = 32;
 | 
			
		||||
const TYPE_MASK: u64 = 0xFF;
 | 
			
		||||
const TYPE_BITS: u64 = 8;
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// BasicType: 3 bits
 | 
			
		||||
	KNull   = 0 // xxxxx000
 | 
			
		||||
	KBool   = 2 // xxxxx010
 | 
			
		||||
	KNumber = 3 // xxxxx011
 | 
			
		||||
	KString = 4 // xxxxx100
 | 
			
		||||
	KRaw    = 5 // xxxxx101
 | 
			
		||||
	KObject = 6 // xxxxx110
 | 
			
		||||
	KArray  = 7 // xxxxx111
 | 
			
		||||
 | 
			
		||||
	// SubType: 2 bits
 | 
			
		||||
	KFalse            = (0 << 3) | KBool   // xxx00_010, 2
 | 
			
		||||
	KTrue             = (1 << 3) | KBool   // xxx01_010, 10
 | 
			
		||||
	KUint             = (0 << 3) | KNumber // xxx00_011, 3
 | 
			
		||||
	KSint             = (1 << 3) | KNumber // xxx01_011, 11
 | 
			
		||||
	KReal             = (2 << 3) | KNumber // xxx10_011, 19
 | 
			
		||||
	KRawNumber        = (3 << 3) | KNumber // xxx11_011, 27
 | 
			
		||||
	KStringCommon     = KString            // xxx00_100, 4
 | 
			
		||||
	KStringEscaped = (1 << 3) | KString // xxx01_100, 12
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	PosMask  = math.MaxUint64 << 32
 | 
			
		||||
	PosBits  = 32
 | 
			
		||||
	TypeMask = 0xFF
 | 
			
		||||
	TypeBits = 8
 | 
			
		||||
 | 
			
		||||
	ConLenMask = uint64(math.MaxUint32)
 | 
			
		||||
	ConLenBits = 32
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										3
									
								
								vendor/github.com/bytedance/sonic/internal/decoder/optdec/context.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/bytedance/sonic/internal/decoder/optdec/context.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
package optdec
 | 
			
		||||
 | 
			
		||||
type context = Context
 | 
			
		||||
							
								
								
									
										160
									
								
								vendor/github.com/bytedance/sonic/internal/decoder/optdec/decoder.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								vendor/github.com/bytedance/sonic/internal/decoder/optdec/decoder.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,160 @@
 | 
			
		|||
package optdec
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"github.com/bytedance/sonic/internal/rt"
 | 
			
		||||
	"github.com/bytedance/sonic/option"
 | 
			
		||||
	"github.com/bytedance/sonic/internal/decoder/errors"
 | 
			
		||||
	"github.com/bytedance/sonic/internal/decoder/consts"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
type (
 | 
			
		||||
	MismatchTypeError = errors.MismatchTypeError
 | 
			
		||||
	SyntaxError = errors.SyntaxError
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	_F_allow_control = consts.F_allow_control
 | 
			
		||||
	_F_copy_string = consts.F_copy_string
 | 
			
		||||
	_F_disable_unknown = consts.F_disable_unknown
 | 
			
		||||
	_F_disable_urc = consts.F_disable_urc
 | 
			
		||||
	_F_use_int64 = consts.F_use_int64
 | 
			
		||||
	_F_use_number = consts.F_use_number
 | 
			
		||||
	_F_validate_string = consts.F_validate_string
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Options = consts.Options
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	OptionUseInt64     = consts.OptionUseInt64
 | 
			
		||||
	OptionUseNumber    = consts.OptionUseNumber
 | 
			
		||||
	OptionUseUnicodeErrors = consts.OptionUseUnicodeErrors
 | 
			
		||||
	OptionDisableUnknown = consts.OptionDisableUnknown
 | 
			
		||||
	OptionCopyString = consts.OptionCopyString
 | 
			
		||||
	OptionValidateString = consts.OptionValidateString
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
func Decode(s *string, i *int, f uint64, val interface{}) error {
 | 
			
		||||
	vv := rt.UnpackEface(val)
 | 
			
		||||
	vp := vv.Value
 | 
			
		||||
 | 
			
		||||
	/* check for nil type */
 | 
			
		||||
	if vv.Type == nil {
 | 
			
		||||
		return &json.InvalidUnmarshalError{}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* must be a non-nil pointer */
 | 
			
		||||
	if vp == nil || vv.Type.Kind() != reflect.Ptr {
 | 
			
		||||
		return &json.InvalidUnmarshalError{Type: vv.Type.Pack()}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	etp := rt.PtrElem(vv.Type)
 | 
			
		||||
 | 
			
		||||
	/* check the defined pointer type for issue 379 */
 | 
			
		||||
	if vv.Type.IsNamed() {
 | 
			
		||||
		newp := vp
 | 
			
		||||
		etp = vv.Type
 | 
			
		||||
		vp = unsafe.Pointer(&newp)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dec, err := findOrCompile(etp)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* parse into document */
 | 
			
		||||
	ctx, err := NewContext(*s, *i, uint64(f), etp)
 | 
			
		||||
	defer ctx.Delete()
 | 
			
		||||
	if ctx.Parser.Utf8Inv {
 | 
			
		||||
		*s = ctx.Parser.Json
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		goto fix_error;
 | 
			
		||||
	}
 | 
			
		||||
	err = dec.FromDom(vp, ctx.Root(), &ctx)
 | 
			
		||||
 | 
			
		||||
fix_error:
 | 
			
		||||
	err = fix_error(*s, *i, err)
 | 
			
		||||
 | 
			
		||||
	// update position at last
 | 
			
		||||
	*i += ctx.Parser.Pos()
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func fix_error(json string, pos int, err error) error {
 | 
			
		||||
	if e, ok := err.(SyntaxError); ok {
 | 
			
		||||
		return SyntaxError{
 | 
			
		||||
			Pos: int(e.Pos) + pos,
 | 
			
		||||
			Src: json,
 | 
			
		||||
			Msg: e.Msg,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if e, ok := err.(MismatchTypeError); ok {
 | 
			
		||||
		return &MismatchTypeError {
 | 
			
		||||
			Pos: int(e.Pos) + pos,
 | 
			
		||||
			Src: json,
 | 
			
		||||
			Type: e.Type,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Pretouch compiles vt ahead-of-time to avoid JIT compilation on-the-fly, in
 | 
			
		||||
// order to reduce the first-hit latency.
 | 
			
		||||
//
 | 
			
		||||
// Opts are the compile options, for example, "option.WithCompileRecursiveDepth" is
 | 
			
		||||
// a compile option to set the depth of recursive compile for the nested struct type.
 | 
			
		||||
func Pretouch(vt reflect.Type, opts ...option.CompileOption) error {
 | 
			
		||||
    cfg := option.DefaultCompileOptions()
 | 
			
		||||
    for _, opt := range opts {
 | 
			
		||||
        opt(&cfg)
 | 
			
		||||
    }
 | 
			
		||||
    return pretouchRec(map[reflect.Type]bool{vt:true}, cfg)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func pretouchType(_vt reflect.Type, opts option.CompileOptions) (map[reflect.Type]bool, error) {
 | 
			
		||||
    /* compile function */
 | 
			
		||||
    compiler := newCompiler().apply(opts)
 | 
			
		||||
    decoder := func(vt *rt.GoType, _ ...interface{}) (interface{}, error) {
 | 
			
		||||
        if f, err := compiler.compileType(_vt); err != nil {
 | 
			
		||||
            return nil, err
 | 
			
		||||
        } else {
 | 
			
		||||
            return f, nil
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* find or compile */
 | 
			
		||||
    vt := rt.UnpackType(_vt)
 | 
			
		||||
    if val := programCache.Get(vt); val != nil {
 | 
			
		||||
        return nil, nil
 | 
			
		||||
    } else if _, err := programCache.Compute(vt, decoder); err == nil {
 | 
			
		||||
        return compiler.visited, nil
 | 
			
		||||
    } else {
 | 
			
		||||
        return nil, err
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func pretouchRec(vtm map[reflect.Type]bool, opts option.CompileOptions) error {
 | 
			
		||||
    if opts.RecursiveDepth < 0 || len(vtm) == 0 {
 | 
			
		||||
        return nil
 | 
			
		||||
    }
 | 
			
		||||
    next := make(map[reflect.Type]bool)
 | 
			
		||||
    for vt := range(vtm) {
 | 
			
		||||
        sub, err := pretouchType(vt, opts)
 | 
			
		||||
        if err != nil {
 | 
			
		||||
            return err
 | 
			
		||||
        }
 | 
			
		||||
        for svt := range(sub) {
 | 
			
		||||
            next[svt] = true
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    opts.RecursiveDepth -= 1
 | 
			
		||||
    return pretouchRec(next, opts)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										73
									
								
								vendor/github.com/bytedance/sonic/internal/decoder/optdec/errors.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								vendor/github.com/bytedance/sonic/internal/decoder/optdec/errors.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,73 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2021 ByteDance Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 package optdec
 | 
			
		||||
 | 
			
		||||
 import (
 | 
			
		||||
	 "encoding/json"
 | 
			
		||||
	 "errors"
 | 
			
		||||
	 "reflect"
 | 
			
		||||
	 "strconv"
 | 
			
		||||
 
 | 
			
		||||
	 "github.com/bytedance/sonic/internal/rt"
 | 
			
		||||
 )
 | 
			
		||||
 | 
			
		||||
 /** JIT Error Helpers **/
 | 
			
		||||
 
 | 
			
		||||
 var stackOverflow = &json.UnsupportedValueError{
 | 
			
		||||
	 Str:   "Value nesting too deep",
 | 
			
		||||
	 Value: reflect.ValueOf("..."),
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 func error_type(vt *rt.GoType) error {
 | 
			
		||||
	 return &json.UnmarshalTypeError{Type: vt.Pack()}
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 func error_mismatch(node Node, ctx *context, typ reflect.Type) error {
 | 
			
		||||
	 return MismatchTypeError{
 | 
			
		||||
		 Pos:  node.Position(),
 | 
			
		||||
		 Src:  ctx.Parser.Json,
 | 
			
		||||
		 Type: typ,
 | 
			
		||||
	 }
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 func newUnmatched(pos int, vt *rt.GoType) error {
 | 
			
		||||
	 return MismatchTypeError{
 | 
			
		||||
		Pos:  pos,
 | 
			
		||||
		Src:  "",
 | 
			
		||||
		Type: vt.Pack(),
 | 
			
		||||
	 }
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 func error_field(name string) error {
 | 
			
		||||
	 return errors.New("json: unknown field " + strconv.Quote(name))
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 func error_value(value string, vtype reflect.Type) error {
 | 
			
		||||
	 return &json.UnmarshalTypeError{
 | 
			
		||||
		 Type:  vtype,
 | 
			
		||||
		 Value: value,
 | 
			
		||||
	 }
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 func error_syntax(pos int, src string, msg string) error {
 | 
			
		||||
	 return SyntaxError{
 | 
			
		||||
		 Pos: pos,
 | 
			
		||||
		 Src: src,
 | 
			
		||||
		 Msg: msg,
 | 
			
		||||
	 }
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										281
									
								
								vendor/github.com/bytedance/sonic/internal/decoder/optdec/functor.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										281
									
								
								vendor/github.com/bytedance/sonic/internal/decoder/optdec/functor.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,281 @@
 | 
			
		|||
package optdec
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"math"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
 | 
			
		||||
	"github.com/bytedance/sonic/internal/rt"
 | 
			
		||||
	"github.com/bytedance/sonic/internal/resolver"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type decFunc interface {
 | 
			
		||||
	FromDom(vp unsafe.Pointer, node Node, ctx *context) error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ptrDecoder struct {
 | 
			
		||||
	typ   *rt.GoType
 | 
			
		||||
	deref decFunc
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Pointer Value is allocated in the Caller
 | 
			
		||||
func (d *ptrDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		*(*unsafe.Pointer)(vp) = nil
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if *(*unsafe.Pointer)(vp) == nil {
 | 
			
		||||
		*(*unsafe.Pointer)(vp) = rt.Mallocgc(d.typ.Size, d.typ, true)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return d.deref.FromDom(*(*unsafe.Pointer)(vp), node, ctx)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type embeddedFieldPtrDecoder struct {
 | 
			
		||||
	field      resolver.FieldMeta
 | 
			
		||||
	fieldDec   decFunc
 | 
			
		||||
	fieldName  string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Pointer Value is allocated in the Caller
 | 
			
		||||
func (d *embeddedFieldPtrDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// seek into the pointer
 | 
			
		||||
	vp = unsafe.Pointer(uintptr(vp) - uintptr(d.field.Path[0].Size))
 | 
			
		||||
	for _, f := range d.field.Path {
 | 
			
		||||
		deref := rt.UnpackType(f.Type)
 | 
			
		||||
		vp = unsafe.Pointer(uintptr(vp) + f.Size)
 | 
			
		||||
		if f.Kind == resolver.F_deref {
 | 
			
		||||
			if  *(*unsafe.Pointer)(vp) == nil  {
 | 
			
		||||
				*(*unsafe.Pointer)(vp) = rt.Mallocgc(deref.Size, deref, true)
 | 
			
		||||
			}
 | 
			
		||||
			vp = *(*unsafe.Pointer)(vp)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return d.fieldDec.FromDom(vp, node, ctx)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type i8Decoder struct{}
 | 
			
		||||
 | 
			
		||||
func (d *i8Decoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret, ok := node.AsI64(ctx)
 | 
			
		||||
	if !ok ||  ret > math.MaxInt8 || ret < math.MinInt8 {
 | 
			
		||||
		return error_mismatch(node, ctx, int8Type)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(*int8)(vp) = int8(ret)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type i16Decoder struct{}
 | 
			
		||||
 | 
			
		||||
func (d *i16Decoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret, ok := node.AsI64(ctx)
 | 
			
		||||
	if !ok || ret > math.MaxInt16 || ret < math.MinInt16 {
 | 
			
		||||
		return error_mismatch(node, ctx, int16Type)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(*int16)(vp) = int16(ret)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type i32Decoder struct{}
 | 
			
		||||
 | 
			
		||||
func (d *i32Decoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret, ok := node.AsI64(ctx)
 | 
			
		||||
	if !ok ||  ret > math.MaxInt32 || ret < math.MinInt32 {
 | 
			
		||||
		return error_mismatch(node, ctx, int32Type)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(*int32)(vp) = int32(ret)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type i64Decoder struct{}
 | 
			
		||||
 | 
			
		||||
func (d *i64Decoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret, ok := node.AsI64(ctx)
 | 
			
		||||
	if !ok  {
 | 
			
		||||
		return error_mismatch(node, ctx, int64Type)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(*int64)(vp) = int64(ret)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type u8Decoder struct{}
 | 
			
		||||
 | 
			
		||||
func (d *u8Decoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret, ok := node.AsU64(ctx)
 | 
			
		||||
	if !ok || ret > math.MaxUint8 {
 | 
			
		||||
		err := error_mismatch(node, ctx, uint8Type)
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(*uint8)(vp) = uint8(ret)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type u16Decoder struct{}
 | 
			
		||||
 | 
			
		||||
func (d *u16Decoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret, ok := node.AsU64(ctx)
 | 
			
		||||
	if !ok || ret > math.MaxUint16 {
 | 
			
		||||
		return error_mismatch(node, ctx, uint16Type)
 | 
			
		||||
	}
 | 
			
		||||
	*(*uint16)(vp) = uint16(ret)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type u32Decoder struct{}
 | 
			
		||||
 | 
			
		||||
func (d *u32Decoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret, ok := node.AsU64(ctx)
 | 
			
		||||
	if !ok || ret > math.MaxUint32 {
 | 
			
		||||
		return error_mismatch(node, ctx, uint32Type)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(*uint32)(vp) = uint32(ret)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type u64Decoder struct{}
 | 
			
		||||
 | 
			
		||||
func (d *u64Decoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret, ok := node.AsU64(ctx)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return error_mismatch(node, ctx, uint64Type)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(*uint64)(vp) = uint64(ret)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type f32Decoder struct{}
 | 
			
		||||
 | 
			
		||||
func (d *f32Decoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret, ok := node.AsF64(ctx)
 | 
			
		||||
	if !ok || ret > math.MaxFloat32 || ret < -math.MaxFloat32 {
 | 
			
		||||
		return error_mismatch(node, ctx, float32Type)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(*float32)(vp) = float32(ret)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type f64Decoder struct{}
 | 
			
		||||
 | 
			
		||||
func (d *f64Decoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret, ok := node.AsF64(ctx)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return  error_mismatch(node, ctx, float64Type)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(*float64)(vp) = float64(ret)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type boolDecoder struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *boolDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret, ok := node.AsBool()
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return error_mismatch(node, ctx, boolType)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(*bool)(vp) = bool(ret)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type stringDecoder struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *stringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret, ok := node.AsStr(ctx)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return error_mismatch(node, ctx, stringType)
 | 
			
		||||
	}
 | 
			
		||||
	*(*string)(vp) = ret
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type numberDecoder struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *numberDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	num, ok := node.AsNumber(ctx)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return error_mismatch(node, ctx, jsonNumberType)
 | 
			
		||||
	}
 | 
			
		||||
	*(*json.Number)(vp) = num
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type recuriveDecoder struct {
 | 
			
		||||
	typ *rt.GoType
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *recuriveDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	dec, err := findOrCompile(d.typ)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return dec.FromDom(vp, node, ctx)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										110
									
								
								vendor/github.com/bytedance/sonic/internal/decoder/optdec/helper.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								vendor/github.com/bytedance/sonic/internal/decoder/optdec/helper.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,110 @@
 | 
			
		|||
package optdec
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"strconv"
 | 
			
		||||
 | 
			
		||||
	"github.com/bytedance/sonic/internal/native"
 | 
			
		||||
	"github.com/bytedance/sonic/internal/utils"
 | 
			
		||||
	"github.com/bytedance/sonic/internal/native/types"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
func SkipNumberFast(json string, start int) (int, bool) {
 | 
			
		||||
	// find the number ending, we pasred in native, it alway valid
 | 
			
		||||
	pos := start
 | 
			
		||||
	for pos < len(json) && json[pos] != ']' && json[pos] != '}' && json[pos] != ',' {
 | 
			
		||||
		if json[pos] >= '0' && json[pos] <= '9' || json[pos] == '.' || json[pos] == '-' || json[pos] == '+' || json[pos] == 'e' || json[pos] == 'E' {
 | 
			
		||||
			pos += 1
 | 
			
		||||
		} else {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// if not found number, return false
 | 
			
		||||
	if pos == start {
 | 
			
		||||
		return pos, false
 | 
			
		||||
	}
 | 
			
		||||
	return pos, true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
func isSpace(c byte) bool {
 | 
			
		||||
    return c == ' ' || c == '\t' || c == '\n' || c == '\r'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// pos is the start index of the raw
 | 
			
		||||
func ValidNumberFast(raw string) bool {
 | 
			
		||||
	ret := utils.SkipNumber(raw, 0)
 | 
			
		||||
	if ret < 0 {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// check trainling chars
 | 
			
		||||
	for ret < len(raw) {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func SkipOneFast2(json string, pos *int) (int, error) {
 | 
			
		||||
	// find the number ending, we pasred in sonic-cpp, it alway valid
 | 
			
		||||
	start := native.SkipOneFast(&json, pos)
 | 
			
		||||
	if start < 0 {
 | 
			
		||||
		return -1, error_syntax(*pos, json, types.ParsingError(-start).Error())
 | 
			
		||||
	}
 | 
			
		||||
	return start, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func SkipOneFast(json string, pos int) (string, error) {
 | 
			
		||||
	// find the number ending, we pasred in sonic-cpp, it alway valid
 | 
			
		||||
	start := native.SkipOneFast(&json, &pos)
 | 
			
		||||
	if start < 0 {
 | 
			
		||||
		// TODO: details error code
 | 
			
		||||
		return "", error_syntax(pos, json, types.ParsingError(-start).Error())
 | 
			
		||||
	}
 | 
			
		||||
	return json[start:pos], nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ParseI64(raw string) (int64, error) {
 | 
			
		||||
	i64, err := strconv.ParseInt(raw, 10, 64)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return 0, err
 | 
			
		||||
	}
 | 
			
		||||
	return i64, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ParseBool(raw string) (bool, error) {
 | 
			
		||||
	var b bool
 | 
			
		||||
	err := json.Unmarshal([]byte(raw), &b)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return false, err
 | 
			
		||||
	}
 | 
			
		||||
	return b, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ParseU64(raw string) (uint64, error) {
 | 
			
		||||
	u64, err := strconv.ParseUint(raw, 10, 64)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return 0, err
 | 
			
		||||
	}
 | 
			
		||||
	return u64, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ParseF64(raw string) (float64, error) {
 | 
			
		||||
	f64, err := strconv.ParseFloat(raw, 64)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return 0, err
 | 
			
		||||
	}
 | 
			
		||||
	return f64, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Unquote(raw string) (string, error) {
 | 
			
		||||
	var u string
 | 
			
		||||
	err := json.Unmarshal([]byte(raw), &u)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	return u, nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										169
									
								
								vendor/github.com/bytedance/sonic/internal/decoder/optdec/interface.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								vendor/github.com/bytedance/sonic/internal/decoder/optdec/interface.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,169 @@
 | 
			
		|||
package optdec
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
	"reflect"
 | 
			
		||||
 | 
			
		||||
	"github.com/bytedance/sonic/internal/rt"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type efaceDecoder struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *efaceDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		*(*interface{})(vp) = interface{}(nil)
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	eface := *(*rt.GoEface)(vp)
 | 
			
		||||
 | 
			
		||||
	// not pointer type, or nil pointer, or *interface{}
 | 
			
		||||
	if eface.Value == nil || eface.Type.Kind() != reflect.Ptr || rt.PtrElem(eface.Type) == anyType {
 | 
			
		||||
		ret, err := node.AsEface(ctx)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	
 | 
			
		||||
		*(*interface{})(vp) = ret
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	etp := rt.PtrElem(eface.Type)
 | 
			
		||||
	vp = eface.Value
 | 
			
		||||
 | 
			
		||||
	/* check the defined pointer type for issue 379 */
 | 
			
		||||
	if eface.Type.IsNamed() {
 | 
			
		||||
		newp := vp
 | 
			
		||||
		etp = eface.Type
 | 
			
		||||
		vp = unsafe.Pointer(&newp)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dec, err := findOrCompile(etp)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return dec.FromDom(vp, node, ctx)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ifaceDecoder struct {
 | 
			
		||||
	typ *rt.GoType
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *ifaceDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		*(*unsafe.Pointer)(vp) = nil
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	iface := *(*rt.GoIface)(vp)
 | 
			
		||||
	if iface.Itab == nil {
 | 
			
		||||
		return error_type(d.typ)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	vt := iface.Itab.Vt
 | 
			
		||||
 | 
			
		||||
	// not pointer type, or nil pointer, or *interface{}
 | 
			
		||||
	if vp == nil || vt.Kind() != reflect.Ptr || rt.PtrElem(vt) == anyType {
 | 
			
		||||
		ret, err := node.AsEface(ctx)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	
 | 
			
		||||
		*(*interface{})(vp) = ret
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	etp := rt.PtrElem(vt)
 | 
			
		||||
	vp = iface.Value
 | 
			
		||||
 | 
			
		||||
	/* check the defined pointer type for issue 379 */
 | 
			
		||||
	if vt.IsNamed() {
 | 
			
		||||
		newp := vp
 | 
			
		||||
		etp = vt
 | 
			
		||||
		vp = unsafe.Pointer(&newp)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dec, err := findOrCompile(etp)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return dec.FromDom(vp, node, ctx)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type unmarshalTextDecoder struct {
 | 
			
		||||
	typ *rt.GoType
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *unmarshalTextDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		*(*unsafe.Pointer)(vp) = nil
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	txt, ok := node.AsStringText(ctx)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return error_mismatch(node, ctx, d.typ.Pack())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	v := *(*interface{})(unsafe.Pointer(&rt.GoEface{
 | 
			
		||||
		Type:  d.typ,
 | 
			
		||||
		Value: vp,
 | 
			
		||||
	}))
 | 
			
		||||
 | 
			
		||||
	// fast path
 | 
			
		||||
	if u, ok :=  v.(encoding.TextUnmarshaler); ok {
 | 
			
		||||
		return u.UnmarshalText(txt)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// slow path
 | 
			
		||||
	rv := reflect.ValueOf(v)
 | 
			
		||||
	if u, ok := rv.Interface().(encoding.TextUnmarshaler); ok {
 | 
			
		||||
		return u.UnmarshalText(txt)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return error_type(d.typ)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type unmarshalJSONDecoder struct {
 | 
			
		||||
	typ 	*rt.GoType
 | 
			
		||||
	strOpt	bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *unmarshalJSONDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	v := *(*interface{})(unsafe.Pointer(&rt.GoEface{
 | 
			
		||||
		Type: d.typ,
 | 
			
		||||
		Value: vp,
 | 
			
		||||
	}))
 | 
			
		||||
 | 
			
		||||
	var input []byte
 | 
			
		||||
	if d.strOpt && node.IsNull() {
 | 
			
		||||
		input = []byte("null")
 | 
			
		||||
	} else if d.strOpt {
 | 
			
		||||
		s, ok := node.AsStringText(ctx)
 | 
			
		||||
		if !ok {
 | 
			
		||||
			return error_mismatch(node, ctx, d.typ.Pack())
 | 
			
		||||
		}
 | 
			
		||||
		input = s
 | 
			
		||||
	} else {
 | 
			
		||||
		input = []byte(node.AsRaw(ctx))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// fast path
 | 
			
		||||
	if u, ok :=  v.(json.Unmarshaler); ok {
 | 
			
		||||
		return u.UnmarshalJSON((input))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// slow path
 | 
			
		||||
	rv := reflect.ValueOf(v)
 | 
			
		||||
	if u, ok := rv.Interface().(json.Unmarshaler); ok {
 | 
			
		||||
		return u.UnmarshalJSON(input)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return error_type(d.typ)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										430
									
								
								vendor/github.com/bytedance/sonic/internal/decoder/optdec/map.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										430
									
								
								vendor/github.com/bytedance/sonic/internal/decoder/optdec/map.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,430 @@
 | 
			
		|||
package optdec
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"math"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
 | 
			
		||||
	"github.com/bytedance/sonic/internal/rt"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
/** Decoder for most common map types: map[string]interface{}, map[string]string **/
 | 
			
		||||
 | 
			
		||||
type mapEfaceDecoder struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *mapEfaceDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		*(*map[string]interface{})(vp) = nil
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return node.AsMapEface(ctx, vp)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type mapStringDecoder struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *mapStringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		*(*map[string]string)(vp) = nil
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return node.AsMapString(ctx, vp)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Decoder for map with string key **/
 | 
			
		||||
 | 
			
		||||
type mapStrKeyDecoder struct {
 | 
			
		||||
	mapType *rt.GoMapType
 | 
			
		||||
	elemDec decFunc
 | 
			
		||||
	assign  rt.MapStrAssign
 | 
			
		||||
	typ 	reflect.Type
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *mapStrKeyDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		*(*unsafe.Pointer)(vp) = nil
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	obj, ok := node.AsObj()
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return error_mismatch(node, ctx, d.mapType.Pack())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// allocate map
 | 
			
		||||
	m := *(*unsafe.Pointer)(vp)
 | 
			
		||||
	if m == nil {
 | 
			
		||||
		m = rt.Makemap(&d.mapType.GoType, obj.Len())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var gerr error
 | 
			
		||||
	next := obj.Children()
 | 
			
		||||
	for i := 0; i < obj.Len(); i++ {
 | 
			
		||||
		keyn := NewNode(next)
 | 
			
		||||
		key, _ := keyn.AsStr(ctx)
 | 
			
		||||
 | 
			
		||||
		valn := NewNode(PtrOffset(next, 1))
 | 
			
		||||
		valp := d.assign(d.mapType, m, key)
 | 
			
		||||
		err := d.elemDec.FromDom(valp, valn, ctx)
 | 
			
		||||
		if gerr == nil && err != nil {
 | 
			
		||||
			gerr = err
 | 
			
		||||
		}
 | 
			
		||||
		next = valn.Next()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(*unsafe.Pointer)(vp) = m
 | 
			
		||||
	return gerr
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Decoder for map with int32 or int64 key **/
 | 
			
		||||
 | 
			
		||||
type mapI32KeyDecoder struct {
 | 
			
		||||
	mapType *rt.GoMapType
 | 
			
		||||
	elemDec decFunc
 | 
			
		||||
	assign rt.Map32Assign
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *mapI32KeyDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		*(*unsafe.Pointer)(vp) = nil
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	obj, ok := node.AsObj()
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return error_mismatch(node, ctx, d.mapType.Pack())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// allocate map
 | 
			
		||||
	m := *(*unsafe.Pointer)(vp)
 | 
			
		||||
	if m == nil {
 | 
			
		||||
		m = rt.Makemap(&d.mapType.GoType, obj.Len())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	next := obj.Children()
 | 
			
		||||
	var gerr error
 | 
			
		||||
	for i := 0; i < obj.Len(); i++ {
 | 
			
		||||
		keyn := NewNode(next)
 | 
			
		||||
		k, ok := keyn.ParseI64(ctx)
 | 
			
		||||
		if !ok || k > math.MaxInt32 || k < math.MinInt32 {
 | 
			
		||||
			if gerr == nil {
 | 
			
		||||
				gerr = error_mismatch(keyn, ctx, d.mapType.Pack())
 | 
			
		||||
			}
 | 
			
		||||
			valn := NewNode(PtrOffset(next, 1))
 | 
			
		||||
			next = valn.Next()
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		key := int32(k)
 | 
			
		||||
		ku32 := *(*uint32)(unsafe.Pointer(&key))
 | 
			
		||||
		valn := NewNode(PtrOffset(next, 1))
 | 
			
		||||
		valp := d.assign(d.mapType, m, ku32)
 | 
			
		||||
		err := d.elemDec.FromDom(valp, valn, ctx)
 | 
			
		||||
		if gerr == nil && err != nil {
 | 
			
		||||
			gerr = err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		next = valn.Next()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(*unsafe.Pointer)(vp) = m
 | 
			
		||||
	return gerr
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type mapI64KeyDecoder struct {
 | 
			
		||||
	mapType *rt.GoMapType
 | 
			
		||||
	elemDec decFunc
 | 
			
		||||
	assign rt.Map64Assign
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *mapI64KeyDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		*(*unsafe.Pointer)(vp) = nil
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	obj, ok := node.AsObj()
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return error_mismatch(node, ctx, d.mapType.Pack())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// allocate map
 | 
			
		||||
	m := *(*unsafe.Pointer)(vp)
 | 
			
		||||
	if m == nil {
 | 
			
		||||
		m = rt.Makemap(&d.mapType.GoType, obj.Len())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var gerr error
 | 
			
		||||
	next := obj.Children()
 | 
			
		||||
	for i := 0; i < obj.Len(); i++ {
 | 
			
		||||
		keyn := NewNode(next)
 | 
			
		||||
		key, ok := keyn.ParseI64(ctx)
 | 
			
		||||
 | 
			
		||||
		if !ok {
 | 
			
		||||
			if gerr == nil {
 | 
			
		||||
				gerr = error_mismatch(keyn, ctx, d.mapType.Pack())
 | 
			
		||||
			}
 | 
			
		||||
			valn := NewNode(PtrOffset(next, 1))
 | 
			
		||||
			next = valn.Next()
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ku64 := *(*uint64)(unsafe.Pointer(&key))
 | 
			
		||||
		valn := NewNode(PtrOffset(next, 1))
 | 
			
		||||
		valp := d.assign(d.mapType, m, ku64)
 | 
			
		||||
		err := d.elemDec.FromDom(valp, valn, ctx)
 | 
			
		||||
		if gerr == nil && err != nil {
 | 
			
		||||
			gerr = err
 | 
			
		||||
		}
 | 
			
		||||
		next = valn.Next()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(*unsafe.Pointer)(vp) = m
 | 
			
		||||
	return gerr
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Decoder for map with unt32 or uint64 key **/
 | 
			
		||||
 | 
			
		||||
type mapU32KeyDecoder struct {
 | 
			
		||||
	mapType *rt.GoMapType
 | 
			
		||||
	elemDec decFunc
 | 
			
		||||
	assign  rt.Map32Assign
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *mapU32KeyDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		*(*unsafe.Pointer)(vp) = nil
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	obj, ok := node.AsObj()
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return error_mismatch(node, ctx, d.mapType.Pack())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// allocate map
 | 
			
		||||
	m := *(*unsafe.Pointer)(vp)
 | 
			
		||||
	if m == nil {
 | 
			
		||||
		m = rt.Makemap(&d.mapType.GoType, obj.Len())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var gerr error
 | 
			
		||||
	next := obj.Children()
 | 
			
		||||
	for i := 0; i < obj.Len(); i++ {
 | 
			
		||||
		keyn := NewNode(next)
 | 
			
		||||
		k, ok := keyn.ParseU64(ctx)
 | 
			
		||||
		if !ok || k > math.MaxUint32 {
 | 
			
		||||
			if gerr == nil {
 | 
			
		||||
				gerr = error_mismatch(keyn, ctx, d.mapType.Pack())
 | 
			
		||||
			}
 | 
			
		||||
			valn := NewNode(PtrOffset(next, 1))
 | 
			
		||||
			next = valn.Next()
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		key := uint32(k)
 | 
			
		||||
		valn := NewNode(PtrOffset(next, 1))
 | 
			
		||||
		valp := d.assign(d.mapType, m, key)
 | 
			
		||||
		err := d.elemDec.FromDom(valp, valn, ctx)
 | 
			
		||||
		if gerr == nil && err != nil {
 | 
			
		||||
			gerr = err
 | 
			
		||||
		}
 | 
			
		||||
		next = valn.Next()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(*unsafe.Pointer)(vp) = m
 | 
			
		||||
	return gerr
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type mapU64KeyDecoder struct {
 | 
			
		||||
	mapType *rt.GoMapType
 | 
			
		||||
	elemDec decFunc
 | 
			
		||||
	assign rt.Map64Assign
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *mapU64KeyDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		*(*unsafe.Pointer)(vp) = nil
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	obj, ok := node.AsObj()
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return  error_mismatch(node, ctx, d.mapType.Pack())
 | 
			
		||||
	}
 | 
			
		||||
	// allocate map
 | 
			
		||||
	m := *(*unsafe.Pointer)(vp)
 | 
			
		||||
	if m == nil {
 | 
			
		||||
		m = rt.Makemap(&d.mapType.GoType, obj.Len())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var gerr error
 | 
			
		||||
	next := obj.Children()
 | 
			
		||||
	for i := 0; i < obj.Len(); i++ {
 | 
			
		||||
		keyn := NewNode(next)
 | 
			
		||||
		key, ok := keyn.ParseU64(ctx)
 | 
			
		||||
		if !ok {
 | 
			
		||||
			if gerr == nil {
 | 
			
		||||
				gerr = error_mismatch(keyn, ctx, d.mapType.Pack())
 | 
			
		||||
			}
 | 
			
		||||
			valn := NewNode(PtrOffset(next, 1))
 | 
			
		||||
			next = valn.Next()
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		valn := NewNode(PtrOffset(next, 1))
 | 
			
		||||
		valp := d.assign(d.mapType, m, key)
 | 
			
		||||
		err := d.elemDec.FromDom(valp, valn, ctx)
 | 
			
		||||
		if gerr == nil && err != nil {
 | 
			
		||||
			gerr = err
 | 
			
		||||
		}
 | 
			
		||||
		next = valn.Next()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(*unsafe.Pointer)(vp) = m
 | 
			
		||||
	return gerr
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Decoder for generic cases */
 | 
			
		||||
 | 
			
		||||
type decKey func(dec *mapDecoder, raw string, ctx *context) (interface{}, error)
 | 
			
		||||
 | 
			
		||||
func decodeKeyU8(dec *mapDecoder, raw string, ctx *context) (interface{}, error) {
 | 
			
		||||
	key, err := Unquote(raw)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	ret, err := ParseU64(key)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if ret > math.MaxUint8 {
 | 
			
		||||
		return nil, error_value(key, dec.mapType.Key.Pack())
 | 
			
		||||
	}
 | 
			
		||||
	return uint8(ret), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func decodeKeyU16(dec *mapDecoder, raw string, ctx *context) (interface{}, error) {
 | 
			
		||||
	key, err := Unquote(raw)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	ret, err := ParseU64(key)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if ret > math.MaxUint16 {
 | 
			
		||||
		return nil, error_value(key, dec.mapType.Key.Pack())
 | 
			
		||||
	}
 | 
			
		||||
	return uint16(ret), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func decodeKeyI8(dec *mapDecoder, raw string, ctx *context) (interface{}, error) {
 | 
			
		||||
	key, err := Unquote(raw)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	ret, err := ParseI64(key)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if ret > math.MaxInt8 || ret < math.MinInt8 {
 | 
			
		||||
		return nil, error_value(key, dec.mapType.Key.Pack())
 | 
			
		||||
	}
 | 
			
		||||
	return int8(ret), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func decodeKeyI16(dec *mapDecoder, raw string, ctx *context) (interface{}, error) {
 | 
			
		||||
	key, err := Unquote(raw)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	ret, err := ParseI64(key)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if ret > math.MaxInt16 || ret < math.MinInt16 {
 | 
			
		||||
		return nil, error_value(key, dec.mapType.Key.Pack())
 | 
			
		||||
	}
 | 
			
		||||
	return int16(ret), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func decodeKeyJSONUnmarshaler(dec *mapDecoder, raw string, _ *context) (interface{}, error) {
 | 
			
		||||
	ret := reflect.New(dec.mapType.Key.Pack()).Interface()
 | 
			
		||||
	err := ret.(json.Unmarshaler).UnmarshalJSON([]byte(raw))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return ret, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func decodeKeyTextUnmarshaler(dec *mapDecoder, raw string, ctx *context) (interface{}, error) {
 | 
			
		||||
	key, err := Unquote(raw)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	ret := reflect.New(dec.mapType.Key.Pack()).Interface()
 | 
			
		||||
	err = ret.(encoding.TextUnmarshaler).UnmarshalText([]byte(key))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return ret, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type mapDecoder struct {
 | 
			
		||||
	mapType *rt.GoMapType
 | 
			
		||||
	keyDec  decKey
 | 
			
		||||
	elemDec decFunc
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *mapDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		*(*unsafe.Pointer)(vp) = nil
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	obj, ok := node.AsObj()
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return	error_mismatch(node, ctx, d.mapType.Pack())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// allocate map
 | 
			
		||||
	m := *(*unsafe.Pointer)(vp)
 | 
			
		||||
	if m == nil {
 | 
			
		||||
		m = rt.Makemap(&d.mapType.GoType, obj.Len())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	next := obj.Children()
 | 
			
		||||
	var gerr error
 | 
			
		||||
	for i := 0; i < obj.Len(); i++ {
 | 
			
		||||
		keyn := NewNode(next)
 | 
			
		||||
		raw := keyn.AsRaw(ctx)
 | 
			
		||||
		key, err := d.keyDec(d, raw, ctx)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			if gerr == nil {
 | 
			
		||||
				gerr = error_mismatch(keyn, ctx, d.mapType.Pack())
 | 
			
		||||
			}
 | 
			
		||||
			valn := NewNode(PtrOffset(next, 1))
 | 
			
		||||
			next = valn.Next()
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		valn := NewNode(PtrOffset(next, 1))
 | 
			
		||||
		keyp := rt.UnpackEface(key).Value
 | 
			
		||||
		valp := rt.Mapassign(d.mapType, m, keyp)
 | 
			
		||||
		err = d.elemDec.FromDom(valp, valn, ctx)
 | 
			
		||||
		if gerr == nil && err != nil {
 | 
			
		||||
			gerr = err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		next = valn.Next()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(*unsafe.Pointer)(vp) = m
 | 
			
		||||
	return gerr
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										269
									
								
								vendor/github.com/bytedance/sonic/internal/decoder/optdec/native.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										269
									
								
								vendor/github.com/bytedance/sonic/internal/decoder/optdec/native.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,269 @@
 | 
			
		|||
package optdec
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"github.com/bytedance/sonic/internal/native"
 | 
			
		||||
	"github.com/bytedance/sonic/internal/native/types"
 | 
			
		||||
	"github.com/bytedance/sonic/internal/rt"
 | 
			
		||||
	"github.com/bytedance/sonic/utf8"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
type ErrorCode int
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	SONIC_OK                = 0;
 | 
			
		||||
	SONIC_CONTROL_CHAR      = 1;
 | 
			
		||||
	SONIC_INVALID_ESCAPED   = 2;
 | 
			
		||||
	SONIC_INVALID_NUM       = 3;
 | 
			
		||||
	SONIC_FLOAT_INF         = 4;
 | 
			
		||||
	SONIC_EOF               = 5;
 | 
			
		||||
	SONIC_INVALID_CHAR   	= 6;
 | 
			
		||||
	SONIC_EXPECT_KEY        = 7;
 | 
			
		||||
	SONIC_EXPECT_COLON      = 8;
 | 
			
		||||
	SONIC_EXPECT_OBJ_COMMA_OR_END  = 9;
 | 
			
		||||
	SONIC_EXPECT_ARR_COMMA_OR_END  = 10;
 | 
			
		||||
	SONIC_VISIT_FAILED        = 11;
 | 
			
		||||
	SONIC_INVALID_ESCAPED_UTF = 12;
 | 
			
		||||
	SONIC_INVALID_LITERAL 	  = 13;
 | 
			
		||||
	SONIC_STACK_OVERFLOW	  = 14;
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var ParsingErrors = []string{
 | 
			
		||||
    SONIC_OK                      	: "ok",
 | 
			
		||||
	SONIC_CONTROL_CHAR      	  	: "control chars in string",
 | 
			
		||||
	SONIC_INVALID_ESCAPED 		  	: "invalid escaped chars in string",
 | 
			
		||||
	SONIC_INVALID_NUM       		: "invalid number",
 | 
			
		||||
	SONIC_FLOAT_INF         		: "float infinity",
 | 
			
		||||
	SONIC_EOF               		: "eof",
 | 
			
		||||
	SONIC_INVALID_CHAR		  		: "invalid chars",
 | 
			
		||||
	SONIC_EXPECT_KEY        		: "expect a json key",
 | 
			
		||||
	SONIC_EXPECT_COLON      		: "expect a `:`",
 | 
			
		||||
	SONIC_EXPECT_OBJ_COMMA_OR_END	: "expect a `,` or `}`",
 | 
			
		||||
	SONIC_EXPECT_ARR_COMMA_OR_END	: "expect a `,` or `]`",
 | 
			
		||||
	SONIC_VISIT_FAILED     			: "failed in json visitor",
 | 
			
		||||
	SONIC_INVALID_ESCAPED_UTF		: "invalid escaped unicodes",
 | 
			
		||||
	SONIC_INVALID_LITERAL			: "invalid literal(true/false/null)",
 | 
			
		||||
	SONIC_STACK_OVERFLOW			: "json is exceeded max depth 4096, cause stack overflow",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (code ErrorCode) Error() string {
 | 
			
		||||
	return ParsingErrors[code]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type node struct {
 | 
			
		||||
	typ uint64
 | 
			
		||||
	val uint64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// should consitent with native/parser.c
 | 
			
		||||
type _nospaceBlock struct {
 | 
			
		||||
	_ [8]byte
 | 
			
		||||
	_ [8]byte
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// should consitent with native/parser.c
 | 
			
		||||
type nodeBuf struct {
 | 
			
		||||
	ncur    uintptr
 | 
			
		||||
	parent  int64
 | 
			
		||||
	depth   uint64
 | 
			
		||||
	nstart  uintptr
 | 
			
		||||
	nend    uintptr
 | 
			
		||||
	stat    jsonStat
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (self *nodeBuf) init(nodes []node) {
 | 
			
		||||
	self.ncur = uintptr(unsafe.Pointer(&nodes[0]))
 | 
			
		||||
	self.nstart = self.ncur
 | 
			
		||||
	self.nend = self.ncur + uintptr(cap(nodes)) * unsafe.Sizeof(node{})
 | 
			
		||||
	self.parent = -1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// should consitent with native/parser.c
 | 
			
		||||
type Parser struct {
 | 
			
		||||
	Json    string
 | 
			
		||||
	padded	[]byte
 | 
			
		||||
	nodes 	[]node
 | 
			
		||||
	dbuf 	[]byte
 | 
			
		||||
	backup  []node
 | 
			
		||||
 | 
			
		||||
	options uint64
 | 
			
		||||
	// JSON cursor
 | 
			
		||||
	start   uintptr
 | 
			
		||||
	cur     uintptr
 | 
			
		||||
	end     uintptr
 | 
			
		||||
	_nbk    _nospaceBlock
 | 
			
		||||
 | 
			
		||||
	// node buffer cursor
 | 
			
		||||
	nbuf   	nodeBuf
 | 
			
		||||
	Utf8Inv  	bool
 | 
			
		||||
	isEface    bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// only when parse non-empty object/array are needed.
 | 
			
		||||
type jsonStat struct {
 | 
			
		||||
    object 		uint32
 | 
			
		||||
    array 		uint32
 | 
			
		||||
    str 		uint32
 | 
			
		||||
    number 		uint32
 | 
			
		||||
    array_elems uint32
 | 
			
		||||
    object_keys uint32
 | 
			
		||||
    max_depth	uint32
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	defaultJsonPaddedCap uintptr =  1 << 20  // 1 Mb
 | 
			
		||||
	defaultNodesCap      uintptr =  (1 << 20) / unsafe.Sizeof(node{})  // 1 Mb
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var parsePool sync.Pool = sync.Pool {
 | 
			
		||||
	New: func () interface{} {
 | 
			
		||||
		return &Parser{
 | 
			
		||||
			options: 0,
 | 
			
		||||
			padded: make([]byte, 0, defaultJsonPaddedCap),
 | 
			
		||||
			nodes: make([]node, defaultNodesCap, defaultNodesCap),
 | 
			
		||||
			dbuf: make([]byte, types.MaxDigitNums, types.MaxDigitNums),
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var padding string = "x\"x\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
 | 
			
		||||
 | 
			
		||||
func newParser(data string, pos int, opt uint64) *Parser {
 | 
			
		||||
	p := parsePool.Get().(*Parser)
 | 
			
		||||
 | 
			
		||||
	/* validate json if needed */
 | 
			
		||||
	if (opt & (1 << _F_validate_string)) != 0  && !utf8.ValidateString(data){
 | 
			
		||||
		dbuf := utf8.CorrectWith(nil, rt.Str2Mem(data[pos:]), "\ufffd")
 | 
			
		||||
		dbuf = append(dbuf, padding...)
 | 
			
		||||
		p.Json = rt.Mem2Str(dbuf[:len(dbuf) - len(padding)])
 | 
			
		||||
		p.Utf8Inv = true
 | 
			
		||||
		p.start = uintptr((*rt.GoString)(unsafe.Pointer(&p.Json)).Ptr)
 | 
			
		||||
	} else {
 | 
			
		||||
		p.Json = data
 | 
			
		||||
		// TODO: prevent too large JSON
 | 
			
		||||
		p.padded = append(p.padded, data[pos:]...)
 | 
			
		||||
		p.padded = append(p.padded, padding...)
 | 
			
		||||
		p.start = uintptr((*rt.GoSlice)(unsafe.Pointer(&p.padded)).Ptr)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	p.cur 	= p.start
 | 
			
		||||
	p.end   = p.cur + uintptr(len(p.Json))
 | 
			
		||||
	p.options = opt
 | 
			
		||||
	p.nbuf.init(p.nodes)
 | 
			
		||||
	return p
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
func (p *Parser) Pos() int {
 | 
			
		||||
	return int(p.cur - p.start)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *Parser) JsonBytes() []byte {
 | 
			
		||||
	if p.Utf8Inv {
 | 
			
		||||
		return (rt.Str2Mem(p.Json))
 | 
			
		||||
	} else {
 | 
			
		||||
		return p.padded
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var nodeType = rt.UnpackType(reflect.TypeOf(node{}))
 | 
			
		||||
 | 
			
		||||
//go:inline
 | 
			
		||||
func calMaxNodeCap(jsonSize int) int {
 | 
			
		||||
	return jsonSize / 2 + 2
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *Parser) parse() ErrorCode {
 | 
			
		||||
	// when decode into struct, we should decode number as possible
 | 
			
		||||
	old := p.options
 | 
			
		||||
	if !p.isEface {
 | 
			
		||||
		p.options &^= 1 << _F_use_number
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// fast path with limited node buffer
 | 
			
		||||
	err := ErrorCode(native.ParseWithPadding(unsafe.Pointer(p)))
 | 
			
		||||
	if err != SONIC_VISIT_FAILED {
 | 
			
		||||
		p.options = old
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// check OoB here
 | 
			
		||||
	offset := p.nbuf.ncur - p.nbuf.nstart
 | 
			
		||||
	curLen :=  offset / unsafe.Sizeof(node{})
 | 
			
		||||
	if curLen != uintptr(len(p.nodes)) {
 | 
			
		||||
		panic(fmt.Sprintf("current len: %d, real len: %d cap: %d", curLen, len(p.nodes), cap(p.nodes)))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// node buf is not enough, continue parse
 | 
			
		||||
	// the maxCap is always meet all valid JSON
 | 
			
		||||
	maxCap := calMaxNodeCap(len(p.Json))
 | 
			
		||||
	slice := rt.GoSlice{
 | 
			
		||||
		Ptr: rt.Mallocgc(uintptr(maxCap) * nodeType.Size, nodeType, false),
 | 
			
		||||
		Len: maxCap,
 | 
			
		||||
		Cap: maxCap,
 | 
			
		||||
	}
 | 
			
		||||
	rt.Memmove(unsafe.Pointer(slice.Ptr), unsafe.Pointer(&p.nodes[0]), offset)
 | 
			
		||||
	p.backup = p.nodes
 | 
			
		||||
	p.nodes = *(*[]node)(unsafe.Pointer(&slice))
 | 
			
		||||
 | 
			
		||||
	// update node cursor
 | 
			
		||||
	p.nbuf.nstart = uintptr(unsafe.Pointer(&p.nodes[0]))
 | 
			
		||||
	p.nbuf.nend = p.nbuf.nstart + uintptr(cap(p.nodes)) * unsafe.Sizeof(node{})
 | 
			
		||||
	p.nbuf.ncur = p.nbuf.nstart + offset
 | 
			
		||||
 | 
			
		||||
	// continue parse json
 | 
			
		||||
	err = ErrorCode(native.ParseWithPadding(unsafe.Pointer(p)))
 | 
			
		||||
	p.options = old
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *Parser) reset() {
 | 
			
		||||
	p.options = 0
 | 
			
		||||
	p.padded = p.padded[:0]
 | 
			
		||||
	// nodes is too large here, we will not reset it and use small backup nodes buffer
 | 
			
		||||
	if p.backup != nil {
 | 
			
		||||
		p.nodes = p.backup
 | 
			
		||||
		p.backup = nil
 | 
			
		||||
	}
 | 
			
		||||
	p.start = 0
 | 
			
		||||
	p.cur = 0
 | 
			
		||||
	p.end = 0
 | 
			
		||||
	p.Json = ""
 | 
			
		||||
	p.nbuf = nodeBuf{}
 | 
			
		||||
	p._nbk = _nospaceBlock{}
 | 
			
		||||
	p.Utf8Inv = false
 | 
			
		||||
	p.isEface = false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *Parser) free() {
 | 
			
		||||
	p.reset()
 | 
			
		||||
	parsePool.Put(p)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//go:noinline
 | 
			
		||||
func (p *Parser) fixError(code ErrorCode) error {
 | 
			
		||||
	if code == SONIC_OK {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if p.Pos() == 0 {
 | 
			
		||||
		code = SONIC_EOF;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pos := p.Pos() - 1
 | 
			
		||||
	return error_syntax(pos, p.Json, ParsingErrors[code])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Parse(data string, opt uint64) error {
 | 
			
		||||
	p := newParser(data, 0, opt)
 | 
			
		||||
	err := p.parse()
 | 
			
		||||
	p.free()
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1278
									
								
								vendor/github.com/bytedance/sonic/internal/decoder/optdec/node.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1278
									
								
								vendor/github.com/bytedance/sonic/internal/decoder/optdec/node.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										224
									
								
								vendor/github.com/bytedance/sonic/internal/decoder/optdec/slice.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										224
									
								
								vendor/github.com/bytedance/sonic/internal/decoder/optdec/slice.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,224 @@
 | 
			
		|||
package optdec
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
 | 
			
		||||
	"github.com/bytedance/sonic/internal/rt"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type sliceDecoder struct {
 | 
			
		||||
	elemType *rt.GoType
 | 
			
		||||
	elemDec  decFunc
 | 
			
		||||
	typ      reflect.Type
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	emptyPtr = &struct{}{}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (d *sliceDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		*(*rt.GoSlice)(vp) = rt.GoSlice{}
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	arr, ok := node.AsArr()
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return error_mismatch(node, ctx, d.typ)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	slice := rt.MakeSlice(vp, d.elemType, arr.Len())
 | 
			
		||||
	elems := slice.Ptr
 | 
			
		||||
	next := arr.Children()
 | 
			
		||||
 | 
			
		||||
	var gerr error
 | 
			
		||||
	for i := 0; i < arr.Len(); i++ {
 | 
			
		||||
		val := NewNode(next)
 | 
			
		||||
		elem := unsafe.Pointer(uintptr(elems) + uintptr(i)*d.elemType.Size)
 | 
			
		||||
		err := d.elemDec.FromDom(elem, val, ctx)
 | 
			
		||||
		if gerr == nil && err != nil {
 | 
			
		||||
			gerr = err
 | 
			
		||||
		}
 | 
			
		||||
		next = val.Next()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(*rt.GoSlice)(vp) = *slice
 | 
			
		||||
	return gerr
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type arrayDecoder struct {
 | 
			
		||||
	len      int
 | 
			
		||||
	elemType *rt.GoType
 | 
			
		||||
	elemDec  decFunc
 | 
			
		||||
	typ   	reflect.Type
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//go:nocheckptr
 | 
			
		||||
func (d *arrayDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	arr, ok := node.AsArr()
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return error_mismatch(node, ctx, d.typ)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	next := arr.Children()
 | 
			
		||||
	i := 0
 | 
			
		||||
 | 
			
		||||
	var gerr error
 | 
			
		||||
	for ; i < d.len && i < arr.Len(); i++ {
 | 
			
		||||
		elem := unsafe.Pointer(uintptr(vp) + uintptr(i)*d.elemType.Size)
 | 
			
		||||
		val := NewNode(next)
 | 
			
		||||
		err := d.elemDec.FromDom(elem, val, ctx)
 | 
			
		||||
		if gerr == nil && err != nil {
 | 
			
		||||
			gerr = err
 | 
			
		||||
		}
 | 
			
		||||
		next = val.Next()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* zero rest of array */
 | 
			
		||||
	ptr := unsafe.Pointer(uintptr(vp) + uintptr(i)*d.elemType.Size)
 | 
			
		||||
	n := uintptr(d.len-i) * d.elemType.Size
 | 
			
		||||
	rt.ClearMemory(d.elemType, ptr, n)
 | 
			
		||||
	return gerr
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type sliceEfaceDecoder struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *sliceEfaceDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		*(*rt.GoSlice)(vp) = rt.GoSlice{}
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return node.AsSliceEface(ctx, vp)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type sliceI32Decoder struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *sliceI32Decoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		*(*rt.GoSlice)(vp) = rt.GoSlice{}
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return node.AsSliceI32(ctx, vp)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type sliceI64Decoder struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *sliceI64Decoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		*(*rt.GoSlice)(vp) = rt.GoSlice{}
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return node.AsSliceI64(ctx, vp)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type sliceU32Decoder struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *sliceU32Decoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		*(*rt.GoSlice)(vp) = rt.GoSlice{}
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return node.AsSliceU32(ctx, vp)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type sliceU64Decoder struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *sliceU64Decoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		*(*rt.GoSlice)(vp) = rt.GoSlice{}
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return node.AsSliceU64(ctx, vp)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type sliceStringDecoder struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *sliceStringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		*(*rt.GoSlice)(vp) = rt.GoSlice{}
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return node.AsSliceString(ctx, vp)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type sliceBytesDecoder struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *sliceBytesDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		*(*rt.GoSlice)(vp) = rt.GoSlice{}
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s, err := node.AsSliceBytes(ctx)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(*[]byte)(vp) = s
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type sliceBytesUnmarshalerDecoder struct {
 | 
			
		||||
	elemType *rt.GoType
 | 
			
		||||
	elemDec  decFunc
 | 
			
		||||
	typ reflect.Type
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *sliceBytesUnmarshalerDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		*(*rt.GoSlice)(vp) = rt.GoSlice{}
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* parse JSON string into `[]byte` */
 | 
			
		||||
	if node.IsStr() {
 | 
			
		||||
		slice, err := node.AsSliceBytes(ctx)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		*(*[]byte)(vp) = slice
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* parse JSON array into `[]byte` */
 | 
			
		||||
	arr, ok := node.AsArr()
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return error_mismatch(node, ctx, d.typ)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	slice := rt.MakeSlice(vp, d.elemType, arr.Len())
 | 
			
		||||
	elems := slice.Ptr
 | 
			
		||||
 | 
			
		||||
	var gerr error
 | 
			
		||||
	next := arr.Children()
 | 
			
		||||
	for i := 0; i < arr.Len(); i++ {
 | 
			
		||||
		child := NewNode(next)
 | 
			
		||||
		elem := unsafe.Pointer(uintptr(elems) + uintptr(i)*d.elemType.Size)
 | 
			
		||||
		err := d.elemDec.FromDom(elem, child, ctx)
 | 
			
		||||
		if gerr == nil && err != nil {
 | 
			
		||||
			gerr = err
 | 
			
		||||
		}
 | 
			
		||||
		next = child.Next()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(*rt.GoSlice)(vp) = *slice
 | 
			
		||||
	return gerr
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										360
									
								
								vendor/github.com/bytedance/sonic/internal/decoder/optdec/stringopts.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										360
									
								
								vendor/github.com/bytedance/sonic/internal/decoder/optdec/stringopts.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,360 @@
 | 
			
		|||
package optdec
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"math"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
 | 
			
		||||
	"github.com/bytedance/sonic/internal/rt"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type ptrStrDecoder struct {
 | 
			
		||||
	typ   *rt.GoType
 | 
			
		||||
	deref decFunc
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Pointer Value is allocated in the Caller
 | 
			
		||||
func (d *ptrStrDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		*(*unsafe.Pointer)(vp) = nil
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s, ok := node.AsStrRef(ctx)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return	error_mismatch(node, ctx, stringType)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if s == "null" {
 | 
			
		||||
		*(*unsafe.Pointer)(vp) = nil
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if *(*unsafe.Pointer)(vp) == nil {
 | 
			
		||||
		*(*unsafe.Pointer)(vp) = rt.Mallocgc(d.typ.Size, d.typ, true)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return d.deref.FromDom(*(*unsafe.Pointer)(vp), node, ctx)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type boolStringDecoder struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *boolStringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s, ok := node.AsStrRef(ctx)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return error_mismatch(node, ctx, stringType)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if s == "null" {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	b, err := ParseBool(s)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return error_mismatch(node, ctx, boolType)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(*bool)(vp) = b
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func parseI64(node Node, ctx *context) (int64, error, bool) {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		return 0, nil, true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s, ok := node.AsStrRef(ctx)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return 0, error_mismatch(node, ctx, stringType), false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if s == "null" {
 | 
			
		||||
		return 0, nil, true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret, err := ParseI64(s)
 | 
			
		||||
	return ret, err, false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type i8StringDecoder struct{}
 | 
			
		||||
 | 
			
		||||
func (d *i8StringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	ret, err, null := parseI64(node, ctx)
 | 
			
		||||
	if null {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ret > math.MaxInt8 || ret < math.MinInt8 {
 | 
			
		||||
		return error_mismatch(node, ctx, int8Type)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(*int8)(vp) = int8(ret)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type i16StringDecoder struct{}
 | 
			
		||||
 | 
			
		||||
func (d *i16StringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	ret, err, null := parseI64(node, ctx)
 | 
			
		||||
	if null {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ret > math.MaxInt16 || ret < math.MinInt16 {
 | 
			
		||||
		return error_mismatch(node, ctx, int16Type)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(*int16)(vp) = int16(ret)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type i32StringDecoder struct{}
 | 
			
		||||
 | 
			
		||||
func (d *i32StringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	ret, err, null := parseI64(node, ctx)
 | 
			
		||||
	if null {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ret > math.MaxInt32 || ret < math.MinInt32 {
 | 
			
		||||
		return error_mismatch(node, ctx, int32Type)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(*int32)(vp) = int32(ret)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type i64StringDecoder struct{}
 | 
			
		||||
 | 
			
		||||
func (d *i64StringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	ret, err, null := parseI64(node, ctx)
 | 
			
		||||
	if null {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(*int64)(vp) = int64(ret)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func parseU64(node Node, ctx *context) (uint64, error, bool) {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		return 0, nil, true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s, ok := node.AsStrRef(ctx)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return 0, error_mismatch(node, ctx, stringType), false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if s == "null" {
 | 
			
		||||
		return 0, nil, true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret, err := ParseU64(s)
 | 
			
		||||
	return 	ret, err, false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type u8StringDecoder struct{}
 | 
			
		||||
 | 
			
		||||
func (d *u8StringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	ret, err, null := parseU64(node, ctx)
 | 
			
		||||
	if null {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ret > math.MaxUint8 {
 | 
			
		||||
		return error_mismatch(node, ctx, uint8Type)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(*uint8)(vp) = uint8(ret)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type u16StringDecoder struct{}
 | 
			
		||||
 | 
			
		||||
func (d *u16StringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	ret, err, null := parseU64(node, ctx)
 | 
			
		||||
	if null {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ret > math.MaxUint16 {
 | 
			
		||||
		return error_mismatch(node, ctx, uint16Type)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(*uint16)(vp) = uint16(ret)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type u32StringDecoder struct{}
 | 
			
		||||
 | 
			
		||||
func (d *u32StringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	ret, err, null := parseU64(node, ctx)
 | 
			
		||||
	if null {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ret > math.MaxUint32 {
 | 
			
		||||
		return error_mismatch(node, ctx, uint32Type)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(*uint32)(vp) = uint32(ret)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
type u64StringDecoder struct{}
 | 
			
		||||
 | 
			
		||||
func (d *u64StringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	ret, err, null := parseU64(node, ctx)
 | 
			
		||||
	if null {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(*uint64)(vp) = uint64(ret)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type f32StringDecoder struct{}
 | 
			
		||||
 | 
			
		||||
func (d *f32StringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s, ok := node.AsStrRef(ctx)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return error_mismatch(node, ctx, stringType)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if s == "null" {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret, err := ParseF64(s)
 | 
			
		||||
	if err != nil || ret > math.MaxFloat32 || ret < -math.MaxFloat32 {
 | 
			
		||||
		return error_mismatch(node, ctx, float32Type)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(*float32)(vp) = float32(ret)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type f64StringDecoder struct{}
 | 
			
		||||
 | 
			
		||||
func (d *f64StringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s, ok := node.AsStrRef(ctx)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return error_mismatch(node, ctx, stringType)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if s == "null" {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret, err := ParseF64(s)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return error_mismatch(node, ctx, float64Type)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(*float64)(vp) = float64(ret)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* parse string field with string options */
 | 
			
		||||
type strStringDecoder struct{}
 | 
			
		||||
 | 
			
		||||
func (d *strStringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s, ok := node.AsStrRef(ctx)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return error_mismatch(node, ctx, stringType)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if s == "null" {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s, err := Unquote(s)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return error_mismatch(node, ctx, stringType)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(*string)(vp) = s
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type numberStringDecoder struct{}
 | 
			
		||||
 | 
			
		||||
func (d *numberStringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s, ok := node.AsStrRef(ctx)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return error_mismatch(node, ctx, stringType)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if s == "null" {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	num, ok := node.ParseNumber(ctx)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return error_mismatch(node, ctx, jsonNumberType)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	end, ok := SkipNumberFast(s, 0)
 | 
			
		||||
	// has error or trailing chars
 | 
			
		||||
	if !ok || end != len(s) {
 | 
			
		||||
		return error_mismatch(node, ctx, jsonNumberType)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(*json.Number)(vp) = json.Number(num)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										61
									
								
								vendor/github.com/bytedance/sonic/internal/decoder/optdec/structs.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								vendor/github.com/bytedance/sonic/internal/decoder/optdec/structs.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,61 @@
 | 
			
		|||
package optdec
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
 | 
			
		||||
	caching "github.com/bytedance/sonic/internal/optcaching"
 | 
			
		||||
	"github.com/bytedance/sonic/internal/resolver"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type fieldEntry struct {
 | 
			
		||||
	resolver.FieldMeta
 | 
			
		||||
	fieldDec decFunc
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type structDecoder struct {
 | 
			
		||||
	fieldMap   caching.FieldLookup
 | 
			
		||||
	fields     []fieldEntry
 | 
			
		||||
	structName string
 | 
			
		||||
	typ        reflect.Type
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *structDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
 | 
			
		||||
	if node.IsNull() {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var gerr error
 | 
			
		||||
	obj, ok := node.AsObj()
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return error_mismatch(node, ctx, d.typ)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	next := obj.Children()
 | 
			
		||||
	for i := 0; i < obj.Len(); i++ {
 | 
			
		||||
		key, _ := NewNode(next).AsStrRef(ctx)
 | 
			
		||||
		val := NewNode(PtrOffset(next, 1))
 | 
			
		||||
		next = val.Next()
 | 
			
		||||
 | 
			
		||||
		// find field idx
 | 
			
		||||
		idx := d.fieldMap.Get(key)
 | 
			
		||||
        if idx == -1 {
 | 
			
		||||
            if Options(ctx.Options())&OptionDisableUnknown != 0 {
 | 
			
		||||
                return error_field(key)
 | 
			
		||||
            }
 | 
			
		||||
            continue
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		offset := d.fields[idx].Path[0].Size
 | 
			
		||||
		elem := unsafe.Pointer(uintptr(vp) + offset)
 | 
			
		||||
		err := d.fields[idx].fieldDec.FromDom(elem, val, ctx)
 | 
			
		||||
 | 
			
		||||
		// deal with mismatch type errors
 | 
			
		||||
		if gerr == nil && err != nil {
 | 
			
		||||
			// TODO: better error info
 | 
			
		||||
			gerr = err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return gerr
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										60
									
								
								vendor/github.com/bytedance/sonic/internal/decoder/optdec/types.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								vendor/github.com/bytedance/sonic/internal/decoder/optdec/types.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,60 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2021 ByteDance Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package optdec
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding"
 | 
			
		||||
	"encoding/base64"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
 | 
			
		||||
	"github.com/bytedance/sonic/internal/rt"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	boolType                = reflect.TypeOf(bool(false))
 | 
			
		||||
	byteType                = reflect.TypeOf(byte(0))
 | 
			
		||||
	intType                 = reflect.TypeOf(int(0))
 | 
			
		||||
	int8Type                = reflect.TypeOf(int8(0))
 | 
			
		||||
	int16Type               = reflect.TypeOf(int16(0))
 | 
			
		||||
	int32Type               = reflect.TypeOf(int32(0))
 | 
			
		||||
	int64Type               = reflect.TypeOf(int64(0))
 | 
			
		||||
	uintType                = reflect.TypeOf(uint(0))
 | 
			
		||||
	uint8Type               = reflect.TypeOf(uint8(0))
 | 
			
		||||
	uint16Type              = reflect.TypeOf(uint16(0))
 | 
			
		||||
	uint32Type              = reflect.TypeOf(uint32(0))
 | 
			
		||||
	uint64Type              = reflect.TypeOf(uint64(0))
 | 
			
		||||
	float32Type             = reflect.TypeOf(float32(0))
 | 
			
		||||
	float64Type             = reflect.TypeOf(float64(0))
 | 
			
		||||
	stringType              = reflect.TypeOf("")
 | 
			
		||||
	bytesType               = reflect.TypeOf([]byte(nil))
 | 
			
		||||
	jsonNumberType          = reflect.TypeOf(json.Number(""))
 | 
			
		||||
	base64CorruptInputError = reflect.TypeOf(base64.CorruptInputError(0))
 | 
			
		||||
	anyType                 = rt.UnpackType(reflect.TypeOf((*interface{})(nil)).Elem())
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	errorType                   = reflect.TypeOf((*error)(nil)).Elem()
 | 
			
		||||
	jsonUnmarshalerType         = reflect.TypeOf((*json.Unmarshaler)(nil)).Elem()
 | 
			
		||||
	encodingTextUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func rtype(t reflect.Type) (*rt.GoItab, *rt.GoType) {
 | 
			
		||||
	p := (*rt.GoIface)(unsafe.Pointer(&t))
 | 
			
		||||
	return p.Itab, (*rt.GoType)(p.Value)
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue