summaryrefslogtreecommitdiff
path: root/vendor/github.com/bytedance/sonic/internal/decoder/optdec
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/bytedance/sonic/internal/decoder/optdec')
-rw-r--r--vendor/github.com/bytedance/sonic/internal/decoder/optdec/compile_struct.go174
-rw-r--r--vendor/github.com/bytedance/sonic/internal/decoder/optdec/compiler.go449
-rw-r--r--vendor/github.com/bytedance/sonic/internal/decoder/optdec/const.go60
-rw-r--r--vendor/github.com/bytedance/sonic/internal/decoder/optdec/context.go3
-rw-r--r--vendor/github.com/bytedance/sonic/internal/decoder/optdec/decoder.go160
-rw-r--r--vendor/github.com/bytedance/sonic/internal/decoder/optdec/errors.go73
-rw-r--r--vendor/github.com/bytedance/sonic/internal/decoder/optdec/functor.go281
-rw-r--r--vendor/github.com/bytedance/sonic/internal/decoder/optdec/helper.go110
-rw-r--r--vendor/github.com/bytedance/sonic/internal/decoder/optdec/interface.go169
-rw-r--r--vendor/github.com/bytedance/sonic/internal/decoder/optdec/map.go430
-rw-r--r--vendor/github.com/bytedance/sonic/internal/decoder/optdec/native.go269
-rw-r--r--vendor/github.com/bytedance/sonic/internal/decoder/optdec/node.go1278
-rw-r--r--vendor/github.com/bytedance/sonic/internal/decoder/optdec/slice.go224
-rw-r--r--vendor/github.com/bytedance/sonic/internal/decoder/optdec/stringopts.go360
-rw-r--r--vendor/github.com/bytedance/sonic/internal/decoder/optdec/structs.go61
-rw-r--r--vendor/github.com/bytedance/sonic/internal/decoder/optdec/types.go60
16 files changed, 0 insertions, 4161 deletions
diff --git a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/compile_struct.go b/vendor/github.com/bytedance/sonic/internal/decoder/optdec/compile_struct.go
deleted file mode 100644
index 713fb6561..000000000
--- a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/compile_struct.go
+++ /dev/null
@@ -1,174 +0,0 @@
-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,
- }
-}
diff --git a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/compiler.go b/vendor/github.com/bytedance/sonic/internal/decoder/optdec/compiler.go
deleted file mode 100644
index 7d9d60a01..000000000
--- a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/compiler.go
+++ /dev/null
@@ -1,449 +0,0 @@
-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)
-
- // special 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, string tag */
- if strOpt {
- panicForInvalidStrType(vt)
- }
- return &unmarshalTextDecoder{
- typ: rt.UnpackType(pt),
- }
- }
-
- return nil
-}
-
-func panicForInvalidStrType(vt reflect.Type) {
- panic(error_type(rt.UnpackType(vt)))
-}
diff --git a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/const.go b/vendor/github.com/bytedance/sonic/internal/decoder/optdec/const.go
deleted file mode 100644
index 77879fafe..000000000
--- a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/const.go
+++ /dev/null
@@ -1,60 +0,0 @@
-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
-)
diff --git a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/context.go b/vendor/github.com/bytedance/sonic/internal/decoder/optdec/context.go
deleted file mode 100644
index 93ed9b7e0..000000000
--- a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/context.go
+++ /dev/null
@@ -1,3 +0,0 @@
-package optdec
-
-type context = Context
diff --git a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/decoder.go b/vendor/github.com/bytedance/sonic/internal/decoder/optdec/decoder.go
deleted file mode 100644
index 81eed34ea..000000000
--- a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/decoder.go
+++ /dev/null
@@ -1,160 +0,0 @@
-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)
-}
diff --git a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/errors.go b/vendor/github.com/bytedance/sonic/internal/decoder/optdec/errors.go
deleted file mode 100644
index db0af547b..000000000
--- a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/errors.go
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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,
- }
- }
- \ No newline at end of file
diff --git a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/functor.go b/vendor/github.com/bytedance/sonic/internal/decoder/optdec/functor.go
deleted file mode 100644
index 2a0523d5e..000000000
--- a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/functor.go
+++ /dev/null
@@ -1,281 +0,0 @@
-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)
-}
diff --git a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/helper.go b/vendor/github.com/bytedance/sonic/internal/decoder/optdec/helper.go
deleted file mode 100644
index 61faa6c80..000000000
--- a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/helper.go
+++ /dev/null
@@ -1,110 +0,0 @@
-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 parsed in native, it always 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 trailing chars
- for ret < len(raw) {
- return false
- }
-
- return true
-}
-
-func SkipOneFast2(json string, pos *int) (int, error) {
- // find the number ending, we parsed in sonic-cpp, it always 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 parsed in sonic-cpp, it always 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
-}
diff --git a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/interface.go b/vendor/github.com/bytedance/sonic/internal/decoder/optdec/interface.go
deleted file mode 100644
index 0c063d55f..000000000
--- a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/interface.go
+++ /dev/null
@@ -1,169 +0,0 @@
-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)
-}
diff --git a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/map.go b/vendor/github.com/bytedance/sonic/internal/decoder/optdec/map.go
deleted file mode 100644
index 1a2bda8f3..000000000
--- a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/map.go
+++ /dev/null
@@ -1,430 +0,0 @@
-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
-}
diff --git a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/native.go b/vendor/github.com/bytedance/sonic/internal/decoder/optdec/native.go
deleted file mode 100644
index 5dadec0b7..000000000
--- a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/native.go
+++ /dev/null
@@ -1,269 +0,0 @@
-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 consistent with native/parser.c
-type _nospaceBlock struct {
- _ [8]byte
- _ [8]byte
-}
-
-// should consistent 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 consistent 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
-}
diff --git a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/node.go b/vendor/github.com/bytedance/sonic/internal/decoder/optdec/node.go
deleted file mode 100644
index b23901e38..000000000
--- a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/node.go
+++ /dev/null
@@ -1,1278 +0,0 @@
-package optdec
-
-import (
- "encoding/json"
- "math"
- "unsafe"
-
- "github.com/bytedance/sonic/internal/envs"
- "github.com/bytedance/sonic/internal/rt"
-)
-
-type Context struct {
- Parser *Parser
- efacePool *efacePool
- Stack bounedStack
- Utf8Inv bool
-}
-
-func (ctx *Context) Options() uint64 {
- return ctx.Parser.options
-}
-
-/************************* Stack and Pool Helper *******************/
-
-type parentStat struct {
- con unsafe.Pointer
- remain uint64
-}
-type bounedStack struct {
- stack []parentStat
- index int
-}
-
-func newStack(size int) bounedStack {
- return bounedStack{
- stack: make([]parentStat, size + 2),
- index: 0,
- }
-}
-
-//go:nosplit
-func (s *bounedStack) Pop() (unsafe.Pointer, int, bool){
- s.index--
- con := s.stack[s.index].con
- remain := s.stack[s.index].remain &^ (uint64(1) << 63)
- isObj := (s.stack[s.index].remain & (uint64(1) << 63)) != 0
- s.stack[s.index].con = nil
- s.stack[s.index].remain = 0
- return con, int(remain), isObj
-}
-
-//go:nosplit
-func (s *bounedStack) Push(p unsafe.Pointer, remain int, isObj bool) {
- s.stack[s.index].con = p
- s.stack[s.index].remain = uint64(remain)
- if isObj {
- s.stack[s.index].remain |= (uint64(1) << 63)
- }
- s.index++
-}
-
-type efacePool struct{
- t64 rt.T64Pool
- tslice rt.TslicePool
- tstring rt.TstringPool
- efaceSlice rt.SlicePool
-}
-
-func newEfacePool(stat *jsonStat, useNumber bool) *efacePool {
- strs := int(stat.str)
- nums := 0
- if useNumber {
- strs += int(stat.number)
- } else {
- nums = int(stat.number)
- }
-
- return &efacePool{
- t64: rt.NewT64Pool(nums),
- tslice: rt.NewTslicePool(int(stat.array)),
- tstring: rt.NewTstringPool(strs),
- efaceSlice: rt.NewPool(rt.AnyType, int(stat.array_elems)),
- }
-}
-
-func (self *efacePool) GetMap(hint int) unsafe.Pointer {
- m := make(map[string]interface{}, hint)
- return *(*unsafe.Pointer)(unsafe.Pointer(&m))
-}
-
-func (self *efacePool) GetSlice(hint int) unsafe.Pointer {
- return unsafe.Pointer(self.efaceSlice.GetSlice(hint))
-}
-
-func (self *efacePool) ConvTSlice(val rt.GoSlice, typ *rt.GoType, dst unsafe.Pointer) {
- self.tslice.Conv(val, typ, (*interface{})(dst))
-}
-
-func (self *efacePool) ConvF64(val float64, dst unsafe.Pointer) {
- self.t64.Conv(castU64(val), rt.Float64Type, (*interface{})(dst))
-}
-
-func (self *efacePool) ConvTstring(val string, dst unsafe.Pointer) {
- self.tstring.Conv(val, (*interface{})(dst))
-}
-
-func (self *efacePool) ConvTnum(val json.Number, dst unsafe.Pointer) {
- self.tstring.ConvNum(val, (*interface{})(dst))
-}
-
-/********************************************************/
-
-func canUseFastMap( opts uint64, root *rt.GoType) bool {
- return envs.UseFastMap && (opts & (1 << _F_copy_string)) == 0 && (opts & (1 << _F_use_int64)) == 0 && (root == rt.AnyType || root == rt.MapEfaceType || root == rt.SliceEfaceType)
-}
-
-func NewContext(json string, pos int, opts uint64, root *rt.GoType) (Context, error) {
- ctx := Context{
- Parser: newParser(json, pos, opts),
- }
- if root == rt.AnyType || root == rt.MapEfaceType || root == rt.SliceEfaceType {
- ctx.Parser.isEface = true
- }
-
- ecode := ctx.Parser.parse()
-
- if ecode != 0 {
- return ctx, ctx.Parser.fixError(ecode)
- }
-
- useNumber := (opts & (1 << _F_use_number )) != 0
- if canUseFastMap(opts, root) {
- ctx.efacePool = newEfacePool(&ctx.Parser.nbuf.stat, useNumber)
- ctx.Stack = newStack(int(ctx.Parser.nbuf.stat.max_depth))
- }
-
- return ctx, nil
-}
-
-func (ctx *Context) Delete() {
- ctx.Parser.free()
- ctx.Parser = nil
-}
-
-type Node struct {
- cptr uintptr
-}
-
-func NewNode(cptr uintptr) Node {
- return Node{cptr: cptr}
-}
-
-type Dom struct {
- cdom uintptr
-}
-
-func (ctx *Context) Root() Node {
- root := (uintptr)(((*rt.GoSlice)(unsafe.Pointer(&ctx.Parser.nodes))).Ptr)
- return Node{cptr: root}
-}
-
-type Array struct {
- cptr uintptr
-}
-
-type Object struct {
- cptr uintptr
-}
-
-func (obj Object) Len() int {
- cobj := ptrCast(obj.cptr)
- return int(uint64(cobj.val) & ConLenMask)
-}
-
-func (arr Array) Len() int {
- carr := ptrCast(arr.cptr)
- return int(uint64(carr.val) & ConLenMask)
-}
-
-// / Helper functions to eliminate CGO calls
-func (val Node) Type() uint8 {
- ctype := ptrCast(val.cptr)
- return uint8(ctype.typ & TypeMask)
-}
-
-func (val Node) Next() uintptr {
- if val.Type() != KObject && val.Type() != KArray {
- return PtrOffset(val.cptr, 1)
- }
- cobj := ptrCast(val.cptr)
- offset := int64(uint64(cobj.val) >> ConLenBits)
- return PtrOffset(val.cptr, offset)
-}
-
-func (val *Node) next() {
- *val = NewNode(val.Next())
-}
-
-type NodeIter struct {
- next uintptr
-}
-
-func NewNodeIter(node Node) NodeIter {
- return NodeIter{next: node.cptr}
-}
-
-func (iter *NodeIter) Next() Node {
- ret := NewNode(iter.next)
- iter.next = PtrOffset(iter.next, 1)
- return ret
-}
-
-
-func (iter *NodeIter) Peek() Node {
- return NewNode(iter.next)
-}
-
-func (val Node) U64() uint64 {
- cnum := ptrCast(val.cptr)
- return *(*uint64)((unsafe.Pointer)(&(cnum.val)))
-}
-
-func (val Node) I64() int64 {
- cnum := ptrCast(val.cptr)
- return *(*int64)((unsafe.Pointer)(&(cnum.val)))
-}
-
-func (val Node) IsNull() bool {
- return val.Type() == KNull
-}
-
-func (val Node) IsNumber() bool {
- return val.Type() & KNumber != 0
-}
-
-func (val Node) F64() float64 {
- cnum := ptrCast(val.cptr)
- return *(*float64)((unsafe.Pointer)(&(cnum.val)))
-}
-
-func (val Node) Bool() bool {
- return val.Type() == KTrue
-}
-
-func (self Node) AsU64(ctx *Context) (uint64, bool) {
- if self.Type() == KUint {
- return self.U64(), true
- } else if self.Type() == KRawNumber {
- num, err := ParseU64(self.Raw(ctx))
- if err != nil {
- return 0, false
- }
- return num, true
- } else {
- return 0, false
- }
-}
-
-func (val *Node) AsObj() (Object, bool) {
- var ret Object
- if val.Type() != KObject {
- return ret, false
- }
- return Object{
- cptr: val.cptr,
- }, true
-}
-
-func (val Node) Obj() Object {
- return Object{cptr: val.cptr}
-}
-
-func (val Node) Arr() Array {
- return Array{cptr: val.cptr}
-}
-
-func (val *Node) AsArr() (Array, bool) {
- var ret Array
- if val.Type() != KArray {
- return ret, false
- }
- return Array{
- cptr: val.cptr,
- }, true
-}
-
-func (self Node) AsI64(ctx *Context) (int64, bool) {
- typ := self.Type()
- if typ == KUint && self.U64() <= math.MaxInt64 {
- return int64(self.U64()), true
- } else if typ == KSint {
- return self.I64(), true
- } else if typ == KRawNumber {
- val, err := self.Number(ctx).Int64()
- if err != nil {
- return 0, false
- }
- return val, true
- } else {
- return 0, false
- }
-}
-
-/********* Parse Node String into Value ***************/
-
-func (val Node) ParseI64(ctx *Context) (int64, bool) {
- s, ok := val.AsStrRef(ctx)
- if !ok {
- return 0, false
- }
-
- if s == "null" {
- return 0, true
- }
-
- i, err := ParseI64(s)
- if err != nil {
- return 0, false
- }
- return i, true
-}
-
-func (val Node) ParseBool(ctx *Context) (bool, bool) {
- s, ok := val.AsStrRef(ctx)
- if !ok {
- return false, false
- }
-
- if s == "null" {
- return false, true
- }
-
- b, err := ParseBool(s)
- if err != nil {
- return false, false
- }
- return b, true
-}
-
-func (val Node) ParseU64(ctx *Context) (uint64, bool) {
- s, ok := val.AsStrRef(ctx)
- if !ok {
- return 0, false
- }
-
- if s == "null" {
- return 0, true
- }
-
- i, err := ParseU64(s)
- if err != nil {
- return 0, false
- }
- return i, true
-}
-
-func (val Node) ParseF64(ctx *Context) (float64, bool) {
- s, ok := val.AsStrRef(ctx)
- if !ok {
- return 0, false
- }
-
- if s == "null" {
- return 0, true
- }
-
- i, err := ParseF64(s)
- if err != nil {
- return 0, false
- }
- return i, true
-}
-
-func (val Node) ParseString(ctx *Context) (string, bool) {
- // should not use AsStrRef
- s, ok := val.AsStr(ctx)
- if !ok {
- return "", false
- }
-
- if s == "null" {
- return "", true
- }
-
- s, err := Unquote(s)
- if err != nil {
- return "", false
- }
- return s, true
-}
-
-
-func (val Node) ParseNumber(ctx *Context) (json.Number, bool) {
- // should not use AsStrRef
- s, ok := val.AsStr(ctx)
- if !ok {
- return json.Number(""), false
- }
-
- if s == "null" {
- return json.Number(""), true
- }
-
- end, ok := SkipNumberFast(s, 0)
- // has error or trailing chars
- if !ok || end != len(s) {
- return json.Number(""), false
- }
- return json.Number(s), true
-}
-
-
-
-func (val Node) AsF64(ctx *Context) (float64, bool) {
- switch val.Type() {
- case KUint: return float64(val.U64()), true
- case KSint: return float64(val.I64()), true
- case KReal: return float64(val.F64()), true
- case KRawNumber: f, err := val.Number(ctx).Float64(); return f, err == nil
- default: return 0, false
- }
-}
-
-func (val Node) AsBool() (bool, bool) {
- switch val.Type() {
- case KTrue: return true, true
- case KFalse: return false, true
- default: return false, false
- }
-}
-
-func (val Node) AsStr(ctx *Context) (string, bool) {
- switch val.Type() {
- case KStringCommon:
- s := val.StringRef(ctx)
- if (ctx.Options() & (1 << _F_copy_string) == 0) {
- return s, true
- }
- return string(rt.Str2Mem(s)), true
- case KStringEscaped:
- return val.StringCopyEsc(ctx), true
- default: return "", false
- }
-}
-
-func (val Node) AsStrRef(ctx *Context) (string, bool) {
- switch val.Type() {
- case KStringEscaped:
- node := ptrCast(val.cptr)
- offset := val.Position()
- len := int(node.val)
- return rt.Mem2Str(ctx.Parser.JsonBytes()[offset : offset + len]), true
- case KStringCommon:
- return val.StringRef(ctx), true
- default:
- return "", false
- }
-}
-
-func (val Node) AsBytesRef(ctx *Context) ([]byte, bool) {
- switch val.Type() {
- case KStringEscaped:
- node := ptrCast(val.cptr)
- offset := val.Position()
- len := int(node.val)
- return ctx.Parser.JsonBytes()[offset : offset + len], true
- case KStringCommon:
- return rt.Str2Mem(val.StringRef(ctx)), true
- default:
- return nil, false
- }
-}
-
-func (val Node) AsStringText(ctx *Context) ([]byte, bool) {
- if !val.IsStr() {
- return nil, false
- }
-
- // clone to new bytes
- s, b := val.AsStrRef(ctx)
- return []byte(s), b
-}
-
-func (val Node) IsStr() bool {
- return (val.Type() == KStringCommon) || (val.Type() == KStringEscaped)
-}
-
-func (val Node) IsRawNumber() bool {
- return val.Type() == KRawNumber
-}
-
-func (val Node) Number(ctx *Context) json.Number {
- return json.Number(val.Raw(ctx))
-}
-
-func (val Node) Raw(ctx *Context) string {
- node := ptrCast(val.cptr)
- len := int(node.val)
- offset := val.Position()
- return ctx.Parser.Json[offset:int(offset+len)]
-}
-
-func (val Node) Position() int {
- node := ptrCast(val.cptr)
- return int(node.typ >> PosBits)
-}
-
-func (val Node) AsNumber(ctx *Context) (json.Number, bool) {
- // parse JSON string as number
- if val.IsStr() {
- s, _ := val.AsStr(ctx)
- if !ValidNumberFast(s) {
- return "", false
- } else {
- return json.Number(s), true
- }
- }
-
- return val.NonstrAsNumber(ctx)
-}
-
-func (val Node) NonstrAsNumber(ctx *Context) (json.Number, bool) {
- // deal with raw number
- if val.IsRawNumber() {
- return val.Number(ctx), true
- }
-
- // deal with parse number
- if !val.IsNumber() {
- return json.Number(""), false
- }
-
- start := val.Position()
- end, ok := SkipNumberFast(ctx.Parser.Json, start)
- if !ok {
- return "", false
- }
- return json.Number(ctx.Parser.Json[start:end]), true
-}
-
-func (val Node) AsRaw(ctx *Context) string {
- // fast path for unescaped strings
- switch val.Type() {
- case KNull:
- return "null"
- case KTrue:
- return "true"
- case KFalse:
- return "false"
- case KStringCommon:
- node := ptrCast(val.cptr)
- len := int(node.val)
- offset := val.Position()
- // add start abd end quote
- ref := rt.Str2Mem(ctx.Parser.Json)[offset-1 : offset+len+1]
- return rt.Mem2Str(ref)
- case KRawNumber: fallthrough
- case KRaw: return val.Raw(ctx)
- case KStringEscaped:
- raw, _ := SkipOneFast(ctx.Parser.Json, val.Position() - 1)
- return raw
- default:
- raw, err := SkipOneFast(ctx.Parser.Json, val.Position())
- if err != nil {
- break
- }
- return raw
- }
- panic("should always be valid json here")
-}
-
-// reference from the input JSON as possible
-func (val Node) StringRef(ctx *Context) string {
- return val.Raw(ctx)
-}
-
-//go:nocheckptr
-func ptrCast(p uintptr) *node {
- return (*node)(unsafe.Pointer(p))
-}
-
-func (val Node) StringCopyEsc(ctx *Context) string {
- // check whether there are in padded
- node := ptrCast(val.cptr)
- len := int(node.val)
- offset := val.Position()
- return string(ctx.Parser.JsonBytes()[offset : offset + len])
-}
-
-func (val Node) Object() Object {
- return Object{cptr: val.cptr}
-}
-
-func (val Node) Array() Array {
- return Array{cptr: val.cptr}
-}
-
-func (val *Array) Children() uintptr {
- return PtrOffset(val.cptr, 1)
-}
-
-func (val *Object) Children() uintptr {
- return PtrOffset(val.cptr, 1)
-}
-
-func (val *Node) Equal(ctx *Context, lhs string) bool {
- // check whether escaped
- cstr := ptrCast(val.cptr)
- offset := int(val.Position())
- len := int(cstr.val)
- return lhs == ctx.Parser.Json[offset:offset+len]
-}
-
-func (node *Node) AsMapEface(ctx *Context, vp unsafe.Pointer) error {
- if node.IsNull() {
- return nil
- }
-
- obj, ok := node.AsObj()
- if !ok {
- return newUnmatched(node.Position(), rt.MapEfaceType)
- }
-
- var err, gerr error
- size := obj.Len()
-
- var m map[string]interface{}
- if *(*unsafe.Pointer)(vp) == nil {
- if ctx.efacePool != nil {
- p := ctx.efacePool.GetMap(size)
- m = *(*map[string]interface{})(unsafe.Pointer(&p))
- } else {
- m = make(map[string]interface{}, size)
- }
- } else {
- m = *(*map[string]interface{})(vp)
- }
-
- next := obj.Children()
- for i := 0; i < size; i++ {
- knode := NewNode(next)
- key, _ := knode.AsStr(ctx)
- val := NewNode(PtrOffset(next, 1))
- m[key], err = val.AsEface(ctx)
- next = val.cptr
- if gerr == nil && err != nil {
- gerr = err
- }
- }
-
- *(*map[string]interface{})(vp) = m
- return gerr
-}
-
-func (node *Node) AsMapString(ctx *Context, vp unsafe.Pointer) error {
- obj, ok := node.AsObj()
- if !ok {
- return newUnmatched(node.Position(), rt.MapStringType)
- }
-
- size := obj.Len()
-
- var m map[string]string
- if *(*unsafe.Pointer)(vp) == nil {
- m = make(map[string]string, size)
- } else {
- m = *(*map[string]string)(vp)
- }
-
- var gerr error
- next := obj.Children()
- for i := 0; i < size; i++ {
- knode := NewNode(next)
- key, _ := knode.AsStr(ctx)
- val := NewNode(PtrOffset(next, 1))
- m[key], ok = val.AsStr(ctx)
- if !ok {
- if gerr == nil {
- gerr = newUnmatched(val.Position(), rt.StringType)
- }
- next = val.Next()
- } else {
- next = PtrOffset(val.cptr, 1)
- }
- }
-
- *(*map[string]string)(vp) = m
- return gerr
-}
-
-func (node *Node) AsSliceEface(ctx *Context, vp unsafe.Pointer) error {
- arr, ok := node.AsArr()
- if !ok {
- return newUnmatched(node.Position(), rt.SliceEfaceType)
- }
-
- size := arr.Len()
- var s []interface{}
- if size != 0 && ctx.efacePool != nil {
- slice := rt.GoSlice {
- Ptr: ctx.efacePool.GetSlice(size),
- Len: size,
- Cap: size,
- }
- *(*rt.GoSlice)(unsafe.Pointer(&s)) = slice
- } else {
- s = *(*[]interface{})((unsafe.Pointer)(rt.MakeSlice(vp, rt.AnyType, size)))
- }
-
- *node = NewNode(arr.Children())
-
- var err, gerr error
- for i := 0; i < size; i++ {
- s[i], err = node.AsEface(ctx)
- if gerr == nil && err != nil {
- gerr = err
- }
- }
-
- *(*[]interface{})(vp) = s
- return nil
-}
-
-func (node *Node) AsSliceI32(ctx *Context, vp unsafe.Pointer) error {
- arr, ok := node.AsArr()
- if !ok {
- return newUnmatched(node.Position(), rt.SliceI32Type)
- }
-
- size := arr.Len()
- s := *(*[]int32)((unsafe.Pointer)(rt.MakeSlice(vp, rt.Int32Type, size)))
- next := arr.Children()
-
- var gerr error
- for i := 0; i < size; i++ {
- val := NewNode(next)
- ret, ok := val.AsI64(ctx)
- if !ok || ret > math.MaxInt32 || ret < math.MinInt32 {
- if gerr == nil {
- gerr = newUnmatched(val.Position(), rt.Int32Type)
- }
- next = val.Next()
- } else {
- s[i] = int32(ret)
- next = PtrOffset(val.cptr, 1)
- }
- }
-
- *(*[]int32)(vp) = s
- return gerr
-}
-
-func (node *Node) AsSliceI64(ctx *Context, vp unsafe.Pointer) error {
- arr, ok := node.AsArr()
- if !ok {
- return newUnmatched(node.Position(), rt.SliceI64Type)
- }
-
- size := arr.Len()
- s := *(*[]int64)((unsafe.Pointer)(rt.MakeSlice(vp, rt.Int64Type, size)))
- next := arr.Children()
-
- var gerr error
- for i := 0; i < size; i++ {
- val := NewNode(next)
-
- ret, ok := val.AsI64(ctx)
- if !ok {
- if gerr == nil {
- gerr = newUnmatched(val.Position(), rt.Int64Type)
- }
- next = val.Next()
- } else {
- s[i] = ret
- next = PtrOffset(val.cptr, 1)
- }
- }
-
- *(*[]int64)(vp) = s
- return gerr
-}
-
-func (node *Node) AsSliceU32(ctx *Context, vp unsafe.Pointer) error {
- arr, ok := node.AsArr()
- if !ok {
- return newUnmatched(node.Position(), rt.SliceU32Type)
- }
-
- size := arr.Len()
- next := arr.Children()
- s := *(*[]uint32)((unsafe.Pointer)(rt.MakeSlice(vp, rt.Uint32Type, size)))
-
- var gerr error
- for i := 0; i < size; i++ {
- val := NewNode(next)
- ret, ok := val.AsU64(ctx)
- if !ok || ret > math.MaxUint32 {
- if gerr == nil {
- gerr = newUnmatched(val.Position(), rt.Uint32Type)
- }
- next = val.Next()
- } else {
- s[i] = uint32(ret)
- next = PtrOffset(val.cptr, 1)
- }
- }
-
- *(*[]uint32)(vp) = s
- return gerr
-}
-
-func (node *Node) AsSliceU64(ctx *Context, vp unsafe.Pointer) error {
- arr, ok := node.AsArr()
- if !ok {
- return newUnmatched(node.Position(), rt.SliceU64Type)
- }
-
- size := arr.Len()
- next := arr.Children()
-
- s := *(*[]uint64)((unsafe.Pointer)(rt.MakeSlice(vp, rt.Uint64Type, size)))
- var gerr error
- for i := 0; i < size; i++ {
- val := NewNode(next)
- ret, ok := val.AsU64(ctx)
- if !ok {
- if gerr == nil {
- gerr = newUnmatched(val.Position(), rt.Uint64Type)
- }
- next = val.Next()
- } else {
- s[i] = ret
- next = PtrOffset(val.cptr, 1)
- }
- }
-
- *(*[]uint64)(vp) = s
- return gerr
-}
-
-func (node *Node) AsSliceString(ctx *Context, vp unsafe.Pointer) error {
- arr, ok := node.AsArr()
- if !ok {
- return newUnmatched(node.Position(), rt.SliceStringType)
- }
-
- size := arr.Len()
- next := arr.Children()
- s := *(*[]string)((unsafe.Pointer)(rt.MakeSlice(vp, rt.StringType, size)))
-
- var gerr error
- for i := 0; i < size; i++ {
- val := NewNode(next)
- ret, ok := val.AsStr(ctx)
- if !ok {
- if gerr == nil {
- gerr = newUnmatched(val.Position(), rt.StringType)
- }
- next = val.Next()
- } else {
- s[i] = ret
- next = PtrOffset(val.cptr, 1)
- }
- }
-
- *(*[]string)(vp) = s
- return gerr
-}
-
-func (node *Node) AsSliceBytes(ctx *Context) ([]byte, error) {
- b, ok := node.AsBytesRef(ctx)
- if !ok {
- return nil, newUnmatched(node.Position(), rt.BytesType)
- }
-
- b64, err := rt.DecodeBase64(b)
- if err != nil {
- return nil, newUnmatched(node.Position(), rt.BytesType)
- }
- return b64, nil
-}
-
-// AsEface will always ok, because we have parse in native.
-func (node *Node) AsEface(ctx *Context) (interface{}, error) {
- if ctx.efacePool != nil {
- iter := NewNodeIter(*node)
- v := AsEfaceFast(&iter, ctx)
- *node = iter.Peek()
- return v, nil
- } else {
- return node.AsEfaceFallback(ctx)
- }
-}
-
-func parseSingleNode(node Node, ctx *Context) interface{} {
- var v interface{}
- switch node.Type() {
- case KObject: v = map[string]interface{}{}
- case KArray: v = []interface{}{}
- case KStringCommon: v = node.StringRef(ctx)
- case KStringEscaped: v = node.StringCopyEsc(ctx)
- case KTrue: v = true
- case KFalse: v = false
- case KNull: v = nil
- case KUint: v = float64(node.U64())
- case KSint: v = float64(node.I64())
- case KReal: v = float64(node.F64())
- case KRawNumber: v = node.Number(ctx)
- default: panic("unreachable for as eface")
- }
- return v
-}
-
-func castU64(val float64) uint64 {
- return *((*uint64)(unsafe.Pointer((&val))))
-}
-
-func AsEfaceFast(iter *NodeIter, ctx *Context) interface{} {
- var mp, sp, parent unsafe.Pointer // current container pointer
- var node Node
- var size int
- var isObj bool
- var slice rt.GoSlice
- var val unsafe.Pointer
- var vt **rt.GoType
- var vp *unsafe.Pointer
- var rootM unsafe.Pointer
- var rootS rt.GoSlice
- var root interface{}
- var key string
-
- node = iter.Next()
-
- switch node.Type() {
- case KObject:
- size = node.Object().Len()
- if size != 0 {
- ctx.Stack.Push(nil, 0, true)
- mp = ctx.efacePool.GetMap(size)
- rootM = mp
- isObj = true
- goto _object_key
- } else {
- return rt.GoEface {
- Type: rt.MapEfaceType,
- Value: ctx.efacePool.GetMap(0),
- }.Pack()
- }
- case KArray:
- size = node.Array().Len()
- if size != 0 {
- ctx.Stack.Push(nil, 0, false)
- sp = ctx.efacePool.GetSlice(size)
- slice = rt.GoSlice {
- Ptr: sp,
- Len: size,
- Cap: size,
- }
- rootS = slice
- isObj = false
- val = sp
- goto _arr_val;
- } else {
- ctx.efacePool.ConvTSlice(rt.EmptySlice, rt.SliceEfaceType, unsafe.Pointer(&root))
- }
- case KStringCommon: ctx.efacePool.ConvTstring(node.StringRef(ctx), unsafe.Pointer(&root))
- case KStringEscaped: ctx.efacePool.ConvTstring(node.StringCopyEsc(ctx), unsafe.Pointer(&root))
- case KTrue: root = true
- case KFalse: root = false
- case KNull: root = nil
- case KUint: ctx.efacePool.ConvF64(float64(node.U64()), unsafe.Pointer(&root))
- case KSint: ctx.efacePool.ConvF64(float64(node.I64()), unsafe.Pointer(&root))
- case KReal: ctx.efacePool.ConvF64(node.F64(), unsafe.Pointer(&root))
- case KRawNumber: ctx.efacePool.ConvTnum(node.Number(ctx), unsafe.Pointer(&root))
- default: panic("unreachable for as eface")
- }
- return root
-
-_object_key:
- node = iter.Next()
- if node.Type() == KStringCommon {
- key = node.StringRef(ctx)
- } else {
- key = node.StringCopyEsc(ctx)
- }
-
- // interface{} slot in map bucket
- val = rt.Mapassign_faststr(rt.MapEfaceMapType, mp, key)
- vt = &(*rt.GoEface)(val).Type
- vp = &(*rt.GoEface)(val).Value
-
- // parse value node
- node = iter.Next()
- switch node.Type() {
- case KObject:
- newSize := node.Object().Len()
- newMp := ctx.efacePool.GetMap(newSize)
- *vt = rt.MapEfaceType
- *vp = newMp
- remain := size - 1
- isObj = true
- if newSize != 0 {
- if remain > 0 {
- ctx.Stack.Push(mp, remain, true)
- }
- mp = newMp
- size = newSize
- goto _object_key;
- }
- case KArray:
- newSize := node.Array().Len()
- if newSize == 0 {
- ctx.efacePool.ConvTSlice(rt.EmptySlice, rt.SliceEfaceType, val)
- break;
- }
-
- newSp := ctx.efacePool.GetSlice(newSize)
- // pack to []interface{}
- ctx.efacePool.ConvTSlice(rt.GoSlice{
- Ptr: newSp,
- Len: newSize,
- Cap: newSize,
- }, rt.SliceEfaceType, val)
- remain := size - 1
- if remain > 0 {
- ctx.Stack.Push(mp, remain, true)
- }
- val = newSp
- isObj = false
- size = newSize
- goto _arr_val;
- case KStringCommon:
- ctx.efacePool.ConvTstring(node.StringRef(ctx), val)
- case KStringEscaped:
- ctx.efacePool.ConvTstring(node.StringCopyEsc(ctx), val)
- case KTrue:
- rt.ConvTBool(true, (*interface{})(val))
- case KFalse:
- rt.ConvTBool(false, (*interface{})(val))
- case KNull: /* skip */
- case KUint:
- ctx.efacePool.ConvF64(float64(node.U64()), val)
- case KSint:
- ctx.efacePool.ConvF64(float64(node.I64()), val)
- case KReal:
- ctx.efacePool.ConvF64(node.F64(), val)
- case KRawNumber:
- ctx.efacePool.ConvTnum(node.Number(ctx), val)
- default:
- panic("unreachable for as eface")
- }
-
- // check size
- size -= 1
- if size != 0 {
- goto _object_key;
- }
-
- parent, size, isObj = ctx.Stack.Pop()
-
- // parent is empty
- if parent == nil {
- if isObj {
- return rt.GoEface {
- Type: rt.MapEfaceType,
- Value: rootM,
- }.Pack()
- } else {
- ctx.efacePool.ConvTSlice(rootS, rt.SliceEfaceType, (unsafe.Pointer)(&root))
- return root
- }
- }
-
- // continue to parse parent
- if isObj {
- mp = parent
- goto _object_key;
- } else {
- val = rt.PtrAdd(parent, rt.AnyType.Size)
- goto _arr_val;
- }
-
-_arr_val:
- // interface{} slot in slice
- vt = &(*rt.GoEface)(val).Type
- vp = &(*rt.GoEface)(val).Value
-
- // parse value node
- node = iter.Next()
- switch node.Type() {
- case KObject:
- newSize := node.Object().Len()
- newMp := ctx.efacePool.GetMap(newSize)
- *vt = rt.MapEfaceType
- *vp = newMp
- remain := size - 1
- if newSize != 0 {
- // push next array elem into stack
- if remain > 0 {
- ctx.Stack.Push(val, remain, false)
- }
- mp = newMp
- size = newSize
- isObj = true
- goto _object_key;
- }
- case KArray:
- newSize := node.Array().Len()
- if newSize == 0 {
- ctx.efacePool.ConvTSlice(rt.EmptySlice, rt.SliceEfaceType, val)
- break;
- }
-
- newSp := ctx.efacePool.GetSlice(newSize)
- // pack to []interface{}
- ctx.efacePool.ConvTSlice(rt.GoSlice {
- Ptr: newSp,
- Len: newSize,
- Cap: newSize,
- }, rt.SliceEfaceType, val)
-
- remain := size - 1
- if remain > 0 {
- ctx.Stack.Push(val, remain, false)
- }
-
- val = newSp
- isObj = false
- size = newSize
- goto _arr_val;
- case KStringCommon:
- ctx.efacePool.ConvTstring(node.StringRef(ctx), val)
- case KStringEscaped:
- ctx.efacePool.ConvTstring(node.StringCopyEsc(ctx), val)
- case KTrue:
- rt.ConvTBool(true, (*interface{})(val))
- case KFalse:
- rt.ConvTBool(false, (*interface{})(val))
- case KNull: /* skip */
- case KUint:
- ctx.efacePool.ConvF64(float64(node.U64()), val)
- case KSint:
- ctx.efacePool.ConvF64(float64(node.I64()), val)
- case KReal:
- ctx.efacePool.ConvF64(node.F64(), val)
- case KRawNumber:
- ctx.efacePool.ConvTnum(node.Number(ctx), val)
- default: panic("unreachable for as eface")
- }
-
- // check size
- size -= 1
- if size != 0 {
- val = rt.PtrAdd(val, rt.AnyType.Size)
- goto _arr_val;
- }
-
-
- parent, size, isObj = ctx.Stack.Pop()
-
- // parent is empty
- if parent == nil {
- if isObj {
- return rt.GoEface {
- Type: rt.MapEfaceType,
- Value: rootM,
- }.Pack()
- } else {
- ctx.efacePool.ConvTSlice(rootS, rt.SliceEfaceType, unsafe.Pointer(&root))
- return root
- }
- }
-
- // continue to parse parent
- if isObj {
- mp = parent
- goto _object_key;
- } else {
- val = rt.PtrAdd(parent, rt.AnyType.Size)
- goto _arr_val;
- }
-}
-
-func (node *Node) AsEfaceFallback(ctx *Context) (interface{}, error) {
- switch node.Type() {
- case KObject:
- obj := node.Object()
- size := obj.Len()
- m := make(map[string]interface{}, size)
- *node = NewNode(obj.Children())
- var gerr, err error
- for i := 0; i < size; i++ {
- key, _ := node.AsStr(ctx)
- *node = NewNode(PtrOffset(node.cptr, 1))
- m[key], err = node.AsEfaceFallback(ctx)
- if gerr == nil && err != nil {
- gerr = err
- }
- }
- return m, gerr
- case KArray:
- arr := node.Array()
- size := arr.Len()
- a := make([]interface{}, size)
- *node = NewNode(arr.Children())
- var gerr, err error
- for i := 0; i < size; i++ {
- a[i], err = node.AsEfaceFallback(ctx)
- if gerr == nil && err != nil {
- gerr = err
- }
- }
- return a, gerr
- case KStringCommon:
- str, _ := node.AsStr(ctx)
- *node = NewNode(PtrOffset(node.cptr, 1))
- return str, nil
- case KStringEscaped:
- str := node.StringCopyEsc(ctx)
- *node = NewNode(PtrOffset(node.cptr, 1))
- return str, nil
- case KTrue:
- *node = NewNode(PtrOffset(node.cptr, 1))
- return true, nil
- case KFalse:
- *node = NewNode(PtrOffset(node.cptr, 1))
- return false, nil
- case KNull:
- *node = NewNode(PtrOffset(node.cptr, 1))
- return nil, nil
- default:
- // use float64
- if ctx.Parser.options & (1 << _F_use_number) != 0 {
- num, ok := node.AsNumber(ctx)
- if !ok {
- // skip the unmacthed type
- *node = NewNode(node.Next())
- return nil, newUnmatched(node.Position(), rt.JsonNumberType)
- } else {
- *node = NewNode(PtrOffset(node.cptr, 1))
- return num, nil
- }
- } else if ctx.Parser.options & (1 << _F_use_int64) != 0 {
- // first try int64
- i, ok := node.AsI64(ctx)
- if ok {
- *node = NewNode(PtrOffset(node.cptr, 1))
- return i, nil
- }
-
- // is not integer, then use float64
- f, ok := node.AsF64(ctx)
- if ok {
- *node = NewNode(PtrOffset(node.cptr, 1))
- return f, nil
- }
-
- // skip the unmacthed type
- *node = NewNode(node.Next())
- return nil, newUnmatched(node.Position(), rt.Int64Type)
- } else {
- num, ok := node.AsF64(ctx)
- if !ok {
- // skip the unmacthed type
- *node = NewNode(node.Next())
- return nil, newUnmatched(node.Position(), rt.Float64Type)
- } else {
- *node = NewNode(PtrOffset(node.cptr, 1))
- return num, nil
- }
- }
- }
-}
-
-//go:nosplit
-func PtrOffset(ptr uintptr, off int64) uintptr {
- return uintptr(int64(ptr) + off * int64(unsafe.Sizeof(node{})))
-}
diff --git a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/slice.go b/vendor/github.com/bytedance/sonic/internal/decoder/optdec/slice.go
deleted file mode 100644
index a94e422b3..000000000
--- a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/slice.go
+++ /dev/null
@@ -1,224 +0,0 @@
-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
-}
diff --git a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/stringopts.go b/vendor/github.com/bytedance/sonic/internal/decoder/optdec/stringopts.go
deleted file mode 100644
index 5af8c97e2..000000000
--- a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/stringopts.go
+++ /dev/null
@@ -1,360 +0,0 @@
-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
-}
diff --git a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/structs.go b/vendor/github.com/bytedance/sonic/internal/decoder/optdec/structs.go
deleted file mode 100644
index bce2758f1..000000000
--- a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/structs.go
+++ /dev/null
@@ -1,61 +0,0 @@
-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
-}
-
diff --git a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/types.go b/vendor/github.com/bytedance/sonic/internal/decoder/optdec/types.go
deleted file mode 100644
index fe1433eec..000000000
--- a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/types.go
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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)
-}