summaryrefslogtreecommitdiff
path: root/vendor/github.com/bytedance/sonic/ast
diff options
context:
space:
mode:
authorLibravatar Terin Stock <terinjokes@gmail.com>2025-03-09 17:47:56 +0100
committerLibravatar Terin Stock <terinjokes@gmail.com>2025-03-10 01:59:49 +0100
commit3ac1ee16f377d31a0fb80c8dae28b6239ac4229e (patch)
treef61faa581feaaeaba2542b9f2b8234a590684413 /vendor/github.com/bytedance/sonic/ast
parent[chore] update URLs to forked source (diff)
downloadgotosocial-3ac1ee16f377d31a0fb80c8dae28b6239ac4229e.tar.xz
[chore] remove vendor
Diffstat (limited to 'vendor/github.com/bytedance/sonic/ast')
-rw-r--r--vendor/github.com/bytedance/sonic/ast/api.go135
-rw-r--r--vendor/github.com/bytedance/sonic/ast/api_compat.go114
-rw-r--r--vendor/github.com/bytedance/sonic/ast/asm.s0
-rw-r--r--vendor/github.com/bytedance/sonic/ast/buffer.go470
-rw-r--r--vendor/github.com/bytedance/sonic/ast/decode.go562
-rw-r--r--vendor/github.com/bytedance/sonic/ast/encode.go274
-rw-r--r--vendor/github.com/bytedance/sonic/ast/error.go134
-rw-r--r--vendor/github.com/bytedance/sonic/ast/iterator.go216
-rw-r--r--vendor/github.com/bytedance/sonic/ast/node.go1843
-rw-r--r--vendor/github.com/bytedance/sonic/ast/parser.go766
-rw-r--r--vendor/github.com/bytedance/sonic/ast/search.go157
-rw-r--r--vendor/github.com/bytedance/sonic/ast/stubs.go142
-rw-r--r--vendor/github.com/bytedance/sonic/ast/visitor.go332
13 files changed, 0 insertions, 5145 deletions
diff --git a/vendor/github.com/bytedance/sonic/ast/api.go b/vendor/github.com/bytedance/sonic/ast/api.go
deleted file mode 100644
index 7c8253aa1..000000000
--- a/vendor/github.com/bytedance/sonic/ast/api.go
+++ /dev/null
@@ -1,135 +0,0 @@
-//go:build (amd64 && go1.17 && !go1.24) || (arm64 && go1.20 && !go1.24)
-// +build amd64,go1.17,!go1.24 arm64,go1.20,!go1.24
-
-/*
- * Copyright 2022 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 ast
-
-import (
- `runtime`
- `unsafe`
-
- `github.com/bytedance/sonic/encoder`
- `github.com/bytedance/sonic/internal/native`
- `github.com/bytedance/sonic/internal/native/types`
- `github.com/bytedance/sonic/internal/rt`
- uq `github.com/bytedance/sonic/unquote`
- `github.com/bytedance/sonic/utf8`
-)
-
-var typeByte = rt.UnpackEface(byte(0)).Type
-
-//go:nocheckptr
-func quote(buf *[]byte, val string) {
- *buf = append(*buf, '"')
- if len(val) == 0 {
- *buf = append(*buf, '"')
- return
- }
-
- sp := rt.IndexChar(val, 0)
- nb := len(val)
- b := (*rt.GoSlice)(unsafe.Pointer(buf))
-
- // input buffer
- for nb > 0 {
- // output buffer
- dp := unsafe.Pointer(uintptr(b.Ptr) + uintptr(b.Len))
- dn := b.Cap - b.Len
- // call native.Quote, dn is byte count it outputs
- ret := native.Quote(sp, nb, dp, &dn, 0)
- // update *buf length
- b.Len += dn
-
- // no need more output
- if ret >= 0 {
- break
- }
-
- // double buf size
- *b = rt.GrowSlice(typeByte, *b, b.Cap*2)
- // ret is the complement of consumed input
- ret = ^ret
- // update input buffer
- nb -= ret
- sp = unsafe.Pointer(uintptr(sp) + uintptr(ret))
- }
-
- runtime.KeepAlive(buf)
- runtime.KeepAlive(sp)
- *buf = append(*buf, '"')
-}
-
-func unquote(src string) (string, types.ParsingError) {
- return uq.String(src)
-}
-
-func (self *Parser) decodeValue() (val types.JsonState) {
- sv := (*rt.GoString)(unsafe.Pointer(&self.s))
- flag := types.F_USE_NUMBER
- if self.dbuf != nil {
- flag = 0
- val.Dbuf = self.dbuf
- val.Dcap = types.MaxDigitNums
- }
- self.p = native.Value(sv.Ptr, sv.Len, self.p, &val, uint64(flag))
- return
-}
-
-func (self *Parser) skip() (int, types.ParsingError) {
- fsm := types.NewStateMachine()
- start := native.SkipOne(&self.s, &self.p, fsm, 0)
- types.FreeStateMachine(fsm)
-
- if start < 0 {
- return self.p, types.ParsingError(-start)
- }
- return start, 0
-}
-
-func (self *Node) encodeInterface(buf *[]byte) error {
- //WARN: NOT compatible with json.Encoder
- return encoder.EncodeInto(buf, self.packAny(), encoder.NoEncoderNewline)
-}
-
-func (self *Parser) skipFast() (int, types.ParsingError) {
- start := native.SkipOneFast(&self.s, &self.p)
- if start < 0 {
- return self.p, types.ParsingError(-start)
- }
- return start, 0
-}
-
-func (self *Parser) getByPath(validate bool, path ...interface{}) (int, types.ParsingError) {
- var fsm *types.StateMachine
- if validate {
- fsm = types.NewStateMachine()
- }
- start := native.GetByPath(&self.s, &self.p, &path, fsm)
- if validate {
- types.FreeStateMachine(fsm)
- }
- runtime.KeepAlive(path)
- if start < 0 {
- return self.p, types.ParsingError(-start)
- }
- return start, 0
-}
-
-func validate_utf8(str string) bool {
- return utf8.ValidateString(str)
-}
diff --git a/vendor/github.com/bytedance/sonic/ast/api_compat.go b/vendor/github.com/bytedance/sonic/ast/api_compat.go
deleted file mode 100644
index 6541e219d..000000000
--- a/vendor/github.com/bytedance/sonic/ast/api_compat.go
+++ /dev/null
@@ -1,114 +0,0 @@
-// +build !amd64,!arm64 go1.24 !go1.17 arm64,!go1.20
-
-/*
-* Copyright 2022 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 ast
-
-import (
- `encoding/json`
- `unicode/utf8`
-
- `github.com/bytedance/sonic/internal/native/types`
- `github.com/bytedance/sonic/internal/rt`
-)
-
-func init() {
- println("WARNING:(ast) sonic only supports go1.17~1.23, but your environment is not suitable")
-}
-
-func quote(buf *[]byte, val string) {
- quoteString(buf, val)
-}
-
-// unquote unescapes an internal JSON string (it doesn't count quotas at the beginning and end)
-func unquote(src string) (string, types.ParsingError) {
- sp := rt.IndexChar(src, -1)
- out, ok := unquoteBytes(rt.BytesFrom(sp, len(src)+2, len(src)+2))
- if !ok {
- return "", types.ERR_INVALID_ESCAPE
- }
- return rt.Mem2Str(out), 0
-}
-
-
-func (self *Parser) decodeValue() (val types.JsonState) {
- e, v := decodeValue(self.s, self.p, self.dbuf == nil)
- if e < 0 {
- return v
- }
- self.p = e
- return v
-}
-
-func (self *Parser) skip() (int, types.ParsingError) {
- e, s := skipValue(self.s, self.p)
- if e < 0 {
- return self.p, types.ParsingError(-e)
- }
- self.p = e
- return s, 0
-}
-
-func (self *Parser) skipFast() (int, types.ParsingError) {
- e, s := skipValueFast(self.s, self.p)
- if e < 0 {
- return self.p, types.ParsingError(-e)
- }
- self.p = e
- return s, 0
-}
-
-func (self *Node) encodeInterface(buf *[]byte) error {
- out, err := json.Marshal(self.packAny())
- if err != nil {
- return err
- }
- *buf = append(*buf, out...)
- return nil
-}
-
-func (self *Parser) getByPath(validate bool, path ...interface{}) (int, types.ParsingError) {
- for _, p := range path {
- if idx, ok := p.(int); ok && idx >= 0 {
- if err := self.searchIndex(idx); err != 0 {
- return self.p, err
- }
- } else if key, ok := p.(string); ok {
- if err := self.searchKey(key); err != 0 {
- return self.p, err
- }
- } else {
- panic("path must be either int(>=0) or string")
- }
- }
-
- var start int
- var e types.ParsingError
- if validate {
- start, e = self.skip()
- } else {
- start, e = self.skipFast()
- }
- if e != 0 {
- return self.p, e
- }
- return start, 0
-}
-
-func validate_utf8(str string) bool {
- return utf8.ValidString(str)
-}
diff --git a/vendor/github.com/bytedance/sonic/ast/asm.s b/vendor/github.com/bytedance/sonic/ast/asm.s
deleted file mode 100644
index e69de29bb..000000000
--- a/vendor/github.com/bytedance/sonic/ast/asm.s
+++ /dev/null
diff --git a/vendor/github.com/bytedance/sonic/ast/buffer.go b/vendor/github.com/bytedance/sonic/ast/buffer.go
deleted file mode 100644
index 04701ef5b..000000000
--- a/vendor/github.com/bytedance/sonic/ast/buffer.go
+++ /dev/null
@@ -1,470 +0,0 @@
-/**
- * Copyright 2023 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 ast
-
-import (
- "sort"
- "unsafe"
-
- "github.com/bytedance/sonic/internal/caching"
-)
-
-type nodeChunk [_DEFAULT_NODE_CAP]Node
-
-type linkedNodes struct {
- head nodeChunk
- tail []*nodeChunk
- size int
-}
-
-func (self *linkedNodes) Cap() int {
- if self == nil {
- return 0
- }
- return (len(self.tail)+1)*_DEFAULT_NODE_CAP
-}
-
-func (self *linkedNodes) Len() int {
- if self == nil {
- return 0
- }
- return self.size
-}
-
-func (self *linkedNodes) At(i int) (*Node) {
- if self == nil {
- return nil
- }
- if i >= 0 && i<self.size && i < _DEFAULT_NODE_CAP {
- return &self.head[i]
- } else if i >= _DEFAULT_NODE_CAP && i<self.size {
- a, b := i/_DEFAULT_NODE_CAP-1, i%_DEFAULT_NODE_CAP
- if a < len(self.tail) {
- return &self.tail[a][b]
- }
- }
- return nil
-}
-
-func (self *linkedNodes) MoveOne(source int, target int) {
- if source == target {
- return
- }
- if source < 0 || source >= self.size || target < 0 || target >= self.size {
- return
- }
- // reserve source
- n := *self.At(source)
- if source < target {
- // move every element (source,target] one step back
- for i:=source; i<target; i++ {
- *self.At(i) = *self.At(i+1)
- }
- } else {
- // move every element [target,source) one step forward
- for i:=source; i>target; i-- {
- *self.At(i) = *self.At(i-1)
- }
- }
- // set target
- *self.At(target) = n
-}
-
-func (self *linkedNodes) Pop() {
- if self == nil || self.size == 0 {
- return
- }
- self.Set(self.size-1, Node{})
- self.size--
-}
-
-func (self *linkedNodes) Push(v Node) {
- self.Set(self.size, v)
-}
-
-
-func (self *linkedNodes) Set(i int, v Node) {
- if i < _DEFAULT_NODE_CAP {
- self.head[i] = v
- if self.size <= i {
- self.size = i+1
- }
- return
- }
- a, b := i/_DEFAULT_NODE_CAP-1, i%_DEFAULT_NODE_CAP
- if a < 0 {
- self.head[b] = v
- } else {
- self.growTailLength(a+1)
- var n = &self.tail[a]
- if *n == nil {
- *n = new(nodeChunk)
- }
- (*n)[b] = v
- }
- if self.size <= i {
- self.size = i+1
- }
-}
-
-func (self *linkedNodes) growTailLength(l int) {
- if l <= len(self.tail) {
- return
- }
- c := cap(self.tail)
- for c < l {
- c += 1 + c>>_APPEND_GROW_SHIFT
- }
- if c == cap(self.tail) {
- self.tail = self.tail[:l]
- return
- }
- tmp := make([]*nodeChunk, l, c)
- copy(tmp, self.tail)
- self.tail = tmp
-}
-
-func (self *linkedNodes) ToSlice(con []Node) {
- if len(con) < self.size {
- return
- }
- i := (self.size-1)
- a, b := i/_DEFAULT_NODE_CAP-1, i%_DEFAULT_NODE_CAP
- if a < 0 {
- copy(con, self.head[:b+1])
- return
- } else {
- copy(con, self.head[:])
- con = con[_DEFAULT_NODE_CAP:]
- }
-
- for i:=0; i<a; i++ {
- copy(con, self.tail[i][:])
- con = con[_DEFAULT_NODE_CAP:]
- }
- copy(con, self.tail[a][:b+1])
-}
-
-func (self *linkedNodes) FromSlice(con []Node) {
- self.size = len(con)
- i := self.size-1
- a, b := i/_DEFAULT_NODE_CAP-1, i%_DEFAULT_NODE_CAP
- if a < 0 {
- copy(self.head[:b+1], con)
- return
- } else {
- copy(self.head[:], con)
- con = con[_DEFAULT_NODE_CAP:]
- }
-
- if cap(self.tail) <= a {
- c := (a+1) + (a+1)>>_APPEND_GROW_SHIFT
- self.tail = make([]*nodeChunk, a+1, c)
- }
- self.tail = self.tail[:a+1]
-
- for i:=0; i<a; i++ {
- self.tail[i] = new(nodeChunk)
- copy(self.tail[i][:], con)
- con = con[_DEFAULT_NODE_CAP:]
- }
-
- self.tail[a] = new(nodeChunk)
- copy(self.tail[a][:b+1], con)
-}
-
-type pairChunk [_DEFAULT_NODE_CAP]Pair
-
-type linkedPairs struct {
- index map[uint64]int
- head pairChunk
- tail []*pairChunk
- size int
-}
-
-func (self *linkedPairs) BuildIndex() {
- if self.index == nil {
- self.index = make(map[uint64]int, self.size)
- }
- for i:=0; i<self.size; i++ {
- p := self.At(i)
- self.index[p.hash] = i
- }
-}
-
-func (self *linkedPairs) Cap() int {
- if self == nil {
- return 0
- }
- return (len(self.tail)+1)*_DEFAULT_NODE_CAP
-}
-
-func (self *linkedPairs) Len() int {
- if self == nil {
- return 0
- }
- return self.size
-}
-
-func (self *linkedPairs) At(i int) *Pair {
- if self == nil {
- return nil
- }
- if i >= 0 && i < _DEFAULT_NODE_CAP && i<self.size {
- return &self.head[i]
- } else if i >= _DEFAULT_NODE_CAP && i<self.size {
- a, b := i/_DEFAULT_NODE_CAP-1, i%_DEFAULT_NODE_CAP
- if a < len(self.tail) {
- return &self.tail[a][b]
- }
- }
- return nil
-}
-
-func (self *linkedPairs) Push(v Pair) {
- self.Set(self.size, v)
-}
-
-func (self *linkedPairs) Pop() {
- if self == nil || self.size == 0 {
- return
- }
- self.Unset(self.size-1)
- self.size--
-}
-
-func (self *linkedPairs) Unset(i int) {
- if self.index != nil {
- p := self.At(i)
- delete(self.index, p.hash)
- }
- self.set(i, Pair{})
-}
-
-func (self *linkedPairs) Set(i int, v Pair) {
- if self.index != nil {
- h := v.hash
- self.index[h] = i
- }
- self.set(i, v)
-}
-
-func (self *linkedPairs) set(i int, v Pair) {
- if i < _DEFAULT_NODE_CAP {
- self.head[i] = v
- if self.size <= i {
- self.size = i+1
- }
- return
- }
- a, b := i/_DEFAULT_NODE_CAP-1, i%_DEFAULT_NODE_CAP
- if a < 0 {
- self.head[b] = v
- } else {
- self.growTailLength(a+1)
- var n = &self.tail[a]
- if *n == nil {
- *n = new(pairChunk)
- }
- (*n)[b] = v
- }
- if self.size <= i {
- self.size = i+1
- }
-}
-
-func (self *linkedPairs) growTailLength(l int) {
- if l <= len(self.tail) {
- return
- }
- c := cap(self.tail)
- for c < l {
- c += 1 + c>>_APPEND_GROW_SHIFT
- }
- if c == cap(self.tail) {
- self.tail = self.tail[:l]
- return
- }
- tmp := make([]*pairChunk, l, c)
- copy(tmp, self.tail)
- self.tail = tmp
-}
-
-// linear search
-func (self *linkedPairs) Get(key string) (*Pair, int) {
- if self.index != nil {
- // fast-path
- i, ok := self.index[caching.StrHash(key)]
- if ok {
- n := self.At(i)
- if n.Key == key {
- return n, i
- }
- // hash conflicts
- goto linear_search
- } else {
- return nil, -1
- }
- }
-linear_search:
- for i:=0; i<self.size; i++ {
- if n := self.At(i); n.Key == key {
- return n, i
- }
- }
- return nil, -1
-}
-
-func (self *linkedPairs) ToSlice(con []Pair) {
- if len(con) < self.size {
- return
- }
- i := self.size-1
- a, b := i/_DEFAULT_NODE_CAP-1, i%_DEFAULT_NODE_CAP
-
- if a < 0 {
- copy(con, self.head[:b+1])
- return
- } else {
- copy(con, self.head[:])
- con = con[_DEFAULT_NODE_CAP:]
- }
-
- for i:=0; i<a; i++ {
- copy(con, self.tail[i][:])
- con = con[_DEFAULT_NODE_CAP:]
- }
- copy(con, self.tail[a][:b+1])
-}
-
-func (self *linkedPairs) ToMap(con map[string]Node) {
- for i:=0; i<self.size; i++ {
- n := self.At(i)
- con[n.Key] = n.Value
- }
-}
-
-func (self *linkedPairs) copyPairs(to []Pair, from []Pair, l int) {
- copy(to, from)
- if self.index != nil {
- for i:=0; i<l; i++ {
- // NOTICE: in case of user not pass hash, just cal it
- h := caching.StrHash(from[i].Key)
- from[i].hash = h
- self.index[h] = i
- }
- }
-}
-
-func (self *linkedPairs) FromSlice(con []Pair) {
- self.size = len(con)
- i := self.size-1
- a, b := i/_DEFAULT_NODE_CAP-1, i%_DEFAULT_NODE_CAP
- if a < 0 {
- self.copyPairs(self.head[:b+1], con, b+1)
- return
- } else {
- self.copyPairs(self.head[:], con, len(self.head))
- con = con[_DEFAULT_NODE_CAP:]
- }
-
- if cap(self.tail) <= a {
- c := (a+1) + (a+1)>>_APPEND_GROW_SHIFT
- self.tail = make([]*pairChunk, a+1, c)
- }
- self.tail = self.tail[:a+1]
-
- for i:=0; i<a; i++ {
- self.tail[i] = new(pairChunk)
- self.copyPairs(self.tail[i][:], con, len(self.tail[i]))
- con = con[_DEFAULT_NODE_CAP:]
- }
-
- self.tail[a] = new(pairChunk)
- self.copyPairs(self.tail[a][:b+1], con, b+1)
-}
-
-func (self *linkedPairs) Less(i, j int) bool {
- return lessFrom(self.At(i).Key, self.At(j).Key, 0)
-}
-
-func (self *linkedPairs) Swap(i, j int) {
- a, b := self.At(i), self.At(j)
- if self.index != nil {
- self.index[a.hash] = j
- self.index[b.hash] = i
- }
- *a, *b = *b, *a
-}
-
-func (self *linkedPairs) Sort() {
- sort.Stable(self)
-}
-
-// Compare two strings from the pos d.
-func lessFrom(a, b string, d int) bool {
- l := len(a)
- if l > len(b) {
- l = len(b)
- }
- for i := d; i < l; i++ {
- if a[i] == b[i] {
- continue
- }
- return a[i] < b[i]
- }
- return len(a) < len(b)
-}
-
-type parseObjectStack struct {
- parser Parser
- v linkedPairs
-}
-
-type parseArrayStack struct {
- parser Parser
- v linkedNodes
-}
-
-func newLazyArray(p *Parser) Node {
- s := new(parseArrayStack)
- s.parser = *p
- return Node{
- t: _V_ARRAY_LAZY,
- p: unsafe.Pointer(s),
- }
-}
-
-func newLazyObject(p *Parser) Node {
- s := new(parseObjectStack)
- s.parser = *p
- return Node{
- t: _V_OBJECT_LAZY,
- p: unsafe.Pointer(s),
- }
-}
-
-func (self *Node) getParserAndArrayStack() (*Parser, *parseArrayStack) {
- stack := (*parseArrayStack)(self.p)
- return &stack.parser, stack
-}
-
-func (self *Node) getParserAndObjectStack() (*Parser, *parseObjectStack) {
- stack := (*parseObjectStack)(self.p)
- return &stack.parser, stack
-}
-
diff --git a/vendor/github.com/bytedance/sonic/ast/decode.go b/vendor/github.com/bytedance/sonic/ast/decode.go
deleted file mode 100644
index 135ee6eb8..000000000
--- a/vendor/github.com/bytedance/sonic/ast/decode.go
+++ /dev/null
@@ -1,562 +0,0 @@
-/*
- * Copyright 2022 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 ast
-
-import (
- "encoding/base64"
- "runtime"
- "strconv"
- "unsafe"
-
- "github.com/bytedance/sonic/internal/native/types"
- "github.com/bytedance/sonic/internal/rt"
- "github.com/bytedance/sonic/internal/utils"
-)
-
-// Hack: this is used for both checking space and cause friendly compile errors in 32-bit arch.
-const _Sonic_Not_Support_32Bit_Arch__Checking_32Bit_Arch_Here = (1 << ' ') | (1 << '\t') | (1 << '\r') | (1 << '\n')
-
-var bytesNull = []byte("null")
-
-const (
- strNull = "null"
- bytesTrue = "true"
- bytesFalse = "false"
- bytesObject = "{}"
- bytesArray = "[]"
-)
-
-func isSpace(c byte) bool {
- return (int(1<<c) & _Sonic_Not_Support_32Bit_Arch__Checking_32Bit_Arch_Here) != 0
-}
-
-//go:nocheckptr
-func skipBlank(src string, pos int) int {
- se := uintptr(rt.IndexChar(src, len(src)))
- sp := uintptr(rt.IndexChar(src, pos))
-
- for sp < se {
- if !isSpace(*(*byte)(unsafe.Pointer(sp))) {
- break
- }
- sp += 1
- }
- if sp >= se {
- return -int(types.ERR_EOF)
- }
- runtime.KeepAlive(src)
- return int(sp - uintptr(rt.IndexChar(src, 0)))
-}
-
-func decodeNull(src string, pos int) (ret int) {
- ret = pos + 4
- if ret > len(src) {
- return -int(types.ERR_EOF)
- }
- if src[pos:ret] == strNull {
- return ret
- } else {
- return -int(types.ERR_INVALID_CHAR)
- }
-}
-
-func decodeTrue(src string, pos int) (ret int) {
- ret = pos + 4
- if ret > len(src) {
- return -int(types.ERR_EOF)
- }
- if src[pos:ret] == bytesTrue {
- return ret
- } else {
- return -int(types.ERR_INVALID_CHAR)
- }
-
-}
-
-func decodeFalse(src string, pos int) (ret int) {
- ret = pos + 5
- if ret > len(src) {
- return -int(types.ERR_EOF)
- }
- if src[pos:ret] == bytesFalse {
- return ret
- }
- return -int(types.ERR_INVALID_CHAR)
-}
-
-//go:nocheckptr
-func decodeString(src string, pos int) (ret int, v string) {
- ret, ep := skipString(src, pos)
- if ep == -1 {
- (*rt.GoString)(unsafe.Pointer(&v)).Ptr = rt.IndexChar(src, pos+1)
- (*rt.GoString)(unsafe.Pointer(&v)).Len = ret - pos - 2
- return ret, v
- }
-
- vv, ok := unquoteBytes(rt.Str2Mem(src[pos:ret]))
- if !ok {
- return -int(types.ERR_INVALID_CHAR), ""
- }
-
- runtime.KeepAlive(src)
- return ret, rt.Mem2Str(vv)
-}
-
-func decodeBinary(src string, pos int) (ret int, v []byte) {
- var vv string
- ret, vv = decodeString(src, pos)
- if ret < 0 {
- return ret, nil
- }
- var err error
- v, err = base64.StdEncoding.DecodeString(vv)
- if err != nil {
- return -int(types.ERR_INVALID_CHAR), nil
- }
- return ret, v
-}
-
-func isDigit(c byte) bool {
- return c >= '0' && c <= '9'
-}
-
-//go:nocheckptr
-func decodeInt64(src string, pos int) (ret int, v int64, err error) {
- sp := uintptr(rt.IndexChar(src, pos))
- ss := uintptr(sp)
- se := uintptr(rt.IndexChar(src, len(src)))
- if uintptr(sp) >= se {
- return -int(types.ERR_EOF), 0, nil
- }
-
- if c := *(*byte)(unsafe.Pointer(sp)); c == '-' {
- sp += 1
- }
- if sp == se {
- return -int(types.ERR_EOF), 0, nil
- }
-
- for ; sp < se; sp += uintptr(1) {
- if !isDigit(*(*byte)(unsafe.Pointer(sp))) {
- break
- }
- }
-
- if sp < se {
- if c := *(*byte)(unsafe.Pointer(sp)); c == '.' || c == 'e' || c == 'E' {
- return -int(types.ERR_INVALID_NUMBER_FMT), 0, nil
- }
- }
-
- var vv string
- ret = int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr))
- (*rt.GoString)(unsafe.Pointer(&vv)).Ptr = unsafe.Pointer(ss)
- (*rt.GoString)(unsafe.Pointer(&vv)).Len = ret - pos
-
- v, err = strconv.ParseInt(vv, 10, 64)
- if err != nil {
- //NOTICE: allow overflow here
- if err.(*strconv.NumError).Err == strconv.ErrRange {
- return ret, 0, err
- }
- return -int(types.ERR_INVALID_CHAR), 0, err
- }
-
- runtime.KeepAlive(src)
- return ret, v, nil
-}
-
-func isNumberChars(c byte) bool {
- return (c >= '0' && c <= '9') || c == '+' || c == '-' || c == 'e' || c == 'E' || c == '.'
-}
-
-//go:nocheckptr
-func decodeFloat64(src string, pos int) (ret int, v float64, err error) {
- sp := uintptr(rt.IndexChar(src, pos))
- ss := uintptr(sp)
- se := uintptr(rt.IndexChar(src, len(src)))
- if uintptr(sp) >= se {
- return -int(types.ERR_EOF), 0, nil
- }
-
- if c := *(*byte)(unsafe.Pointer(sp)); c == '-' {
- sp += 1
- }
- if sp == se {
- return -int(types.ERR_EOF), 0, nil
- }
-
- for ; sp < se; sp += uintptr(1) {
- if !isNumberChars(*(*byte)(unsafe.Pointer(sp))) {
- break
- }
- }
-
- var vv string
- ret = int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr))
- (*rt.GoString)(unsafe.Pointer(&vv)).Ptr = unsafe.Pointer(ss)
- (*rt.GoString)(unsafe.Pointer(&vv)).Len = ret - pos
-
- v, err = strconv.ParseFloat(vv, 64)
- if err != nil {
- //NOTICE: allow overflow here
- if err.(*strconv.NumError).Err == strconv.ErrRange {
- return ret, 0, err
- }
- return -int(types.ERR_INVALID_CHAR), 0, err
- }
-
- runtime.KeepAlive(src)
- return ret, v, nil
-}
-
-func decodeValue(src string, pos int, skipnum bool) (ret int, v types.JsonState) {
- pos = skipBlank(src, pos)
- if pos < 0 {
- return pos, types.JsonState{Vt: types.ValueType(pos)}
- }
- switch c := src[pos]; c {
- case 'n':
- ret = decodeNull(src, pos)
- if ret < 0 {
- return ret, types.JsonState{Vt: types.ValueType(ret)}
- }
- return ret, types.JsonState{Vt: types.V_NULL}
- case '"':
- var ep int
- ret, ep = skipString(src, pos)
- if ret < 0 {
- return ret, types.JsonState{Vt: types.ValueType(ret)}
- }
- return ret, types.JsonState{Vt: types.V_STRING, Iv: int64(pos + 1), Ep: ep}
- case '{':
- return pos + 1, types.JsonState{Vt: types.V_OBJECT}
- case '[':
- return pos + 1, types.JsonState{Vt: types.V_ARRAY}
- case 't':
- ret = decodeTrue(src, pos)
- if ret < 0 {
- return ret, types.JsonState{Vt: types.ValueType(ret)}
- }
- return ret, types.JsonState{Vt: types.V_TRUE}
- case 'f':
- ret = decodeFalse(src, pos)
- if ret < 0 {
- return ret, types.JsonState{Vt: types.ValueType(ret)}
- }
- return ret, types.JsonState{Vt: types.V_FALSE}
- case '-', '+', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
- if skipnum {
- ret = skipNumber(src, pos)
- if ret >= 0 {
- return ret, types.JsonState{Vt: types.V_DOUBLE, Iv: 0, Ep: pos}
- } else {
- return ret, types.JsonState{Vt: types.ValueType(ret)}
- }
- } else {
- var iv int64
- ret, iv, _ = decodeInt64(src, pos)
- if ret >= 0 {
- return ret, types.JsonState{Vt: types.V_INTEGER, Iv: iv, Ep: pos}
- } else if ret != -int(types.ERR_INVALID_NUMBER_FMT) {
- return ret, types.JsonState{Vt: types.ValueType(ret)}
- }
- var fv float64
- ret, fv, _ = decodeFloat64(src, pos)
- if ret >= 0 {
- return ret, types.JsonState{Vt: types.V_DOUBLE, Dv: fv, Ep: pos}
- } else {
- return ret, types.JsonState{Vt: types.ValueType(ret)}
- }
- }
-
- default:
- return -int(types.ERR_INVALID_CHAR), types.JsonState{Vt:-types.ValueType(types.ERR_INVALID_CHAR)}
- }
-}
-
-//go:nocheckptr
-func skipNumber(src string, pos int) (ret int) {
- return utils.SkipNumber(src, pos)
-}
-
-//go:nocheckptr
-func skipString(src string, pos int) (ret int, ep int) {
- if pos+1 >= len(src) {
- return -int(types.ERR_EOF), -1
- }
-
- sp := uintptr(rt.IndexChar(src, pos))
- se := uintptr(rt.IndexChar(src, len(src)))
-
- // not start with quote
- if *(*byte)(unsafe.Pointer(sp)) != '"' {
- return -int(types.ERR_INVALID_CHAR), -1
- }
- sp += 1
-
- ep = -1
- for sp < se {
- c := *(*byte)(unsafe.Pointer(sp))
- if c == '\\' {
- if ep == -1 {
- ep = int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr))
- }
- sp += 2
- continue
- }
- sp += 1
- if c == '"' {
- return int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr)), ep
- }
- }
-
- runtime.KeepAlive(src)
- // not found the closed quote until EOF
- return -int(types.ERR_EOF), -1
-}
-
-//go:nocheckptr
-func skipPair(src string, pos int, lchar byte, rchar byte) (ret int) {
- if pos+1 >= len(src) {
- return -int(types.ERR_EOF)
- }
-
- sp := uintptr(rt.IndexChar(src, pos))
- se := uintptr(rt.IndexChar(src, len(src)))
-
- if *(*byte)(unsafe.Pointer(sp)) != lchar {
- return -int(types.ERR_INVALID_CHAR)
- }
-
- sp += 1
- nbrace := 1
- inquote := false
-
- for sp < se {
- c := *(*byte)(unsafe.Pointer(sp))
- if c == '\\' {
- sp += 2
- continue
- } else if c == '"' {
- inquote = !inquote
- } else if c == lchar {
- if !inquote {
- nbrace += 1
- }
- } else if c == rchar {
- if !inquote {
- nbrace -= 1
- if nbrace == 0 {
- sp += 1
- break
- }
- }
- }
- sp += 1
- }
-
- if nbrace != 0 {
- return -int(types.ERR_INVALID_CHAR)
- }
-
- runtime.KeepAlive(src)
- return int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr))
-}
-
-func skipValueFast(src string, pos int) (ret int, start int) {
- pos = skipBlank(src, pos)
- if pos < 0 {
- return pos, -1
- }
- switch c := src[pos]; c {
- case 'n':
- ret = decodeNull(src, pos)
- case '"':
- ret, _ = skipString(src, pos)
- case '{':
- ret = skipPair(src, pos, '{', '}')
- case '[':
- ret = skipPair(src, pos, '[', ']')
- case 't':
- ret = decodeTrue(src, pos)
- case 'f':
- ret = decodeFalse(src, pos)
- case '-', '+', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
- ret = skipNumber(src, pos)
- default:
- ret = -int(types.ERR_INVALID_CHAR)
- }
- return ret, pos
-}
-
-func skipValue(src string, pos int) (ret int, start int) {
- pos = skipBlank(src, pos)
- if pos < 0 {
- return pos, -1
- }
- switch c := src[pos]; c {
- case 'n':
- ret = decodeNull(src, pos)
- case '"':
- ret, _ = skipString(src, pos)
- case '{':
- ret, _ = skipObject(src, pos)
- case '[':
- ret, _ = skipArray(src, pos)
- case 't':
- ret = decodeTrue(src, pos)
- case 'f':
- ret = decodeFalse(src, pos)
- case '-', '+', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
- ret = skipNumber(src, pos)
- default:
- ret = -int(types.ERR_INVALID_CHAR)
- }
- return ret, pos
-}
-
-func skipObject(src string, pos int) (ret int, start int) {
- start = skipBlank(src, pos)
- if start < 0 {
- return start, -1
- }
-
- if src[start] != '{' {
- return -int(types.ERR_INVALID_CHAR), -1
- }
-
- pos = start + 1
- pos = skipBlank(src, pos)
- if pos < 0 {
- return pos, -1
- }
- if src[pos] == '}' {
- return pos + 1, start
- }
-
- for {
- pos, _ = skipString(src, pos)
- if pos < 0 {
- return pos, -1
- }
-
- pos = skipBlank(src, pos)
- if pos < 0 {
- return pos, -1
- }
- if src[pos] != ':' {
- return -int(types.ERR_INVALID_CHAR), -1
- }
-
- pos++
- pos, _ = skipValue(src, pos)
- if pos < 0 {
- return pos, -1
- }
-
- pos = skipBlank(src, pos)
- if pos < 0 {
- return pos, -1
- }
- if src[pos] == '}' {
- return pos + 1, start
- }
- if src[pos] != ',' {
- return -int(types.ERR_INVALID_CHAR), -1
- }
-
- pos++
- pos = skipBlank(src, pos)
- if pos < 0 {
- return pos, -1
- }
-
- }
-}
-
-func skipArray(src string, pos int) (ret int, start int) {
- start = skipBlank(src, pos)
- if start < 0 {
- return start, -1
- }
-
- if src[start] != '[' {
- return -int(types.ERR_INVALID_CHAR), -1
- }
-
- pos = start + 1
- pos = skipBlank(src, pos)
- if pos < 0 {
- return pos, -1
- }
- if src[pos] == ']' {
- return pos + 1, start
- }
-
- for {
- pos, _ = skipValue(src, pos)
- if pos < 0 {
- return pos, -1
- }
-
- pos = skipBlank(src, pos)
- if pos < 0 {
- return pos, -1
- }
- if src[pos] == ']' {
- return pos + 1, start
- }
- if src[pos] != ',' {
- return -int(types.ERR_INVALID_CHAR), -1
- }
- pos++
- }
-}
-
-// DecodeString decodes a JSON string from pos and return golang string.
-// - needEsc indicates if to unescaped escaping chars
-// - hasEsc tells if the returned string has escaping chars
-// - validStr enables validating UTF8 charset
-//
-func _DecodeString(src string, pos int, needEsc bool, validStr bool) (v string, ret int, hasEsc bool) {
- p := NewParserObj(src)
- p.p = pos
- switch val := p.decodeValue(); val.Vt {
- case types.V_STRING:
- str := p.s[val.Iv : p.p-1]
- if validStr && !validate_utf8(str) {
- return "", -int(types.ERR_INVALID_UTF8), false
- }
- /* fast path: no escape sequence */
- if val.Ep == -1 {
- return str, p.p, false
- } else if !needEsc {
- return str, p.p, true
- }
- /* unquote the string */
- out, err := unquote(str)
- /* check for errors */
- if err != 0 {
- return "", -int(err), true
- } else {
- return out, p.p, true
- }
- default:
- return "", -int(_ERR_UNSUPPORT_TYPE), false
- }
-}
diff --git a/vendor/github.com/bytedance/sonic/ast/encode.go b/vendor/github.com/bytedance/sonic/ast/encode.go
deleted file mode 100644
index eae0bd258..000000000
--- a/vendor/github.com/bytedance/sonic/ast/encode.go
+++ /dev/null
@@ -1,274 +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 ast
-
-import (
- "sync"
- "unicode/utf8"
-
- "github.com/bytedance/sonic/internal/rt"
- "github.com/bytedance/sonic/option"
-)
-
-func quoteString(e *[]byte, s string) {
- *e = append(*e, '"')
- start := 0
- for i := 0; i < len(s); {
- if b := s[i]; b < utf8.RuneSelf {
- if rt.SafeSet[b] {
- i++
- continue
- }
- if start < i {
- *e = append(*e, s[start:i]...)
- }
- *e = append(*e, '\\')
- switch b {
- case '\\', '"':
- *e = append(*e, b)
- case '\n':
- *e = append(*e, 'n')
- case '\r':
- *e = append(*e, 'r')
- case '\t':
- *e = append(*e, 't')
- default:
- // This encodes bytes < 0x20 except for \t, \n and \r.
- // If escapeHTML is set, it also escapes <, >, and &
- // because they can lead to security holes when
- // user-controlled strings are rendered into JSON
- // and served to some browsers.
- *e = append(*e, `u00`...)
- *e = append(*e, rt.Hex[b>>4])
- *e = append(*e, rt.Hex[b&0xF])
- }
- i++
- start = i
- continue
- }
- c, size := utf8.DecodeRuneInString(s[i:])
- // if c == utf8.RuneError && size == 1 {
- // if start < i {
- // e.Write(s[start:i])
- // }
- // e.WriteString(`\ufffd`)
- // i += size
- // start = i
- // continue
- // }
- if c == '\u2028' || c == '\u2029' {
- if start < i {
- *e = append(*e, s[start:i]...)
- }
- *e = append(*e, `\u202`...)
- *e = append(*e, rt.Hex[c&0xF])
- i += size
- start = i
- continue
- }
- i += size
- }
- if start < len(s) {
- *e = append(*e, s[start:]...)
- }
- *e = append(*e, '"')
-}
-
-var bytesPool = sync.Pool{}
-
-func (self *Node) MarshalJSON() ([]byte, error) {
- if self == nil {
- return bytesNull, nil
- }
-
- buf := newBuffer()
- err := self.encode(buf)
- if err != nil {
- freeBuffer(buf)
- return nil, err
- }
- var ret []byte
- if !rt.CanSizeResue(cap(*buf)) {
- ret = *buf
- } else {
- ret = make([]byte, len(*buf))
- copy(ret, *buf)
- freeBuffer(buf)
- }
- return ret, err
-}
-
-func newBuffer() *[]byte {
- if ret := bytesPool.Get(); ret != nil {
- return ret.(*[]byte)
- } else {
- buf := make([]byte, 0, option.DefaultAstBufferSize)
- return &buf
- }
-}
-
-func freeBuffer(buf *[]byte) {
- if !rt.CanSizeResue(cap(*buf)) {
- return
- }
- *buf = (*buf)[:0]
- bytesPool.Put(buf)
-}
-
-func (self *Node) encode(buf *[]byte) error {
- if self.isRaw() {
- return self.encodeRaw(buf)
- }
- switch int(self.itype()) {
- case V_NONE : return ErrNotExist
- case V_ERROR : return self.Check()
- case V_NULL : return self.encodeNull(buf)
- case V_TRUE : return self.encodeTrue(buf)
- case V_FALSE : return self.encodeFalse(buf)
- case V_ARRAY : return self.encodeArray(buf)
- case V_OBJECT: return self.encodeObject(buf)
- case V_STRING: return self.encodeString(buf)
- case V_NUMBER: return self.encodeNumber(buf)
- case V_ANY : return self.encodeInterface(buf)
- default : return ErrUnsupportType
- }
-}
-
-func (self *Node) encodeRaw(buf *[]byte) error {
- lock := self.rlock()
- if !self.isRaw() {
- self.runlock()
- return self.encode(buf)
- }
- raw := self.toString()
- if lock {
- self.runlock()
- }
- *buf = append(*buf, raw...)
- return nil
-}
-
-func (self *Node) encodeNull(buf *[]byte) error {
- *buf = append(*buf, strNull...)
- return nil
-}
-
-func (self *Node) encodeTrue(buf *[]byte) error {
- *buf = append(*buf, bytesTrue...)
- return nil
-}
-
-func (self *Node) encodeFalse(buf *[]byte) error {
- *buf = append(*buf, bytesFalse...)
- return nil
-}
-
-func (self *Node) encodeNumber(buf *[]byte) error {
- str := self.toString()
- *buf = append(*buf, str...)
- return nil
-}
-
-func (self *Node) encodeString(buf *[]byte) error {
- if self.l == 0 {
- *buf = append(*buf, '"', '"')
- return nil
- }
-
- quote(buf, self.toString())
- return nil
-}
-
-func (self *Node) encodeArray(buf *[]byte) error {
- if self.isLazy() {
- if err := self.skipAllIndex(); err != nil {
- return err
- }
- }
-
- nb := self.len()
- if nb == 0 {
- *buf = append(*buf, bytesArray...)
- return nil
- }
-
- *buf = append(*buf, '[')
-
- var started bool
- for i := 0; i < nb; i++ {
- n := self.nodeAt(i)
- if !n.Exists() {
- continue
- }
- if started {
- *buf = append(*buf, ',')
- }
- started = true
- if err := n.encode(buf); err != nil {
- return err
- }
- }
-
- *buf = append(*buf, ']')
- return nil
-}
-
-func (self *Pair) encode(buf *[]byte) error {
- if len(*buf) == 0 {
- *buf = append(*buf, '"', '"', ':')
- return self.Value.encode(buf)
- }
-
- quote(buf, self.Key)
- *buf = append(*buf, ':')
-
- return self.Value.encode(buf)
-}
-
-func (self *Node) encodeObject(buf *[]byte) error {
- if self.isLazy() {
- if err := self.skipAllKey(); err != nil {
- return err
- }
- }
-
- nb := self.len()
- if nb == 0 {
- *buf = append(*buf, bytesObject...)
- return nil
- }
-
- *buf = append(*buf, '{')
-
- var started bool
- for i := 0; i < nb; i++ {
- n := self.pairAt(i)
- if n == nil || !n.Value.Exists() {
- continue
- }
- if started {
- *buf = append(*buf, ',')
- }
- started = true
- if err := n.encode(buf); err != nil {
- return err
- }
- }
-
- *buf = append(*buf, '}')
- return nil
-}
diff --git a/vendor/github.com/bytedance/sonic/ast/error.go b/vendor/github.com/bytedance/sonic/ast/error.go
deleted file mode 100644
index 3716e7a91..000000000
--- a/vendor/github.com/bytedance/sonic/ast/error.go
+++ /dev/null
@@ -1,134 +0,0 @@
-package ast
-
-import (
- `fmt`
- `strings`
- `unsafe`
-
- `github.com/bytedance/sonic/internal/native/types`
-)
-
-
-func newError(err types.ParsingError, msg string) *Node {
- return &Node{
- t: V_ERROR,
- l: uint(err),
- p: unsafe.Pointer(&msg),
- }
-}
-
-func newErrorPair(err SyntaxError) *Pair {
- return &Pair{0, "", *newSyntaxError(err)}
-}
-
-// Error returns error message if the node is invalid
-func (self Node) Error() string {
- if self.t != V_ERROR {
- return ""
- } else {
- return *(*string)(self.p)
- }
-}
-
-func newSyntaxError(err SyntaxError) *Node {
- msg := err.Description()
- return &Node{
- t: V_ERROR,
- l: uint(err.Code),
- p: unsafe.Pointer(&msg),
- }
-}
-
-func (self *Parser) syntaxError(err types.ParsingError) SyntaxError {
- return SyntaxError{
- Pos : self.p,
- Src : self.s,
- Code: err,
- }
-}
-
-func unwrapError(err error) *Node {
- if se, ok := err.(*Node); ok {
- return se
- }else if sse, ok := err.(Node); ok {
- return &sse
- } else {
- msg := err.Error()
- return &Node{
- t: V_ERROR,
- p: unsafe.Pointer(&msg),
- }
- }
-}
-
-type SyntaxError struct {
- Pos int
- Src string
- Code types.ParsingError
- Msg string
-}
-
-func (self SyntaxError) Error() string {
- return fmt.Sprintf("%q", self.Description())
-}
-
-func (self SyntaxError) Description() string {
- return "Syntax error " + self.description()
-}
-
-func (self SyntaxError) description() string {
- i := 16
- p := self.Pos - i
- q := self.Pos + i
-
- /* check for empty source */
- if self.Src == "" {
- return fmt.Sprintf("no sources available, the input json is empty: %#v", self)
- }
-
- /* prevent slicing before the beginning */
- if p < 0 {
- p, q, i = 0, q - p, i + p
- }
-
- /* prevent slicing beyond the end */
- if n := len(self.Src); q > n {
- n = q - n
- q = len(self.Src)
-
- /* move the left bound if possible */
- if p > n {
- i += n
- p -= n
- }
- }
-
- /* left and right length */
- x := clamp_zero(i)
- y := clamp_zero(q - p - i - 1)
-
- /* compose the error description */
- return fmt.Sprintf(
- "at index %d: %s\n\n\t%s\n\t%s^%s\n",
- self.Pos,
- self.Message(),
- self.Src[p:q],
- strings.Repeat(".", x),
- strings.Repeat(".", y),
- )
-}
-
-func (self SyntaxError) Message() string {
- if self.Msg == "" {
- return self.Code.Message()
- }
- return self.Msg
-}
-
-func clamp_zero(v int) int {
- if v < 0 {
- return 0
- } else {
- return v
- }
-}
diff --git a/vendor/github.com/bytedance/sonic/ast/iterator.go b/vendor/github.com/bytedance/sonic/ast/iterator.go
deleted file mode 100644
index 1052dd0a0..000000000
--- a/vendor/github.com/bytedance/sonic/ast/iterator.go
+++ /dev/null
@@ -1,216 +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 ast
-
-import (
- "fmt"
-
- "github.com/bytedance/sonic/internal/caching"
- "github.com/bytedance/sonic/internal/native/types"
-)
-
-type Pair struct {
- hash uint64
- Key string
- Value Node
-}
-
-func NewPair(key string, val Node) Pair {
- return Pair{
- hash: caching.StrHash(key),
- Key: key,
- Value: val,
- }
-}
-
-// Values returns iterator for array's children traversal
-func (self *Node) Values() (ListIterator, error) {
- if err := self.should(types.V_ARRAY); err != nil {
- return ListIterator{}, err
- }
- return self.values(), nil
-}
-
-func (self *Node) values() ListIterator {
- return ListIterator{Iterator{p: self}}
-}
-
-// Properties returns iterator for object's children traversal
-func (self *Node) Properties() (ObjectIterator, error) {
- if err := self.should(types.V_OBJECT); err != nil {
- return ObjectIterator{}, err
- }
- return self.properties(), nil
-}
-
-func (self *Node) properties() ObjectIterator {
- return ObjectIterator{Iterator{p: self}}
-}
-
-type Iterator struct {
- i int
- p *Node
-}
-
-func (self *Iterator) Pos() int {
- return self.i
-}
-
-func (self *Iterator) Len() int {
- return self.p.len()
-}
-
-// HasNext reports if it is the end of iteration or has error.
-func (self *Iterator) HasNext() bool {
- if !self.p.isLazy() {
- return self.p.Valid() && self.i < self.p.len()
- } else if self.p.t == _V_ARRAY_LAZY {
- return self.p.skipNextNode().Valid()
- } else if self.p.t == _V_OBJECT_LAZY {
- pair := self.p.skipNextPair()
- if pair == nil {
- return false
- }
- return pair.Value.Valid()
- }
- return false
-}
-
-// ListIterator is specialized iterator for V_ARRAY
-type ListIterator struct {
- Iterator
-}
-
-// ObjectIterator is specialized iterator for V_ARRAY
-type ObjectIterator struct {
- Iterator
-}
-
-func (self *ListIterator) next() *Node {
-next_start:
- if !self.HasNext() {
- return nil
- } else {
- n := self.p.nodeAt(self.i)
- self.i++
- if !n.Exists() {
- goto next_start
- }
- return n
- }
-}
-
-// Next scans through children of underlying V_ARRAY,
-// copies each child to v, and returns .HasNext().
-func (self *ListIterator) Next(v *Node) bool {
- n := self.next()
- if n == nil {
- return false
- }
- *v = *n
- return true
-}
-
-func (self *ObjectIterator) next() *Pair {
-next_start:
- if !self.HasNext() {
- return nil
- } else {
- n := self.p.pairAt(self.i)
- self.i++
- if n == nil || !n.Value.Exists() {
- goto next_start
- }
- return n
- }
-}
-
-// Next scans through children of underlying V_OBJECT,
-// copies each child to v, and returns .HasNext().
-func (self *ObjectIterator) Next(p *Pair) bool {
- n := self.next()
- if n == nil {
- return false
- }
- *p = *n
- return true
-}
-
-// Sequence represents scanning path of single-layer nodes.
-// Index indicates the value's order in both V_ARRAY and V_OBJECT json.
-// Key is the value's key (for V_OBJECT json only, otherwise it will be nil).
-type Sequence struct {
- Index int
- Key *string
- // Level int
-}
-
-// String is string representation of one Sequence
-func (s Sequence) String() string {
- k := ""
- if s.Key != nil {
- k = *s.Key
- }
- return fmt.Sprintf("Sequence(%d, %q)", s.Index, k)
-}
-
-type Scanner func(path Sequence, node *Node) bool
-
-// ForEach scans one V_OBJECT node's children from JSON head to tail,
-// and pass the Sequence and Node of corresponding JSON value.
-//
-// Especially, if the node is not V_ARRAY or V_OBJECT,
-// the node itself will be returned and Sequence.Index == -1.
-//
-// NOTICE: A unsetted node WON'T trigger sc, but its index still counts into Path.Index
-func (self *Node) ForEach(sc Scanner) error {
- if err := self.checkRaw(); err != nil {
- return err
- }
- switch self.itype() {
- case types.V_ARRAY:
- iter, err := self.Values()
- if err != nil {
- return err
- }
- v := iter.next()
- for v != nil {
- if !sc(Sequence{iter.i-1, nil}, v) {
- return nil
- }
- v = iter.next()
- }
- case types.V_OBJECT:
- iter, err := self.Properties()
- if err != nil {
- return err
- }
- v := iter.next()
- for v != nil {
- if !sc(Sequence{iter.i-1, &v.Key}, &v.Value) {
- return nil
- }
- v = iter.next()
- }
- default:
- if self.Check() != nil {
- return self
- }
- sc(Sequence{-1, nil}, self)
- }
- return nil
-}
diff --git a/vendor/github.com/bytedance/sonic/ast/node.go b/vendor/github.com/bytedance/sonic/ast/node.go
deleted file mode 100644
index 2bb504850..000000000
--- a/vendor/github.com/bytedance/sonic/ast/node.go
+++ /dev/null
@@ -1,1843 +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 ast
-
-import (
- "encoding/json"
- "fmt"
- "strconv"
- "sync"
- "sync/atomic"
- "unsafe"
-
- "github.com/bytedance/sonic/internal/native/types"
- "github.com/bytedance/sonic/internal/rt"
-)
-
-const (
- _V_NONE types.ValueType = 0
- _V_NODE_BASE types.ValueType = 1 << 5
- _V_LAZY types.ValueType = 1 << 7
- _V_RAW types.ValueType = 1 << 8
- _V_NUMBER = _V_NODE_BASE + 1
- _V_ANY = _V_NODE_BASE + 2
- _V_ARRAY_LAZY = _V_LAZY | types.V_ARRAY
- _V_OBJECT_LAZY = _V_LAZY | types.V_OBJECT
- _MASK_LAZY = _V_LAZY - 1
- _MASK_RAW = _V_RAW - 1
-)
-
-const (
- V_NONE = 0
- V_ERROR = 1
- V_NULL = int(types.V_NULL)
- V_TRUE = int(types.V_TRUE)
- V_FALSE = int(types.V_FALSE)
- V_ARRAY = int(types.V_ARRAY)
- V_OBJECT = int(types.V_OBJECT)
- V_STRING = int(types.V_STRING)
- V_NUMBER = int(_V_NUMBER)
- V_ANY = int(_V_ANY)
-)
-
-type Node struct {
- t types.ValueType
- l uint
- p unsafe.Pointer
- m *sync.RWMutex
-}
-
-// UnmarshalJSON is just an adapter to json.Unmarshaler.
-// If you want better performance, use Searcher.GetByPath() directly
-func (self *Node) UnmarshalJSON(data []byte) (err error) {
- *self = NewRaw(string(data))
- return self.Check()
-}
-
-/** Node Type Accessor **/
-
-// Type returns json type represented by the node
-// It will be one of belows:
-// V_NONE = 0 (empty node, key not exists)
-// V_ERROR = 1 (error node)
-// V_NULL = 2 (json value `null`, key exists)
-// V_TRUE = 3 (json value `true`)
-// V_FALSE = 4 (json value `false`)
-// V_ARRAY = 5 (json value array)
-// V_OBJECT = 6 (json value object)
-// V_STRING = 7 (json value string)
-// V_NUMBER = 33 (json value number )
-// V_ANY = 34 (golang interface{})
-//
-// Deprecated: not concurrent safe. Use TypeSafe instead
-func (self Node) Type() int {
- return int(self.t & _MASK_LAZY & _MASK_RAW)
-}
-
-// Type concurrently-safe returns json type represented by the node
-// It will be one of belows:
-// V_NONE = 0 (empty node, key not exists)
-// V_ERROR = 1 (error node)
-// V_NULL = 2 (json value `null`, key exists)
-// V_TRUE = 3 (json value `true`)
-// V_FALSE = 4 (json value `false`)
-// V_ARRAY = 5 (json value array)
-// V_OBJECT = 6 (json value object)
-// V_STRING = 7 (json value string)
-// V_NUMBER = 33 (json value number )
-// V_ANY = 34 (golang interface{})
-func (self *Node) TypeSafe() int {
- return int(self.loadt() & _MASK_LAZY & _MASK_RAW)
-}
-
-func (self *Node) itype() types.ValueType {
- return self.t & _MASK_LAZY & _MASK_RAW
-}
-
-// Exists returns false only if the self is nil or empty node V_NONE
-func (self *Node) Exists() bool {
- if self == nil {
- return false
- }
- t := self.loadt()
- return t != V_ERROR && t != _V_NONE
-}
-
-// Valid reports if self is NOT V_ERROR or nil
-func (self *Node) Valid() bool {
- if self == nil {
- return false
- }
- return self.loadt() != V_ERROR
-}
-
-// Check checks if the node itself is valid, and return:
-// - ErrNotExist If the node is nil
-// - Its underlying error If the node is V_ERROR
-func (self *Node) Check() error {
- if self == nil {
- return ErrNotExist
- } else if self.loadt() != V_ERROR {
- return nil
- } else {
- return self
- }
-}
-
-// isRaw returns true if node's underlying value is raw json
-//
-// Deprecated: not concurrent safe
-func (self Node) IsRaw() bool {
- return self.t & _V_RAW != 0
-}
-
-// IsRaw returns true if node's underlying value is raw json
-func (self *Node) isRaw() bool {
- return self.loadt() & _V_RAW != 0
-}
-
-func (self *Node) isLazy() bool {
- return self != nil && self.t & _V_LAZY != 0
-}
-
-func (self *Node) isAny() bool {
- return self != nil && self.loadt() == _V_ANY
-}
-
-/** Simple Value Methods **/
-
-// Raw returns json representation of the node,
-func (self *Node) Raw() (string, error) {
- if self == nil {
- return "", ErrNotExist
- }
- lock := self.rlock()
- if !self.isRaw() {
- if lock {
- self.runlock()
- }
- buf, err := self.MarshalJSON()
- return rt.Mem2Str(buf), err
- }
- ret := self.toString()
- if lock {
- self.runlock()
- }
- return ret, nil
-}
-
-func (self *Node) checkRaw() error {
- if err := self.Check(); err != nil {
- return err
- }
- if self.isRaw() {
- self.parseRaw(false)
- }
- return self.Check()
-}
-
-// Bool returns bool value represented by this node,
-// including types.V_TRUE|V_FALSE|V_NUMBER|V_STRING|V_ANY|V_NULL,
-// V_NONE will return error
-func (self *Node) Bool() (bool, error) {
- if err := self.checkRaw(); err != nil {
- return false, err
- }
- switch self.t {
- case types.V_TRUE : return true , nil
- case types.V_FALSE : return false, nil
- case types.V_NULL : return false, nil
- case _V_NUMBER :
- if i, err := self.toInt64(); err == nil {
- return i != 0, nil
- } else if f, err := self.toFloat64(); err == nil {
- return f != 0, nil
- } else {
- return false, err
- }
- case types.V_STRING: return strconv.ParseBool(self.toString())
- case _V_ANY :
- any := self.packAny()
- switch v := any.(type) {
- case bool : return v, nil
- case int : return v != 0, nil
- case int8 : return v != 0, nil
- case int16 : return v != 0, nil
- case int32 : return v != 0, nil
- case int64 : return v != 0, nil
- case uint : return v != 0, nil
- case uint8 : return v != 0, nil
- case uint16 : return v != 0, nil
- case uint32 : return v != 0, nil
- case uint64 : return v != 0, nil
- case float32: return v != 0, nil
- case float64: return v != 0, nil
- case string : return strconv.ParseBool(v)
- case json.Number:
- if i, err := v.Int64(); err == nil {
- return i != 0, nil
- } else if f, err := v.Float64(); err == nil {
- return f != 0, nil
- } else {
- return false, err
- }
- default: return false, ErrUnsupportType
- }
- default : return false, ErrUnsupportType
- }
-}
-
-// Int64 casts the node to int64 value,
-// including V_NUMBER|V_TRUE|V_FALSE|V_ANY|V_STRING
-// V_NONE it will return error
-func (self *Node) Int64() (int64, error) {
- if err := self.checkRaw(); err != nil {
- return 0, err
- }
- switch self.t {
- case _V_NUMBER, types.V_STRING :
- if i, err := self.toInt64(); err == nil {
- return i, nil
- } else if f, err := self.toFloat64(); err == nil {
- return int64(f), nil
- } else {
- return 0, err
- }
- case types.V_TRUE : return 1, nil
- case types.V_FALSE : return 0, nil
- case types.V_NULL : return 0, nil
- case _V_ANY :
- any := self.packAny()
- switch v := any.(type) {
- case bool : if v { return 1, nil } else { return 0, nil }
- case int : return int64(v), nil
- case int8 : return int64(v), nil
- case int16 : return int64(v), nil
- case int32 : return int64(v), nil
- case int64 : return int64(v), nil
- case uint : return int64(v), nil
- case uint8 : return int64(v), nil
- case uint16 : return int64(v), nil
- case uint32 : return int64(v), nil
- case uint64 : return int64(v), nil
- case float32: return int64(v), nil
- case float64: return int64(v), nil
- case string :
- if i, err := strconv.ParseInt(v, 10, 64); err == nil {
- return i, nil
- } else if f, err := strconv.ParseFloat(v, 64); err == nil {
- return int64(f), nil
- } else {
- return 0, err
- }
- case json.Number:
- if i, err := v.Int64(); err == nil {
- return i, nil
- } else if f, err := v.Float64(); err == nil {
- return int64(f), nil
- } else {
- return 0, err
- }
- default: return 0, ErrUnsupportType
- }
- default : return 0, ErrUnsupportType
- }
-}
-
-// StrictInt64 exports underlying int64 value, including V_NUMBER, V_ANY
-func (self *Node) StrictInt64() (int64, error) {
- if err := self.checkRaw(); err != nil {
- return 0, err
- }
- switch self.t {
- case _V_NUMBER : return self.toInt64()
- case _V_ANY :
- any := self.packAny()
- switch v := any.(type) {
- case int : return int64(v), nil
- case int8 : return int64(v), nil
- case int16 : return int64(v), nil
- case int32 : return int64(v), nil
- case int64 : return int64(v), nil
- case uint : return int64(v), nil
- case uint8 : return int64(v), nil
- case uint16: return int64(v), nil
- case uint32: return int64(v), nil
- case uint64: return int64(v), nil
- case json.Number:
- if i, err := v.Int64(); err == nil {
- return i, nil
- } else {
- return 0, err
- }
- default: return 0, ErrUnsupportType
- }
- default : return 0, ErrUnsupportType
- }
-}
-
-func castNumber(v bool) json.Number {
- if v {
- return json.Number("1")
- } else {
- return json.Number("0")
- }
-}
-
-// Number casts node to float64,
-// including V_NUMBER|V_TRUE|V_FALSE|V_ANY|V_STRING|V_NULL,
-// V_NONE it will return error
-func (self *Node) Number() (json.Number, error) {
- if err := self.checkRaw(); err != nil {
- return json.Number(""), err
- }
- switch self.t {
- case _V_NUMBER : return self.toNumber(), nil
- case types.V_STRING :
- if _, err := self.toInt64(); err == nil {
- return self.toNumber(), nil
- } else if _, err := self.toFloat64(); err == nil {
- return self.toNumber(), nil
- } else {
- return json.Number(""), err
- }
- case types.V_TRUE : return json.Number("1"), nil
- case types.V_FALSE : return json.Number("0"), nil
- case types.V_NULL : return json.Number("0"), nil
- case _V_ANY :
- any := self.packAny()
- switch v := any.(type) {
- case bool : return castNumber(v), nil
- case int : return castNumber(v != 0), nil
- case int8 : return castNumber(v != 0), nil
- case int16 : return castNumber(v != 0), nil
- case int32 : return castNumber(v != 0), nil
- case int64 : return castNumber(v != 0), nil
- case uint : return castNumber(v != 0), nil
- case uint8 : return castNumber(v != 0), nil
- case uint16 : return castNumber(v != 0), nil
- case uint32 : return castNumber(v != 0), nil
- case uint64 : return castNumber(v != 0), nil
- case float32: return castNumber(v != 0), nil
- case float64: return castNumber(v != 0), nil
- case string :
- if _, err := strconv.ParseFloat(v, 64); err == nil {
- return json.Number(v), nil
- } else {
- return json.Number(""), err
- }
- case json.Number: return v, nil
- default: return json.Number(""), ErrUnsupportType
- }
- default : return json.Number(""), ErrUnsupportType
- }
-}
-
-// Number exports underlying float64 value, including V_NUMBER, V_ANY of json.Number
-func (self *Node) StrictNumber() (json.Number, error) {
- if err := self.checkRaw(); err != nil {
- return json.Number(""), err
- }
- switch self.t {
- case _V_NUMBER : return self.toNumber() , nil
- case _V_ANY :
- if v, ok := self.packAny().(json.Number); ok {
- return v, nil
- } else {
- return json.Number(""), ErrUnsupportType
- }
- default : return json.Number(""), ErrUnsupportType
- }
-}
-
-// String cast node to string,
-// including V_NUMBER|V_TRUE|V_FALSE|V_ANY|V_STRING|V_NULL,
-// V_NONE it will return error
-func (self *Node) String() (string, error) {
- if err := self.checkRaw(); err != nil {
- return "", err
- }
- switch self.t {
- case types.V_NULL : return "" , nil
- case types.V_TRUE : return "true" , nil
- case types.V_FALSE : return "false", nil
- case types.V_STRING, _V_NUMBER : return self.toString(), nil
- case _V_ANY :
- any := self.packAny()
- switch v := any.(type) {
- case bool : return strconv.FormatBool(v), nil
- case int : return strconv.Itoa(v), nil
- case int8 : return strconv.Itoa(int(v)), nil
- case int16 : return strconv.Itoa(int(v)), nil
- case int32 : return strconv.Itoa(int(v)), nil
- case int64 : return strconv.Itoa(int(v)), nil
- case uint : return strconv.Itoa(int(v)), nil
- case uint8 : return strconv.Itoa(int(v)), nil
- case uint16 : return strconv.Itoa(int(v)), nil
- case uint32 : return strconv.Itoa(int(v)), nil
- case uint64 : return strconv.Itoa(int(v)), nil
- case float32: return strconv.FormatFloat(float64(v), 'g', -1, 64), nil
- case float64: return strconv.FormatFloat(float64(v), 'g', -1, 64), nil
- case string : return v, nil
- case json.Number: return v.String(), nil
- default: return "", ErrUnsupportType
- }
- default : return "" , ErrUnsupportType
- }
-}
-
-// StrictString returns string value (unescaped), including V_STRING, V_ANY of string.
-// In other cases, it will return empty string.
-func (self *Node) StrictString() (string, error) {
- if err := self.checkRaw(); err != nil {
- return "", err
- }
- switch self.t {
- case types.V_STRING : return self.toString(), nil
- case _V_ANY :
- if v, ok := self.packAny().(string); ok {
- return v, nil
- } else {
- return "", ErrUnsupportType
- }
- default : return "", ErrUnsupportType
- }
-}
-
-// Float64 cast node to float64,
-// including V_NUMBER|V_TRUE|V_FALSE|V_ANY|V_STRING|V_NULL,
-// V_NONE it will return error
-func (self *Node) Float64() (float64, error) {
- if err := self.checkRaw(); err != nil {
- return 0.0, err
- }
- switch self.t {
- case _V_NUMBER, types.V_STRING : return self.toFloat64()
- case types.V_TRUE : return 1.0, nil
- case types.V_FALSE : return 0.0, nil
- case types.V_NULL : return 0.0, nil
- case _V_ANY :
- any := self.packAny()
- switch v := any.(type) {
- case bool :
- if v {
- return 1.0, nil
- } else {
- return 0.0, nil
- }
- case int : return float64(v), nil
- case int8 : return float64(v), nil
- case int16 : return float64(v), nil
- case int32 : return float64(v), nil
- case int64 : return float64(v), nil
- case uint : return float64(v), nil
- case uint8 : return float64(v), nil
- case uint16 : return float64(v), nil
- case uint32 : return float64(v), nil
- case uint64 : return float64(v), nil
- case float32: return float64(v), nil
- case float64: return float64(v), nil
- case string :
- if f, err := strconv.ParseFloat(v, 64); err == nil {
- return float64(f), nil
- } else {
- return 0, err
- }
- case json.Number:
- if f, err := v.Float64(); err == nil {
- return float64(f), nil
- } else {
- return 0, err
- }
- default : return 0, ErrUnsupportType
- }
- default : return 0.0, ErrUnsupportType
- }
-}
-
-// Float64 exports underlying float64 value, including V_NUMBER, V_ANY
-func (self *Node) StrictFloat64() (float64, error) {
- if err := self.checkRaw(); err != nil {
- return 0.0, err
- }
- switch self.t {
- case _V_NUMBER : return self.toFloat64()
- case _V_ANY :
- any := self.packAny()
- switch v := any.(type) {
- case float32 : return float64(v), nil
- case float64 : return float64(v), nil
- default : return 0, ErrUnsupportType
- }
- default : return 0.0, ErrUnsupportType
- }
-}
-
-/** Sequential Value Methods **/
-
-// Len returns children count of a array|object|string node
-// WARN: For partially loaded node, it also works but only counts the parsed children
-func (self *Node) Len() (int, error) {
- if err := self.checkRaw(); err != nil {
- return 0, err
- }
- if self.t == types.V_ARRAY || self.t == types.V_OBJECT || self.t == _V_ARRAY_LAZY || self.t == _V_OBJECT_LAZY || self.t == types.V_STRING {
- return int(self.l), nil
- } else if self.t == _V_NONE || self.t == types.V_NULL {
- return 0, nil
- } else {
- return 0, ErrUnsupportType
- }
-}
-
-func (self *Node) len() int {
- return int(self.l)
-}
-
-// Cap returns malloc capacity of a array|object node for children
-func (self *Node) Cap() (int, error) {
- if err := self.checkRaw(); err != nil {
- return 0, err
- }
- switch self.t {
- case types.V_ARRAY: return (*linkedNodes)(self.p).Cap(), nil
- case types.V_OBJECT: return (*linkedPairs)(self.p).Cap(), nil
- case _V_ARRAY_LAZY: return (*parseArrayStack)(self.p).v.Cap(), nil
- case _V_OBJECT_LAZY: return (*parseObjectStack)(self.p).v.Cap(), nil
- case _V_NONE, types.V_NULL: return 0, nil
- default: return 0, ErrUnsupportType
- }
-}
-
-// Set sets the node of given key under self, and reports if the key has existed.
-//
-// If self is V_NONE or V_NULL, it becomes V_OBJECT and sets the node at the key.
-func (self *Node) Set(key string, node Node) (bool, error) {
- if err := self.checkRaw(); err != nil {
- return false, err
- }
- if err := node.Check(); err != nil {
- return false, err
- }
-
- if self.t == _V_NONE || self.t == types.V_NULL {
- *self = NewObject([]Pair{NewPair(key, node)})
- return false, nil
- } else if self.itype() != types.V_OBJECT {
- return false, ErrUnsupportType
- }
-
- p := self.Get(key)
-
- if !p.Exists() {
- // self must be fully-loaded here
- if self.len() == 0 {
- *self = newObject(new(linkedPairs))
- }
- s := (*linkedPairs)(self.p)
- s.Push(NewPair(key, node))
- self.l++
- return false, nil
-
- } else if err := p.Check(); err != nil {
- return false, err
- }
-
- *p = node
- return true, nil
-}
-
-// SetAny wraps val with V_ANY node, and Set() the node.
-func (self *Node) SetAny(key string, val interface{}) (bool, error) {
- return self.Set(key, NewAny(val))
-}
-
-// Unset REMOVE (soft) the node of given key under object parent, and reports if the key has existed.
-func (self *Node) Unset(key string) (bool, error) {
- if err := self.should(types.V_OBJECT); err != nil {
- return false, err
- }
- // NOTICE: must get accurate length before deduct
- if err := self.skipAllKey(); err != nil {
- return false, err
- }
- p, i := self.skipKey(key)
- if !p.Exists() {
- return false, nil
- } else if err := p.Check(); err != nil {
- return false, err
- }
- self.removePairAt(i)
- return true, nil
-}
-
-// SetByIndex sets the node of given index, and reports if the key has existed.
-//
-// The index must be within self's children.
-func (self *Node) SetByIndex(index int, node Node) (bool, error) {
- if err := self.checkRaw(); err != nil {
- return false, err
- }
- if err := node.Check(); err != nil {
- return false, err
- }
-
- if index == 0 && (self.t == _V_NONE || self.t == types.V_NULL) {
- *self = NewArray([]Node{node})
- return false, nil
- }
-
- p := self.Index(index)
- if !p.Exists() {
- return false, ErrNotExist
- } else if err := p.Check(); err != nil {
- return false, err
- }
-
- *p = node
- return true, nil
-}
-
-// SetAny wraps val with V_ANY node, and SetByIndex() the node.
-func (self *Node) SetAnyByIndex(index int, val interface{}) (bool, error) {
- return self.SetByIndex(index, NewAny(val))
-}
-
-// UnsetByIndex REMOVE (softly) the node of given index.
-//
-// WARN: this will change address of elements, which is a dangerous action.
-// Use Unset() for object or Pop() for array instead.
-func (self *Node) UnsetByIndex(index int) (bool, error) {
- if err := self.checkRaw(); err != nil {
- return false, err
- }
-
- var p *Node
- it := self.itype()
-
- if it == types.V_ARRAY {
- if err := self.skipAllIndex(); err != nil {
- return false, err
- }
- p = self.nodeAt(index)
- } else if it == types.V_OBJECT {
- if err := self.skipAllKey(); err != nil {
- return false, err
- }
- pr := self.pairAt(index)
- if pr == nil {
- return false, ErrNotExist
- }
- p = &pr.Value
- } else {
- return false, ErrUnsupportType
- }
-
- if !p.Exists() {
- return false, ErrNotExist
- }
-
- // last elem
- if index == self.len() - 1 {
- return true, self.Pop()
- }
-
- // not last elem, self.len() change but linked-chunk not change
- if it == types.V_ARRAY {
- self.removeNode(index)
- }else if it == types.V_OBJECT {
- self.removePair(index)
- }
- return true, nil
-}
-
-// Add appends the given node under self.
-//
-// If self is V_NONE or V_NULL, it becomes V_ARRAY and sets the node at index 0.
-func (self *Node) Add(node Node) error {
- if err := self.checkRaw(); err != nil {
- return err
- }
-
- if self != nil && (self.t == _V_NONE || self.t == types.V_NULL) {
- *self = NewArray([]Node{node})
- return nil
- }
- if err := self.should(types.V_ARRAY); err != nil {
- return err
- }
-
- s, err := self.unsafeArray()
- if err != nil {
- return err
- }
-
- // Notice: array won't have unset node in tail
- s.Push(node)
- self.l++
- return nil
-}
-
-// Pop remove the last child of the V_Array or V_Object node.
-func (self *Node) Pop() error {
- if err := self.checkRaw(); err != nil {
- return err
- }
-
- if it := self.itype(); it == types.V_ARRAY {
- s, err := self.unsafeArray()
- if err != nil {
- return err
- }
- // remove tail unset nodes
- for i := s.Len()-1; i >= 0; i-- {
- if s.At(i).Exists() {
- s.Pop()
- self.l--
- break
- }
- s.Pop()
- }
-
- } else if it == types.V_OBJECT {
- s, err := self.unsafeMap()
- if err != nil {
- return err
- }
- // remove tail unset nodes
- for i := s.Len()-1; i >= 0; i-- {
- if p := s.At(i); p != nil && p.Value.Exists() {
- s.Pop()
- self.l--
- break
- }
- s.Pop()
- }
-
- } else {
- return ErrUnsupportType
- }
-
- return nil
-}
-
-// Move moves the child at src index to dst index,
-// meanwhile slides sliblings from src+1 to dst.
-//
-// WARN: this will change address of elements, which is a dangerous action.
-func (self *Node) Move(dst, src int) error {
- if err := self.should(types.V_ARRAY); err != nil {
- return err
- }
-
- s, err := self.unsafeArray()
- if err != nil {
- return err
- }
-
- // check if any unset node exists
- if l := s.Len(); self.len() != l {
- di, si := dst, src
- // find real pos of src and dst
- for i := 0; i < l; i++ {
- if s.At(i).Exists() {
- di--
- si--
- }
- if di == -1 {
- dst = i
- di--
- }
- if si == -1 {
- src = i
- si--
- }
- if di == -2 && si == -2 {
- break
- }
- }
- }
-
- s.MoveOne(src, dst)
- return nil
-}
-
-// SetAny wraps val with V_ANY node, and Add() the node.
-func (self *Node) AddAny(val interface{}) error {
- return self.Add(NewAny(val))
-}
-
-// GetByPath load given path on demands,
-// which only ensure nodes before this path got parsed.
-//
-// Note, the api expects the json is well-formed at least,
-// otherwise it may return unexpected result.
-func (self *Node) GetByPath(path ...interface{}) *Node {
- if !self.Valid() {
- return self
- }
- var s = self
- for _, p := range path {
- switch p := p.(type) {
- case int:
- s = s.Index(p)
- if !s.Valid() {
- return s
- }
- case string:
- s = s.Get(p)
- if !s.Valid() {
- return s
- }
- default:
- panic("path must be either int or string")
- }
- }
- return s
-}
-
-// Get loads given key of an object node on demands
-func (self *Node) Get(key string) *Node {
- if err := self.should(types.V_OBJECT); err != nil {
- return unwrapError(err)
- }
- n, _ := self.skipKey(key)
- return n
-}
-
-// Index indexies node at given idx,
-// node type CAN be either V_OBJECT or V_ARRAY
-func (self *Node) Index(idx int) *Node {
- if err := self.checkRaw(); err != nil {
- return unwrapError(err)
- }
-
- it := self.itype()
- if it == types.V_ARRAY {
- return self.skipIndex(idx)
-
- }else if it == types.V_OBJECT {
- pr := self.skipIndexPair(idx)
- if pr == nil {
- return newError(_ERR_NOT_FOUND, "value not exists")
- }
- return &pr.Value
-
- } else {
- return newError(_ERR_UNSUPPORT_TYPE, fmt.Sprintf("unsupported type: %v", self.itype()))
- }
-}
-
-// IndexPair indexies pair at given idx,
-// node type MUST be either V_OBJECT
-func (self *Node) IndexPair(idx int) *Pair {
- if err := self.should(types.V_OBJECT); err != nil {
- return nil
- }
- return self.skipIndexPair(idx)
-}
-
-func (self *Node) indexOrGet(idx int, key string) (*Node, int) {
- if err := self.should(types.V_OBJECT); err != nil {
- return unwrapError(err), idx
- }
-
- pr := self.skipIndexPair(idx)
- if pr != nil && pr.Key == key {
- return &pr.Value, idx
- }
-
- return self.skipKey(key)
-}
-
-// IndexOrGet firstly use idx to index a value and check if its key matches
-// If not, then use the key to search value
-func (self *Node) IndexOrGet(idx int, key string) *Node {
- node, _ := self.indexOrGet(idx, key)
- return node
-}
-
-// IndexOrGetWithIdx attempts to retrieve a node by index and key, returning the node and its correct index.
-// If the key does not match at the given index, it searches by key and returns the node with its updated index.
-func (self *Node) IndexOrGetWithIdx(idx int, key string) (*Node, int) {
- return self.indexOrGet(idx, key)
-}
-
-/** Generic Value Converters **/
-
-// Map loads all keys of an object node
-func (self *Node) Map() (map[string]interface{}, error) {
- if self.isAny() {
- any := self.packAny()
- if v, ok := any.(map[string]interface{}); ok {
- return v, nil
- } else {
- return nil, ErrUnsupportType
- }
- }
- if err := self.should(types.V_OBJECT); err != nil {
- return nil, err
- }
- if err := self.loadAllKey(false); err != nil {
- return nil, err
- }
- return self.toGenericObject()
-}
-
-// MapUseNumber loads all keys of an object node, with numeric nodes casted to json.Number
-func (self *Node) MapUseNumber() (map[string]interface{}, error) {
- if self.isAny() {
- any := self.packAny()
- if v, ok := any.(map[string]interface{}); ok {
- return v, nil
- } else {
- return nil, ErrUnsupportType
- }
- }
- if err := self.should(types.V_OBJECT); err != nil {
- return nil, err
- }
- if err := self.loadAllKey(false); err != nil {
- return nil, err
- }
- return self.toGenericObjectUseNumber()
-}
-
-// MapUseNode scans both parsed and non-parsed children nodes,
-// and map them by their keys
-func (self *Node) MapUseNode() (map[string]Node, error) {
- if self.isAny() {
- any := self.packAny()
- if v, ok := any.(map[string]Node); ok {
- return v, nil
- } else {
- return nil, ErrUnsupportType
- }
- }
- if err := self.should(types.V_OBJECT); err != nil {
- return nil, err
- }
- if err := self.skipAllKey(); err != nil {
- return nil, err
- }
- return self.toGenericObjectUseNode()
-}
-
-// MapUnsafe exports the underlying pointer to its children map
-// WARN: don't use it unless you know what you are doing
-//
-// Deprecated: this API now returns copied nodes instead of directly reference,
-// func (self *Node) UnsafeMap() ([]Pair, error) {
-// if err := self.should(types.V_OBJECT, "an object"); err != nil {
-// return nil, err
-// }
-// if err := self.skipAllKey(); err != nil {
-// return nil, err
-// }
-// return self.toGenericObjectUsePair()
-// }
-
-//go:nocheckptr
-func (self *Node) unsafeMap() (*linkedPairs, error) {
- if err := self.skipAllKey(); err != nil {
- return nil, err
- }
- if self.p == nil {
- *self = newObject(new(linkedPairs))
- }
- return (*linkedPairs)(self.p), nil
-}
-
-// SortKeys sorts children of a V_OBJECT node in ascending key-order.
-// If recurse is true, it recursively sorts children's children as long as a V_OBJECT node is found.
-func (self *Node) SortKeys(recurse bool) error {
- // check raw node first
- if err := self.checkRaw(); err != nil {
- return err
- }
- if self.itype() == types.V_OBJECT {
- return self.sortKeys(recurse)
- } else if self.itype() == types.V_ARRAY {
- var err error
- err2 := self.ForEach(func(path Sequence, node *Node) bool {
- it := node.itype()
- if it == types.V_ARRAY || it == types.V_OBJECT {
- err = node.SortKeys(recurse)
- if err != nil {
- return false
- }
- }
- return true
- })
- if err != nil {
- return err
- }
- return err2
- } else {
- return nil
- }
-}
-
-func (self *Node) sortKeys(recurse bool) (err error) {
- // check raw node first
- if err := self.checkRaw(); err != nil {
- return err
- }
- ps, err := self.unsafeMap()
- if err != nil {
- return err
- }
- ps.Sort()
- if recurse {
- var sc Scanner
- sc = func(path Sequence, node *Node) bool {
- if node.itype() == types.V_OBJECT {
- if err := node.sortKeys(recurse); err != nil {
- return false
- }
- }
- if node.itype() == types.V_ARRAY {
- if err := node.ForEach(sc); err != nil {
- return false
- }
- }
- return true
- }
- if err := self.ForEach(sc); err != nil {
- return err
- }
- }
- return nil
-}
-
-// Array loads all indexes of an array node
-func (self *Node) Array() ([]interface{}, error) {
- if self.isAny() {
- any := self.packAny()
- if v, ok := any.([]interface{}); ok {
- return v, nil
- } else {
- return nil, ErrUnsupportType
- }
- }
- if err := self.should(types.V_ARRAY); err != nil {
- return nil, err
- }
- if err := self.loadAllIndex(false); err != nil {
- return nil, err
- }
- return self.toGenericArray()
-}
-
-// ArrayUseNumber loads all indexes of an array node, with numeric nodes casted to json.Number
-func (self *Node) ArrayUseNumber() ([]interface{}, error) {
- if self.isAny() {
- any := self.packAny()
- if v, ok := any.([]interface{}); ok {
- return v, nil
- } else {
- return nil, ErrUnsupportType
- }
- }
- if err := self.should(types.V_ARRAY); err != nil {
- return nil, err
- }
- if err := self.loadAllIndex(false); err != nil {
- return nil, err
- }
- return self.toGenericArrayUseNumber()
-}
-
-// ArrayUseNode copies both parsed and non-parsed children nodes,
-// and indexes them by original order
-func (self *Node) ArrayUseNode() ([]Node, error) {
- if self.isAny() {
- any := self.packAny()
- if v, ok := any.([]Node); ok {
- return v, nil
- } else {
- return nil, ErrUnsupportType
- }
- }
- if err := self.should(types.V_ARRAY); err != nil {
- return nil, err
- }
- if err := self.skipAllIndex(); err != nil {
- return nil, err
- }
- return self.toGenericArrayUseNode()
-}
-
-// ArrayUnsafe exports the underlying pointer to its children array
-// WARN: don't use it unless you know what you are doing
-//
-// Deprecated: this API now returns copied nodes instead of directly reference,
-// which has no difference with ArrayUseNode
-// func (self *Node) UnsafeArray() ([]Node, error) {
-// if err := self.should(types.V_ARRAY, "an array"); err != nil {
-// return nil, err
-// }
-// if err := self.skipAllIndex(); err != nil {
-// return nil, err
-// }
-// return self.toGenericArrayUseNode()
-// }
-
-func (self *Node) unsafeArray() (*linkedNodes, error) {
- if err := self.skipAllIndex(); err != nil {
- return nil, err
- }
- if self.p == nil {
- *self = newArray(new(linkedNodes))
- }
- return (*linkedNodes)(self.p), nil
-}
-
-// Interface loads all children under all paths from this node,
-// and converts itself as generic type.
-// WARN: all numeric nodes are casted to float64
-func (self *Node) Interface() (interface{}, error) {
- if err := self.checkRaw(); err != nil {
- return nil, err
- }
- switch self.t {
- case V_ERROR : return nil, self.Check()
- case types.V_NULL : return nil, nil
- case types.V_TRUE : return true, nil
- case types.V_FALSE : return false, nil
- case types.V_ARRAY : return self.toGenericArray()
- case types.V_OBJECT : return self.toGenericObject()
- case types.V_STRING : return self.toString(), nil
- case _V_NUMBER :
- v, err := self.toFloat64()
- if err != nil {
- return nil, err
- }
- return v, nil
- case _V_ARRAY_LAZY :
- if err := self.loadAllIndex(false); err != nil {
- return nil, err
- }
- return self.toGenericArray()
- case _V_OBJECT_LAZY :
- if err := self.loadAllKey(false); err != nil {
- return nil, err
- }
- return self.toGenericObject()
- case _V_ANY:
- switch v := self.packAny().(type) {
- case Node : return v.Interface()
- case *Node: return v.Interface()
- default : return v, nil
- }
- default : return nil, ErrUnsupportType
- }
-}
-
-func (self *Node) packAny() interface{} {
- return *(*interface{})(self.p)
-}
-
-// InterfaceUseNumber works same with Interface()
-// except numeric nodes are casted to json.Number
-func (self *Node) InterfaceUseNumber() (interface{}, error) {
- if err := self.checkRaw(); err != nil {
- return nil, err
- }
- switch self.t {
- case V_ERROR : return nil, self.Check()
- case types.V_NULL : return nil, nil
- case types.V_TRUE : return true, nil
- case types.V_FALSE : return false, nil
- case types.V_ARRAY : return self.toGenericArrayUseNumber()
- case types.V_OBJECT : return self.toGenericObjectUseNumber()
- case types.V_STRING : return self.toString(), nil
- case _V_NUMBER : return self.toNumber(), nil
- case _V_ARRAY_LAZY :
- if err := self.loadAllIndex(false); err != nil {
- return nil, err
- }
- return self.toGenericArrayUseNumber()
- case _V_OBJECT_LAZY :
- if err := self.loadAllKey(false); err != nil {
- return nil, err
- }
- return self.toGenericObjectUseNumber()
- case _V_ANY : return self.packAny(), nil
- default : return nil, ErrUnsupportType
- }
-}
-
-// InterfaceUseNode clone itself as a new node,
-// or its children as map[string]Node (or []Node)
-func (self *Node) InterfaceUseNode() (interface{}, error) {
- if err := self.checkRaw(); err != nil {
- return nil, err
- }
- switch self.t {
- case types.V_ARRAY : return self.toGenericArrayUseNode()
- case types.V_OBJECT : return self.toGenericObjectUseNode()
- case _V_ARRAY_LAZY :
- if err := self.skipAllIndex(); err != nil {
- return nil, err
- }
- return self.toGenericArrayUseNode()
- case _V_OBJECT_LAZY :
- if err := self.skipAllKey(); err != nil {
- return nil, err
- }
- return self.toGenericObjectUseNode()
- default : return *self, self.Check()
- }
-}
-
-// LoadAll loads the node's children
-// and ensure all its children can be READ concurrently (include its children's children)
-func (self *Node) LoadAll() error {
- return self.Load()
-}
-
-// Load loads the node's children as parsed.
-// and ensure all its children can be READ concurrently (include its children's children)
-func (self *Node) Load() error {
- switch self.t {
- case _V_ARRAY_LAZY: self.loadAllIndex(true)
- case _V_OBJECT_LAZY: self.loadAllKey(true)
- case V_ERROR: return self
- case V_NONE: return nil
- }
- if self.m == nil {
- self.m = new(sync.RWMutex)
- }
- return self.checkRaw()
-}
-
-/**---------------------------------- Internal Helper Methods ----------------------------------**/
-
-func (self *Node) should(t types.ValueType) error {
- if err := self.checkRaw(); err != nil {
- return err
- }
- if self.itype() != t {
- return ErrUnsupportType
- }
- return nil
-}
-
-func (self *Node) nodeAt(i int) *Node {
- var p *linkedNodes
- if self.isLazy() {
- _, stack := self.getParserAndArrayStack()
- p = &stack.v
- } else {
- p = (*linkedNodes)(self.p)
- if l := p.Len(); l != self.len() {
- // some nodes got unset, iterate to skip them
- for j:=0; j<l; j++ {
- v := p.At(j)
- if v.Exists() {
- i--
- }
- if i < 0 {
- return v
- }
- }
- return nil
- }
- }
- return p.At(i)
-}
-
-func (self *Node) pairAt(i int) *Pair {
- var p *linkedPairs
- if self.isLazy() {
- _, stack := self.getParserAndObjectStack()
- p = &stack.v
- } else {
- p = (*linkedPairs)(self.p)
- if l := p.Len(); l != self.len() {
- // some nodes got unset, iterate to skip them
- for j:=0; j<l; j++ {
- v := p.At(j)
- if v != nil && v.Value.Exists() {
- i--
- }
- if i < 0 {
- return v
- }
- }
- return nil
- }
- }
- return p.At(i)
-}
-
-func (self *Node) skipAllIndex() error {
- if !self.isLazy() {
- return nil
- }
- var err types.ParsingError
- parser, stack := self.getParserAndArrayStack()
- parser.skipValue = true
- parser.noLazy = true
- *self, err = parser.decodeArray(&stack.v)
- if err != 0 {
- return parser.ExportError(err)
- }
- return nil
-}
-
-func (self *Node) skipAllKey() error {
- if !self.isLazy() {
- return nil
- }
- var err types.ParsingError
- parser, stack := self.getParserAndObjectStack()
- parser.skipValue = true
- parser.noLazy = true
- *self, err = parser.decodeObject(&stack.v)
- if err != 0 {
- return parser.ExportError(err)
- }
- return nil
-}
-
-func (self *Node) skipKey(key string) (*Node, int) {
- nb := self.len()
- lazy := self.isLazy()
-
- if nb > 0 {
- /* linear search */
- var p *Pair
- var i int
- if lazy {
- s := (*parseObjectStack)(self.p)
- p, i = s.v.Get(key)
- } else {
- p, i = (*linkedPairs)(self.p).Get(key)
- }
-
- if p != nil {
- return &p.Value, i
- }
- }
-
- /* not found */
- if !lazy {
- return nil, -1
- }
-
- // lazy load
- for last, i := self.skipNextPair(), nb; last != nil; last, i = self.skipNextPair(), i+1 {
- if last.Value.Check() != nil {
- return &last.Value, -1
- }
- if last.Key == key {
- return &last.Value, i
- }
- }
-
- return nil, -1
-}
-
-func (self *Node) skipIndex(index int) *Node {
- nb := self.len()
- if nb > index {
- v := self.nodeAt(index)
- return v
- }
- if !self.isLazy() {
- return nil
- }
-
- // lazy load
- for last := self.skipNextNode(); last != nil; last = self.skipNextNode(){
- if last.Check() != nil {
- return last
- }
- if self.len() > index {
- return last
- }
- }
-
- return nil
-}
-
-func (self *Node) skipIndexPair(index int) *Pair {
- nb := self.len()
- if nb > index {
- return self.pairAt(index)
- }
- if !self.isLazy() {
- return nil
- }
-
- // lazy load
- for last := self.skipNextPair(); last != nil; last = self.skipNextPair(){
- if last.Value.Check() != nil {
- return last
- }
- if self.len() > index {
- return last
- }
- }
-
- return nil
-}
-
-func (self *Node) loadAllIndex(loadOnce bool) error {
- if !self.isLazy() {
- return nil
- }
- var err types.ParsingError
- parser, stack := self.getParserAndArrayStack()
- if !loadOnce {
- parser.noLazy = true
- } else {
- parser.loadOnce = true
- }
- *self, err = parser.decodeArray(&stack.v)
- if err != 0 {
- return parser.ExportError(err)
- }
- return nil
-}
-
-func (self *Node) loadAllKey(loadOnce bool) error {
- if !self.isLazy() {
- return nil
- }
- var err types.ParsingError
- parser, stack := self.getParserAndObjectStack()
- if !loadOnce {
- parser.noLazy = true
- *self, err = parser.decodeObject(&stack.v)
- } else {
- parser.loadOnce = true
- *self, err = parser.decodeObject(&stack.v)
- }
- if err != 0 {
- return parser.ExportError(err)
- }
- return nil
-}
-
-func (self *Node) removeNode(i int) {
- node := self.nodeAt(i)
- if node == nil {
- return
- }
- *node = Node{}
- // NOTICE: not be consistent with linkedNode.Len()
- self.l--
-}
-
-func (self *Node) removePair(i int) {
- last := self.pairAt(i)
- if last == nil {
- return
- }
- *last = Pair{}
- // NOTICE: should be consistent with linkedPair.Len()
- self.l--
-}
-
-func (self *Node) removePairAt(i int) {
- p := (*linkedPairs)(self.p).At(i)
- if p == nil {
- return
- }
- *p = Pair{}
- // NOTICE: should be consistent with linkedPair.Len()
- self.l--
-}
-
-func (self *Node) toGenericArray() ([]interface{}, error) {
- nb := self.len()
- if nb == 0 {
- return []interface{}{}, nil
- }
- ret := make([]interface{}, 0, nb)
-
- /* convert each item */
- it := self.values()
- for v := it.next(); v != nil; v = it.next() {
- vv, err := v.Interface()
- if err != nil {
- return nil, err
- }
- ret = append(ret, vv)
- }
-
- /* all done */
- return ret, nil
-}
-
-func (self *Node) toGenericArrayUseNumber() ([]interface{}, error) {
- nb := self.len()
- if nb == 0 {
- return []interface{}{}, nil
- }
- ret := make([]interface{}, 0, nb)
-
- /* convert each item */
- it := self.values()
- for v := it.next(); v != nil; v = it.next() {
- vv, err := v.InterfaceUseNumber()
- if err != nil {
- return nil, err
- }
- ret = append(ret, vv)
- }
-
- /* all done */
- return ret, nil
-}
-
-func (self *Node) toGenericArrayUseNode() ([]Node, error) {
- var nb = self.len()
- if nb == 0 {
- return []Node{}, nil
- }
-
- var s = (*linkedNodes)(self.p)
- var out = make([]Node, nb)
- s.ToSlice(out)
-
- return out, nil
-}
-
-func (self *Node) toGenericObject() (map[string]interface{}, error) {
- nb := self.len()
- if nb == 0 {
- return map[string]interface{}{}, nil
- }
- ret := make(map[string]interface{}, nb)
-
- /* convert each item */
- it := self.properties()
- for v := it.next(); v != nil; v = it.next() {
- vv, err := v.Value.Interface()
- if err != nil {
- return nil, err
- }
- ret[v.Key] = vv
- }
-
- /* all done */
- return ret, nil
-}
-
-
-func (self *Node) toGenericObjectUseNumber() (map[string]interface{}, error) {
- nb := self.len()
- if nb == 0 {
- return map[string]interface{}{}, nil
- }
- ret := make(map[string]interface{}, nb)
-
- /* convert each item */
- it := self.properties()
- for v := it.next(); v != nil; v = it.next() {
- vv, err := v.Value.InterfaceUseNumber()
- if err != nil {
- return nil, err
- }
- ret[v.Key] = vv
- }
-
- /* all done */
- return ret, nil
-}
-
-func (self *Node) toGenericObjectUseNode() (map[string]Node, error) {
- var nb = self.len()
- if nb == 0 {
- return map[string]Node{}, nil
- }
-
- var s = (*linkedPairs)(self.p)
- var out = make(map[string]Node, nb)
- s.ToMap(out)
-
- /* all done */
- return out, nil
-}
-
-/**------------------------------------ Factory Methods ------------------------------------**/
-
-var (
- nullNode = Node{t: types.V_NULL}
- trueNode = Node{t: types.V_TRUE}
- falseNode = Node{t: types.V_FALSE}
-)
-
-// NewRaw creates a node of raw json.
-// If the input json is invalid, NewRaw returns a error Node.
-func NewRaw(json string) Node {
- parser := NewParserObj(json)
- start, err := parser.skip()
- if err != 0 {
- return *newError(err, err.Message())
- }
- it := switchRawType(parser.s[start])
- if it == _V_NONE {
- return Node{}
- }
- return newRawNode(parser.s[start:parser.p], it, false)
-}
-
-// NewRawConcurrentRead creates a node of raw json, which can be READ
-// (GetByPath/Get/Index/GetOrIndex/Int64/Bool/Float64/String/Number/Interface/Array/Map/Raw/MarshalJSON) concurrently.
-// If the input json is invalid, NewRaw returns a error Node.
-func NewRawConcurrentRead(json string) Node {
- parser := NewParserObj(json)
- start, err := parser.skip()
- if err != 0 {
- return *newError(err, err.Message())
- }
- it := switchRawType(parser.s[start])
- if it == _V_NONE {
- return Node{}
- }
- return newRawNode(parser.s[start:parser.p], it, true)
-}
-
-// NewAny creates a node of type V_ANY if any's type isn't Node or *Node,
-// which stores interface{} and can be only used for `.Interface()`\`.MarshalJSON()`.
-func NewAny(any interface{}) Node {
- switch n := any.(type) {
- case Node:
- return n
- case *Node:
- return *n
- default:
- return Node{
- t: _V_ANY,
- p: unsafe.Pointer(&any),
- }
- }
-}
-
-// NewBytes encodes given src with Base64 (RFC 4648), and creates a node of type V_STRING.
-func NewBytes(src []byte) Node {
- if len(src) == 0 {
- panic("empty src bytes")
- }
- out := rt.EncodeBase64(src)
- return NewString(out)
-}
-
-// NewNull creates a node of type V_NULL
-func NewNull() Node {
- return Node{
- p: nil,
- t: types.V_NULL,
- }
-}
-
-// NewBool creates a node of type bool:
-// If v is true, returns V_TRUE node
-// If v is false, returns V_FALSE node
-func NewBool(v bool) Node {
- var t = types.V_FALSE
- if v {
- t = types.V_TRUE
- }
- return Node{
- p: nil,
- t: t,
- }
-}
-
-// NewNumber creates a json.Number node
-// v must be a decimal string complying with RFC8259
-func NewNumber(v string) Node {
- return Node{
- l: uint(len(v)),
- p: rt.StrPtr(v),
- t: _V_NUMBER,
- }
-}
-
-func (node *Node) toNumber() json.Number {
- return json.Number(rt.StrFrom(node.p, int64(node.l)))
-}
-
-func (self *Node) toString() string {
- return rt.StrFrom(self.p, int64(self.l))
-}
-
-func (node *Node) toFloat64() (float64, error) {
- ret, err := node.toNumber().Float64()
- if err != nil {
- return 0, err
- }
- return ret, nil
-}
-
-func (node *Node) toInt64() (int64, error) {
- ret,err := node.toNumber().Int64()
- if err != nil {
- return 0, err
- }
- return ret, nil
-}
-
-func newBytes(v []byte) Node {
- return Node{
- t: types.V_STRING,
- p: mem2ptr(v),
- l: uint(len(v)),
- }
-}
-
-// NewString creates a node of type V_STRING.
-// v is considered to be a valid UTF-8 string,
-// which means it won't be validated and unescaped.
-// when the node is encoded to json, v will be escaped.
-func NewString(v string) Node {
- return Node{
- t: types.V_STRING,
- p: rt.StrPtr(v),
- l: uint(len(v)),
- }
-}
-
-// NewArray creates a node of type V_ARRAY,
-// using v as its underlying children
-func NewArray(v []Node) Node {
- s := new(linkedNodes)
- s.FromSlice(v)
- return newArray(s)
-}
-
-const _Threshold_Index = 16
-
-func newArray(v *linkedNodes) Node {
- return Node{
- t: types.V_ARRAY,
- l: uint(v.Len()),
- p: unsafe.Pointer(v),
- }
-}
-
-func (self *Node) setArray(v *linkedNodes) {
- self.t = types.V_ARRAY
- self.l = uint(v.Len())
- self.p = unsafe.Pointer(v)
-}
-
-// NewObject creates a node of type V_OBJECT,
-// using v as its underlying children
-func NewObject(v []Pair) Node {
- s := new(linkedPairs)
- s.FromSlice(v)
- return newObject(s)
-}
-
-func newObject(v *linkedPairs) Node {
- if v.size > _Threshold_Index {
- v.BuildIndex()
- }
- return Node{
- t: types.V_OBJECT,
- l: uint(v.Len()),
- p: unsafe.Pointer(v),
- }
-}
-
-func (self *Node) setObject(v *linkedPairs) {
- if v.size > _Threshold_Index {
- v.BuildIndex()
- }
- self.t = types.V_OBJECT
- self.l = uint(v.Len())
- self.p = unsafe.Pointer(v)
-}
-
-func (self *Node) parseRaw(full bool) {
- lock := self.lock()
- defer self.unlock()
- if !self.isRaw() {
- return
- }
- raw := self.toString()
- parser := NewParserObj(raw)
- var e types.ParsingError
- if full {
- parser.noLazy = true
- *self, e = parser.Parse()
- } else if lock {
- var n Node
- parser.noLazy = true
- parser.loadOnce = true
- n, e = parser.Parse()
- self.assign(n)
- } else {
- *self, e = parser.Parse()
- }
- if e != 0 {
- *self = *newSyntaxError(parser.syntaxError(e))
- }
-}
-
-func (self *Node) assign(n Node) {
- self.l = n.l
- self.p = n.p
- atomic.StoreInt64(&self.t, n.t)
-}
diff --git a/vendor/github.com/bytedance/sonic/ast/parser.go b/vendor/github.com/bytedance/sonic/ast/parser.go
deleted file mode 100644
index 30bd1f451..000000000
--- a/vendor/github.com/bytedance/sonic/ast/parser.go
+++ /dev/null
@@ -1,766 +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 ast
-
-import (
- "fmt"
- "sync"
- "sync/atomic"
-
- "github.com/bytedance/sonic/internal/native/types"
- "github.com/bytedance/sonic/internal/rt"
-)
-
-const (
- _DEFAULT_NODE_CAP int = 16
- _APPEND_GROW_SHIFT = 1
-)
-
-const (
- _ERR_NOT_FOUND types.ParsingError = 33
- _ERR_UNSUPPORT_TYPE types.ParsingError = 34
-)
-
-var (
- // ErrNotExist means both key and value doesn't exist
- ErrNotExist error = newError(_ERR_NOT_FOUND, "value not exists")
-
- // ErrUnsupportType means API on the node is unsupported
- ErrUnsupportType error = newError(_ERR_UNSUPPORT_TYPE, "unsupported type")
-)
-
-type Parser struct {
- p int
- s string
- noLazy bool
- loadOnce bool
- skipValue bool
- dbuf *byte
-}
-
-/** Parser Private Methods **/
-
-func (self *Parser) delim() types.ParsingError {
- n := len(self.s)
- p := self.lspace(self.p)
-
- /* check for EOF */
- if p >= n {
- return types.ERR_EOF
- }
-
- /* check for the delimtier */
- if self.s[p] != ':' {
- return types.ERR_INVALID_CHAR
- }
-
- /* update the read pointer */
- self.p = p + 1
- return 0
-}
-
-func (self *Parser) object() types.ParsingError {
- n := len(self.s)
- p := self.lspace(self.p)
-
- /* check for EOF */
- if p >= n {
- return types.ERR_EOF
- }
-
- /* check for the delimtier */
- if self.s[p] != '{' {
- return types.ERR_INVALID_CHAR
- }
-
- /* update the read pointer */
- self.p = p + 1
- return 0
-}
-
-func (self *Parser) array() types.ParsingError {
- n := len(self.s)
- p := self.lspace(self.p)
-
- /* check for EOF */
- if p >= n {
- return types.ERR_EOF
- }
-
- /* check for the delimtier */
- if self.s[p] != '[' {
- return types.ERR_INVALID_CHAR
- }
-
- /* update the read pointer */
- self.p = p + 1
- return 0
-}
-
-func (self *Parser) lspace(sp int) int {
- ns := len(self.s)
- for ; sp<ns && isSpace(self.s[sp]); sp+=1 {}
-
- return sp
-}
-
-func (self *Parser) backward() {
- for ; self.p >= 0 && isSpace(self.s[self.p]); self.p-=1 {}
-}
-
-func (self *Parser) decodeArray(ret *linkedNodes) (Node, types.ParsingError) {
- sp := self.p
- ns := len(self.s)
-
- /* check for EOF */
- if self.p = self.lspace(sp); self.p >= ns {
- return Node{}, types.ERR_EOF
- }
-
- /* check for empty array */
- if self.s[self.p] == ']' {
- self.p++
- return Node{t: types.V_ARRAY}, 0
- }
-
- /* allocate array space and parse every element */
- for {
- var val Node
- var err types.ParsingError
-
- if self.skipValue {
- /* skip the value */
- var start int
- if start, err = self.skipFast(); err != 0 {
- return Node{}, err
- }
- if self.p > ns {
- return Node{}, types.ERR_EOF
- }
- t := switchRawType(self.s[start])
- if t == _V_NONE {
- return Node{}, types.ERR_INVALID_CHAR
- }
- val = newRawNode(self.s[start:self.p], t, false)
- }else{
- /* decode the value */
- if val, err = self.Parse(); err != 0 {
- return Node{}, err
- }
- }
-
- /* add the value to result */
- ret.Push(val)
- self.p = self.lspace(self.p)
-
- /* check for EOF */
- if self.p >= ns {
- return Node{}, types.ERR_EOF
- }
-
- /* check for the next character */
- switch self.s[self.p] {
- case ',' : self.p++
- case ']' : self.p++; return newArray(ret), 0
- default:
- // if val.isLazy() {
- // return newLazyArray(self, ret), 0
- // }
- return Node{}, types.ERR_INVALID_CHAR
- }
- }
-}
-
-func (self *Parser) decodeObject(ret *linkedPairs) (Node, types.ParsingError) {
- sp := self.p
- ns := len(self.s)
-
- /* check for EOF */
- if self.p = self.lspace(sp); self.p >= ns {
- return Node{}, types.ERR_EOF
- }
-
- /* check for empty object */
- if self.s[self.p] == '}' {
- self.p++
- return Node{t: types.V_OBJECT}, 0
- }
-
- /* decode each pair */
- for {
- var val Node
- var njs types.JsonState
- var err types.ParsingError
-
- /* decode the key */
- if njs = self.decodeValue(); njs.Vt != types.V_STRING {
- return Node{}, types.ERR_INVALID_CHAR
- }
-
- /* extract the key */
- idx := self.p - 1
- key := self.s[njs.Iv:idx]
-
- /* check for escape sequence */
- if njs.Ep != -1 {
- if key, err = unquote(key); err != 0 {
- return Node{}, err
- }
- }
-
- /* expect a ':' delimiter */
- if err = self.delim(); err != 0 {
- return Node{}, err
- }
-
-
- if self.skipValue {
- /* skip the value */
- var start int
- if start, err = self.skipFast(); err != 0 {
- return Node{}, err
- }
- if self.p > ns {
- return Node{}, types.ERR_EOF
- }
- t := switchRawType(self.s[start])
- if t == _V_NONE {
- return Node{}, types.ERR_INVALID_CHAR
- }
- val = newRawNode(self.s[start:self.p], t, false)
- } else {
- /* decode the value */
- if val, err = self.Parse(); err != 0 {
- return Node{}, err
- }
- }
-
- /* add the value to result */
- // FIXME: ret's address may change here, thus previous referred node in ret may be invalid !!
- ret.Push(NewPair(key, val))
- self.p = self.lspace(self.p)
-
- /* check for EOF */
- if self.p >= ns {
- return Node{}, types.ERR_EOF
- }
-
- /* check for the next character */
- switch self.s[self.p] {
- case ',' : self.p++
- case '}' : self.p++; return newObject(ret), 0
- default:
- // if val.isLazy() {
- // return newLazyObject(self, ret), 0
- // }
- return Node{}, types.ERR_INVALID_CHAR
- }
- }
-}
-
-func (self *Parser) decodeString(iv int64, ep int) (Node, types.ParsingError) {
- p := self.p - 1
- s := self.s[iv:p]
-
- /* fast path: no escape sequence */
- if ep == -1 {
- return NewString(s), 0
- }
-
- /* unquote the string */
- out, err := unquote(s)
-
- /* check for errors */
- if err != 0 {
- return Node{}, err
- } else {
- return newBytes(rt.Str2Mem(out)), 0
- }
-}
-
-/** Parser Interface **/
-
-func (self *Parser) Pos() int {
- return self.p
-}
-
-
-// Parse returns a ast.Node representing the parser's JSON.
-// NOTICE: the specific parsing lazy dependens parser's option
-// It only parse first layer and first child for Object or Array be default
-func (self *Parser) Parse() (Node, types.ParsingError) {
- switch val := self.decodeValue(); val.Vt {
- case types.V_EOF : return Node{}, types.ERR_EOF
- case types.V_NULL : return nullNode, 0
- case types.V_TRUE : return trueNode, 0
- case types.V_FALSE : return falseNode, 0
- case types.V_STRING : return self.decodeString(val.Iv, val.Ep)
- case types.V_ARRAY:
- s := self.p - 1;
- if p := skipBlank(self.s, self.p); p >= self.p && self.s[p] == ']' {
- self.p = p + 1
- return Node{t: types.V_ARRAY}, 0
- }
- if self.noLazy {
- if self.loadOnce {
- self.noLazy = false
- }
- return self.decodeArray(new(linkedNodes))
- }
- // NOTICE: loadOnce always keep raw json for object or array
- if self.loadOnce {
- self.p = s
- s, e := self.skipFast()
- if e != 0 {
- return Node{}, e
- }
- return newRawNode(self.s[s:self.p], types.V_ARRAY, true), 0
- }
- return newLazyArray(self), 0
- case types.V_OBJECT:
- s := self.p - 1;
- if p := skipBlank(self.s, self.p); p >= self.p && self.s[p] == '}' {
- self.p = p + 1
- return Node{t: types.V_OBJECT}, 0
- }
- // NOTICE: loadOnce always keep raw json for object or array
- if self.noLazy {
- if self.loadOnce {
- self.noLazy = false
- }
- return self.decodeObject(new(linkedPairs))
- }
- if self.loadOnce {
- self.p = s
- s, e := self.skipFast()
- if e != 0 {
- return Node{}, e
- }
- return newRawNode(self.s[s:self.p], types.V_OBJECT, true), 0
- }
- return newLazyObject(self), 0
- case types.V_DOUBLE : return NewNumber(self.s[val.Ep:self.p]), 0
- case types.V_INTEGER : return NewNumber(self.s[val.Ep:self.p]), 0
- default : return Node{}, types.ParsingError(-val.Vt)
- }
-}
-
-func (self *Parser) searchKey(match string) types.ParsingError {
- ns := len(self.s)
- if err := self.object(); err != 0 {
- return err
- }
-
- /* check for EOF */
- if self.p = self.lspace(self.p); self.p >= ns {
- return types.ERR_EOF
- }
-
- /* check for empty object */
- if self.s[self.p] == '}' {
- self.p++
- return _ERR_NOT_FOUND
- }
-
- var njs types.JsonState
- var err types.ParsingError
- /* decode each pair */
- for {
-
- /* decode the key */
- if njs = self.decodeValue(); njs.Vt != types.V_STRING {
- return types.ERR_INVALID_CHAR
- }
-
- /* extract the key */
- idx := self.p - 1
- key := self.s[njs.Iv:idx]
-
- /* check for escape sequence */
- if njs.Ep != -1 {
- if key, err = unquote(key); err != 0 {
- return err
- }
- }
-
- /* expect a ':' delimiter */
- if err = self.delim(); err != 0 {
- return err
- }
-
- /* skip value */
- if key != match {
- if _, err = self.skipFast(); err != 0 {
- return err
- }
- } else {
- return 0
- }
-
- /* check for EOF */
- self.p = self.lspace(self.p)
- if self.p >= ns {
- return types.ERR_EOF
- }
-
- /* check for the next character */
- switch self.s[self.p] {
- case ',':
- self.p++
- case '}':
- self.p++
- return _ERR_NOT_FOUND
- default:
- return types.ERR_INVALID_CHAR
- }
- }
-}
-
-func (self *Parser) searchIndex(idx int) types.ParsingError {
- ns := len(self.s)
- if err := self.array(); err != 0 {
- return err
- }
-
- /* check for EOF */
- if self.p = self.lspace(self.p); self.p >= ns {
- return types.ERR_EOF
- }
-
- /* check for empty array */
- if self.s[self.p] == ']' {
- self.p++
- return _ERR_NOT_FOUND
- }
-
- var err types.ParsingError
- /* allocate array space and parse every element */
- for i := 0; i < idx; i++ {
-
- /* decode the value */
- if _, err = self.skipFast(); err != 0 {
- return err
- }
-
- /* check for EOF */
- self.p = self.lspace(self.p)
- if self.p >= ns {
- return types.ERR_EOF
- }
-
- /* check for the next character */
- switch self.s[self.p] {
- case ',':
- self.p++
- case ']':
- self.p++
- return _ERR_NOT_FOUND
- default:
- return types.ERR_INVALID_CHAR
- }
- }
-
- return 0
-}
-
-func (self *Node) skipNextNode() *Node {
- if !self.isLazy() {
- return nil
- }
-
- parser, stack := self.getParserAndArrayStack()
- ret := &stack.v
- sp := parser.p
- ns := len(parser.s)
-
- /* check for EOF */
- if parser.p = parser.lspace(sp); parser.p >= ns {
- return newSyntaxError(parser.syntaxError(types.ERR_EOF))
- }
-
- /* check for empty array */
- if parser.s[parser.p] == ']' {
- parser.p++
- self.setArray(ret)
- return nil
- }
-
- var val Node
- /* skip the value */
- if start, err := parser.skipFast(); err != 0 {
- return newSyntaxError(parser.syntaxError(err))
- } else {
- t := switchRawType(parser.s[start])
- if t == _V_NONE {
- return newSyntaxError(parser.syntaxError(types.ERR_INVALID_CHAR))
- }
- val = newRawNode(parser.s[start:parser.p], t, false)
- }
-
- /* add the value to result */
- ret.Push(val)
- self.l++
- parser.p = parser.lspace(parser.p)
-
- /* check for EOF */
- if parser.p >= ns {
- return newSyntaxError(parser.syntaxError(types.ERR_EOF))
- }
-
- /* check for the next character */
- switch parser.s[parser.p] {
- case ',':
- parser.p++
- return ret.At(ret.Len()-1)
- case ']':
- parser.p++
- self.setArray(ret)
- return ret.At(ret.Len()-1)
- default:
- return newSyntaxError(parser.syntaxError(types.ERR_INVALID_CHAR))
- }
-}
-
-func (self *Node) skipNextPair() (*Pair) {
- if !self.isLazy() {
- return nil
- }
-
- parser, stack := self.getParserAndObjectStack()
- ret := &stack.v
- sp := parser.p
- ns := len(parser.s)
-
- /* check for EOF */
- if parser.p = parser.lspace(sp); parser.p >= ns {
- return newErrorPair(parser.syntaxError(types.ERR_EOF))
- }
-
- /* check for empty object */
- if parser.s[parser.p] == '}' {
- parser.p++
- self.setObject(ret)
- return nil
- }
-
- /* decode one pair */
- var val Node
- var njs types.JsonState
- var err types.ParsingError
-
- /* decode the key */
- if njs = parser.decodeValue(); njs.Vt != types.V_STRING {
- return newErrorPair(parser.syntaxError(types.ERR_INVALID_CHAR))
- }
-
- /* extract the key */
- idx := parser.p - 1
- key := parser.s[njs.Iv:idx]
-
- /* check for escape sequence */
- if njs.Ep != -1 {
- if key, err = unquote(key); err != 0 {
- return newErrorPair(parser.syntaxError(err))
- }
- }
-
- /* expect a ':' delimiter */
- if err = parser.delim(); err != 0 {
- return newErrorPair(parser.syntaxError(err))
- }
-
- /* skip the value */
- if start, err := parser.skipFast(); err != 0 {
- return newErrorPair(parser.syntaxError(err))
- } else {
- t := switchRawType(parser.s[start])
- if t == _V_NONE {
- return newErrorPair(parser.syntaxError(types.ERR_INVALID_CHAR))
- }
- val = newRawNode(parser.s[start:parser.p], t, false)
- }
-
- /* add the value to result */
- ret.Push(NewPair(key, val))
- self.l++
- parser.p = parser.lspace(parser.p)
-
- /* check for EOF */
- if parser.p >= ns {
- return newErrorPair(parser.syntaxError(types.ERR_EOF))
- }
-
- /* check for the next character */
- switch parser.s[parser.p] {
- case ',':
- parser.p++
- return ret.At(ret.Len()-1)
- case '}':
- parser.p++
- self.setObject(ret)
- return ret.At(ret.Len()-1)
- default:
- return newErrorPair(parser.syntaxError(types.ERR_INVALID_CHAR))
- }
-}
-
-
-/** Parser Factory **/
-
-// Loads parse all json into interface{}
-func Loads(src string) (int, interface{}, error) {
- ps := &Parser{s: src}
- np, err := ps.Parse()
-
- /* check for errors */
- if err != 0 {
- return 0, nil, ps.ExportError(err)
- } else {
- x, err := np.Interface()
- if err != nil {
- return 0, nil, err
- }
- return ps.Pos(), x, nil
- }
-}
-
-// LoadsUseNumber parse all json into interface{}, with numeric nodes casted to json.Number
-func LoadsUseNumber(src string) (int, interface{}, error) {
- ps := &Parser{s: src}
- np, err := ps.Parse()
-
- /* check for errors */
- if err != 0 {
- return 0, nil, err
- } else {
- x, err := np.InterfaceUseNumber()
- if err != nil {
- return 0, nil, err
- }
- return ps.Pos(), x, nil
- }
-}
-
-// NewParser returns pointer of new allocated parser
-func NewParser(src string) *Parser {
- return &Parser{s: src}
-}
-
-// NewParser returns new allocated parser
-func NewParserObj(src string) Parser {
- return Parser{s: src}
-}
-
-// decodeNumber controls if parser decodes the number values instead of skip them
-// WARN: once you set decodeNumber(true), please set decodeNumber(false) before you drop the parser
-// otherwise the memory CANNOT be reused
-func (self *Parser) decodeNumber(decode bool) {
- if !decode && self.dbuf != nil {
- types.FreeDbuf(self.dbuf)
- self.dbuf = nil
- return
- }
- if decode && self.dbuf == nil {
- self.dbuf = types.NewDbuf()
- }
-}
-
-// ExportError converts types.ParsingError to std Error
-func (self *Parser) ExportError(err types.ParsingError) error {
- if err == _ERR_NOT_FOUND {
- return ErrNotExist
- }
- return fmt.Errorf("%q", SyntaxError{
- Pos : self.p,
- Src : self.s,
- Code: err,
- }.Description())
-}
-
-func backward(src string, i int) int {
- for ; i>=0 && isSpace(src[i]); i-- {}
- return i
-}
-
-
-func newRawNode(str string, typ types.ValueType, lock bool) Node {
- ret := Node{
- t: typ | _V_RAW,
- p: rt.StrPtr(str),
- l: uint(len(str)),
- }
- if lock {
- ret.m = new(sync.RWMutex)
- }
- return ret
-}
-
-var typeJumpTable = [256]types.ValueType{
- '"' : types.V_STRING,
- '-' : _V_NUMBER,
- '0' : _V_NUMBER,
- '1' : _V_NUMBER,
- '2' : _V_NUMBER,
- '3' : _V_NUMBER,
- '4' : _V_NUMBER,
- '5' : _V_NUMBER,
- '6' : _V_NUMBER,
- '7' : _V_NUMBER,
- '8' : _V_NUMBER,
- '9' : _V_NUMBER,
- '[' : types.V_ARRAY,
- 'f' : types.V_FALSE,
- 'n' : types.V_NULL,
- 't' : types.V_TRUE,
- '{' : types.V_OBJECT,
-}
-
-func switchRawType(c byte) types.ValueType {
- return typeJumpTable[c]
-}
-
-func (self *Node) loadt() types.ValueType {
- return (types.ValueType)(atomic.LoadInt64(&self.t))
-}
-
-func (self *Node) lock() bool {
- if m := self.m; m != nil {
- m.Lock()
- return true
- }
- return false
-}
-
-func (self *Node) unlock() {
- if m := self.m; m != nil {
- m.Unlock()
- }
-}
-
-func (self *Node) rlock() bool {
- if m := self.m; m != nil {
- m.RLock()
- return true
- }
- return false
-}
-
-func (self *Node) runlock() {
- if m := self.m; m != nil {
- m.RUnlock()
- }
-}
diff --git a/vendor/github.com/bytedance/sonic/ast/search.go b/vendor/github.com/bytedance/sonic/ast/search.go
deleted file mode 100644
index 9a5fb9420..000000000
--- a/vendor/github.com/bytedance/sonic/ast/search.go
+++ /dev/null
@@ -1,157 +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 ast
-
-import (
- `github.com/bytedance/sonic/internal/rt`
- `github.com/bytedance/sonic/internal/native/types`
-)
-
-// SearchOptions controls Searcher's behavior
-type SearchOptions struct {
- // ValidateJSON indicates the searcher to validate the entire JSON
- ValidateJSON bool
-
- // CopyReturn indicates the searcher to copy the result JSON instead of refer from the input
- // This can help to reduce memory usage if you cache the results
- CopyReturn bool
-
- // ConcurrentRead indicates the searcher to return a concurrently-READ-safe node,
- // including: GetByPath/Get/Index/GetOrIndex/Int64/Bool/Float64/String/Number/Interface/Array/Map/Raw/MarshalJSON
- ConcurrentRead bool
-}
-
-type Searcher struct {
- parser Parser
- SearchOptions
-}
-
-func NewSearcher(str string) *Searcher {
- return &Searcher{
- parser: Parser{
- s: str,
- noLazy: false,
- },
- SearchOptions: SearchOptions{
- ValidateJSON: true,
- },
- }
-}
-
-// GetByPathCopy search in depth from top json and returns a **Copied** json node at the path location
-func (self *Searcher) GetByPathCopy(path ...interface{}) (Node, error) {
- self.CopyReturn = true
- return self.getByPath(path...)
-}
-
-// GetByPathNoCopy search in depth from top json and returns a **Referenced** json node at the path location
-//
-// WARN: this search directly refer partial json from top json, which has faster speed,
-// may consumes more memory.
-func (self *Searcher) GetByPath(path ...interface{}) (Node, error) {
- return self.getByPath(path...)
-}
-
-func (self *Searcher) getByPath(path ...interface{}) (Node, error) {
- var err types.ParsingError
- var start int
-
- self.parser.p = 0
- start, err = self.parser.getByPath(self.ValidateJSON, path...)
- if err != 0 {
- // for compatibility with old version
- if err == types.ERR_NOT_FOUND {
- return Node{}, ErrNotExist
- }
- if err == types.ERR_UNSUPPORT_TYPE {
- panic("path must be either int(>=0) or string")
- }
- return Node{}, self.parser.syntaxError(err)
- }
-
- t := switchRawType(self.parser.s[start])
- if t == _V_NONE {
- return Node{}, self.parser.ExportError(err)
- }
-
- // copy string to reducing memory usage
- var raw string
- if self.CopyReturn {
- raw = rt.Mem2Str([]byte(self.parser.s[start:self.parser.p]))
- } else {
- raw = self.parser.s[start:self.parser.p]
- }
- return newRawNode(raw, t, self.ConcurrentRead), nil
-}
-
-// GetByPath searches a path and returns relaction and types of target
-func _GetByPath(src string, path ...interface{}) (start int, end int, typ int, err error) {
- p := NewParserObj(src)
- s, e := p.getByPath(false, path...)
- if e != 0 {
- // for compatibility with old version
- if e == types.ERR_NOT_FOUND {
- return -1, -1, 0, ErrNotExist
- }
- if e == types.ERR_UNSUPPORT_TYPE {
- panic("path must be either int(>=0) or string")
- }
- return -1, -1, 0, p.syntaxError(e)
- }
-
- t := switchRawType(p.s[s])
- if t == _V_NONE {
- return -1, -1, 0, ErrNotExist
- }
- if t == _V_NUMBER {
- p.p = 1 + backward(p.s, p.p-1)
- }
- return s, p.p, int(t), nil
-}
-
-// ValidSyntax check if a json has a valid JSON syntax,
-// while not validate UTF-8 charset
-func _ValidSyntax(json string) bool {
- p := NewParserObj(json)
- _, e := p.skip()
- if e != 0 {
- return false
- }
- if skipBlank(p.s, p.p) != -int(types.ERR_EOF) {
- return false
- }
- return true
-}
-
-// SkipFast skip a json value in fast-skip algs,
-// while not strictly validate JSON syntax and UTF-8 charset.
-func _SkipFast(src string, i int) (int, int, error) {
- p := NewParserObj(src)
- p.p = i
- s, e := p.skipFast()
- if e != 0 {
- return -1, -1, p.ExportError(e)
- }
- t := switchRawType(p.s[s])
- if t == _V_NONE {
- return -1, -1, ErrNotExist
- }
- if t == _V_NUMBER {
- p.p = 1 + backward(p.s, p.p-1)
- }
- return s, p.p, nil
-}
diff --git a/vendor/github.com/bytedance/sonic/ast/stubs.go b/vendor/github.com/bytedance/sonic/ast/stubs.go
deleted file mode 100644
index 53bf3b8aa..000000000
--- a/vendor/github.com/bytedance/sonic/ast/stubs.go
+++ /dev/null
@@ -1,142 +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 ast
-
-import (
- "unicode/utf8"
- "unsafe"
-
- "github.com/bytedance/sonic/internal/rt"
-)
-
-//go:noescape
-//go:linkname memmove runtime.memmove
-//goland:noinspection GoUnusedParameter
-func memmove(to unsafe.Pointer, from unsafe.Pointer, n uintptr)
-
-//go:linkname unsafe_NewArray reflect.unsafe_NewArray
-//goland:noinspection GoUnusedParameter
-func unsafe_NewArray(typ *rt.GoType, n int) unsafe.Pointer
-
-//go:nosplit
-func mem2ptr(s []byte) unsafe.Pointer {
- return (*rt.GoSlice)(unsafe.Pointer(&s)).Ptr
-}
-
-var safeSet = [utf8.RuneSelf]bool{
- ' ': true,
- '!': true,
- '"': false,
- '#': true,
- '$': true,
- '%': true,
- '&': true,
- '\'': true,
- '(': true,
- ')': true,
- '*': true,
- '+': true,
- ',': true,
- '-': true,
- '.': true,
- '/': true,
- '0': true,
- '1': true,
- '2': true,
- '3': true,
- '4': true,
- '5': true,
- '6': true,
- '7': true,
- '8': true,
- '9': true,
- ':': true,
- ';': true,
- '<': true,
- '=': true,
- '>': true,
- '?': true,
- '@': true,
- 'A': true,
- 'B': true,
- 'C': true,
- 'D': true,
- 'E': true,
- 'F': true,
- 'G': true,
- 'H': true,
- 'I': true,
- 'J': true,
- 'K': true,
- 'L': true,
- 'M': true,
- 'N': true,
- 'O': true,
- 'P': true,
- 'Q': true,
- 'R': true,
- 'S': true,
- 'T': true,
- 'U': true,
- 'V': true,
- 'W': true,
- 'X': true,
- 'Y': true,
- 'Z': true,
- '[': true,
- '\\': false,
- ']': true,
- '^': true,
- '_': true,
- '`': true,
- 'a': true,
- 'b': true,
- 'c': true,
- 'd': true,
- 'e': true,
- 'f': true,
- 'g': true,
- 'h': true,
- 'i': true,
- 'j': true,
- 'k': true,
- 'l': true,
- 'm': true,
- 'n': true,
- 'o': true,
- 'p': true,
- 'q': true,
- 'r': true,
- 's': true,
- 't': true,
- 'u': true,
- 'v': true,
- 'w': true,
- 'x': true,
- 'y': true,
- 'z': true,
- '{': true,
- '|': true,
- '}': true,
- '~': true,
- '\u007f': true,
-}
-
-var hex = "0123456789abcdef"
-
-//go:linkname unquoteBytes encoding/json.unquoteBytes
-func unquoteBytes(s []byte) (t []byte, ok bool)
diff --git a/vendor/github.com/bytedance/sonic/ast/visitor.go b/vendor/github.com/bytedance/sonic/ast/visitor.go
deleted file mode 100644
index dc0478513..000000000
--- a/vendor/github.com/bytedance/sonic/ast/visitor.go
+++ /dev/null
@@ -1,332 +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 ast
-
-import (
- `encoding/json`
- `errors`
-
- `github.com/bytedance/sonic/internal/native/types`
-)
-
-// Visitor handles the callbacks during preorder traversal of a JSON AST.
-//
-// According to the JSON RFC8259, a JSON AST can be defined by
-// the following rules without separator / whitespace tokens.
-//
-// JSON-AST = value
-// value = false / null / true / object / array / number / string
-// object = begin-object [ member *( member ) ] end-object
-// member = string value
-// array = begin-array [ value *( value ) ] end-array
-//
-type Visitor interface {
-
- // OnNull handles a JSON null value.
- OnNull() error
-
- // OnBool handles a JSON true / false value.
- OnBool(v bool) error
-
- // OnString handles a JSON string value.
- OnString(v string) error
-
- // OnInt64 handles a JSON number value with int64 type.
- OnInt64(v int64, n json.Number) error
-
- // OnFloat64 handles a JSON number value with float64 type.
- OnFloat64(v float64, n json.Number) error
-
- // OnObjectBegin handles the beginning of a JSON object value with a
- // suggested capacity that can be used to make your custom object container.
- //
- // After this point the visitor will receive a sequence of callbacks like
- // [string, value, string, value, ......, ObjectEnd].
- //
- // Note:
- // 1. This is a recursive definition which means the value can
- // also be a JSON object / array described by a sequence of callbacks.
- // 2. The suggested capacity will be 0 if current object is empty.
- // 3. Currently sonic use a fixed capacity for non-empty object (keep in
- // sync with ast.Node) which might not be very suitable. This may be
- // improved in future version.
- OnObjectBegin(capacity int) error
-
- // OnObjectKey handles a JSON object key string in member.
- OnObjectKey(key string) error
-
- // OnObjectEnd handles the ending of a JSON object value.
- OnObjectEnd() error
-
- // OnArrayBegin handles the beginning of a JSON array value with a
- // suggested capacity that can be used to make your custom array container.
- //
- // After this point the visitor will receive a sequence of callbacks like
- // [value, value, value, ......, ArrayEnd].
- //
- // Note:
- // 1. This is a recursive definition which means the value can
- // also be a JSON object / array described by a sequence of callbacks.
- // 2. The suggested capacity will be 0 if current array is empty.
- // 3. Currently sonic use a fixed capacity for non-empty array (keep in
- // sync with ast.Node) which might not be very suitable. This may be
- // improved in future version.
- OnArrayBegin(capacity int) error
-
- // OnArrayEnd handles the ending of a JSON array value.
- OnArrayEnd() error
-}
-
-// VisitorOptions contains all Visitor's options. The default value is an
-// empty VisitorOptions{}.
-type VisitorOptions struct {
- // OnlyNumber indicates parser to directly return number value without
- // conversion, then the first argument of OnInt64 / OnFloat64 will always
- // be zero.
- OnlyNumber bool
-}
-
-var defaultVisitorOptions = &VisitorOptions{}
-
-// Preorder decodes the whole JSON string and callbacks each AST node to visitor
-// during preorder traversal. Any visitor method with an error returned will
-// break the traversal and the given error will be directly returned. The opts
-// argument can be reused after every call.
-func Preorder(str string, visitor Visitor, opts *VisitorOptions) error {
- if opts == nil {
- opts = defaultVisitorOptions
- }
- // process VisitorOptions first to guarantee that all options will be
- // constant during decoding and make options more readable.
- var (
- optDecodeNumber = !opts.OnlyNumber
- )
-
- tv := &traverser{
- parser: Parser{
- s: str,
- noLazy: true,
- skipValue: false,
- },
- visitor: visitor,
- }
-
- if optDecodeNumber {
- tv.parser.decodeNumber(true)
- }
-
- err := tv.decodeValue()
-
- if optDecodeNumber {
- tv.parser.decodeNumber(false)
- }
- return err
-}
-
-type traverser struct {
- parser Parser
- visitor Visitor
-}
-
-// NOTE: keep in sync with (*Parser).Parse method.
-func (self *traverser) decodeValue() error {
- switch val := self.parser.decodeValue(); val.Vt {
- case types.V_EOF:
- return types.ERR_EOF
- case types.V_NULL:
- return self.visitor.OnNull()
- case types.V_TRUE:
- return self.visitor.OnBool(true)
- case types.V_FALSE:
- return self.visitor.OnBool(false)
- case types.V_STRING:
- return self.decodeString(val.Iv, val.Ep)
- case types.V_DOUBLE:
- return self.visitor.OnFloat64(val.Dv,
- json.Number(self.parser.s[val.Ep:self.parser.p]))
- case types.V_INTEGER:
- return self.visitor.OnInt64(val.Iv,
- json.Number(self.parser.s[val.Ep:self.parser.p]))
- case types.V_ARRAY:
- return self.decodeArray()
- case types.V_OBJECT:
- return self.decodeObject()
- default:
- return types.ParsingError(-val.Vt)
- }
-}
-
-// NOTE: keep in sync with (*Parser).decodeArray method.
-func (self *traverser) decodeArray() error {
- sp := self.parser.p
- ns := len(self.parser.s)
-
- /* allocate array space and parse every element */
- if err := self.visitor.OnArrayBegin(_DEFAULT_NODE_CAP); err != nil {
- if err == VisitOPSkip {
- // NOTICE: for user needs to skip entiry object
- self.parser.p -= 1
- if _, e := self.parser.skipFast(); e != 0 {
- return e
- }
- return self.visitor.OnArrayEnd()
- }
- return err
- }
-
- /* check for EOF */
- self.parser.p = self.parser.lspace(sp)
- if self.parser.p >= ns {
- return types.ERR_EOF
- }
-
- /* check for empty array */
- if self.parser.s[self.parser.p] == ']' {
- self.parser.p++
- return self.visitor.OnArrayEnd()
- }
-
- for {
- /* decode the value */
- if err := self.decodeValue(); err != nil {
- return err
- }
- self.parser.p = self.parser.lspace(self.parser.p)
-
- /* check for EOF */
- if self.parser.p >= ns {
- return types.ERR_EOF
- }
-
- /* check for the next character */
- switch self.parser.s[self.parser.p] {
- case ',':
- self.parser.p++
- case ']':
- self.parser.p++
- return self.visitor.OnArrayEnd()
- default:
- return types.ERR_INVALID_CHAR
- }
- }
-}
-
-// NOTE: keep in sync with (*Parser).decodeObject method.
-func (self *traverser) decodeObject() error {
- sp := self.parser.p
- ns := len(self.parser.s)
-
- /* allocate object space and decode each pair */
- if err := self.visitor.OnObjectBegin(_DEFAULT_NODE_CAP); err != nil {
- if err == VisitOPSkip {
- // NOTICE: for user needs to skip entiry object
- self.parser.p -= 1
- if _, e := self.parser.skipFast(); e != 0 {
- return e
- }
- return self.visitor.OnObjectEnd()
- }
- return err
- }
-
- /* check for EOF */
- self.parser.p = self.parser.lspace(sp)
- if self.parser.p >= ns {
- return types.ERR_EOF
- }
-
- /* check for empty object */
- if self.parser.s[self.parser.p] == '}' {
- self.parser.p++
- return self.visitor.OnObjectEnd()
- }
-
- for {
- var njs types.JsonState
- var err types.ParsingError
-
- /* decode the key */
- if njs = self.parser.decodeValue(); njs.Vt != types.V_STRING {
- return types.ERR_INVALID_CHAR
- }
-
- /* extract the key */
- idx := self.parser.p - 1
- key := self.parser.s[njs.Iv:idx]
-
- /* check for escape sequence */
- if njs.Ep != -1 {
- if key, err = unquote(key); err != 0 {
- return err
- }
- }
-
- if err := self.visitor.OnObjectKey(key); err != nil {
- return err
- }
-
- /* expect a ':' delimiter */
- if err = self.parser.delim(); err != 0 {
- return err
- }
-
- /* decode the value */
- if err := self.decodeValue(); err != nil {
- return err
- }
-
- self.parser.p = self.parser.lspace(self.parser.p)
-
- /* check for EOF */
- if self.parser.p >= ns {
- return types.ERR_EOF
- }
-
- /* check for the next character */
- switch self.parser.s[self.parser.p] {
- case ',':
- self.parser.p++
- case '}':
- self.parser.p++
- return self.visitor.OnObjectEnd()
- default:
- return types.ERR_INVALID_CHAR
- }
- }
-}
-
-// NOTE: keep in sync with (*Parser).decodeString method.
-func (self *traverser) decodeString(iv int64, ep int) error {
- p := self.parser.p - 1
- s := self.parser.s[iv:p]
-
- /* fast path: no escape sequence */
- if ep == -1 {
- return self.visitor.OnString(s)
- }
-
- /* unquote the string */
- out, err := unquote(s)
- if err != 0 {
- return err
- }
- return self.visitor.OnString(out)
-}
-
-// If visitor return this error on `OnObjectBegin()` or `OnArrayBegin()`,
-// the transverer will skip entiry object or array
-var VisitOPSkip = errors.New("")