diff options
Diffstat (limited to 'vendor/github.com/bytedance/sonic/internal/decoder/optdec')
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) -} |