diff options
Diffstat (limited to 'vendor/github.com/bytedance/sonic/ast')
-rw-r--r-- | vendor/github.com/bytedance/sonic/ast/api.go | 135 | ||||
-rw-r--r-- | vendor/github.com/bytedance/sonic/ast/api_compat.go | 114 | ||||
-rw-r--r-- | vendor/github.com/bytedance/sonic/ast/asm.s | 0 | ||||
-rw-r--r-- | vendor/github.com/bytedance/sonic/ast/buffer.go | 470 | ||||
-rw-r--r-- | vendor/github.com/bytedance/sonic/ast/decode.go | 562 | ||||
-rw-r--r-- | vendor/github.com/bytedance/sonic/ast/encode.go | 274 | ||||
-rw-r--r-- | vendor/github.com/bytedance/sonic/ast/error.go | 134 | ||||
-rw-r--r-- | vendor/github.com/bytedance/sonic/ast/iterator.go | 216 | ||||
-rw-r--r-- | vendor/github.com/bytedance/sonic/ast/node.go | 1843 | ||||
-rw-r--r-- | vendor/github.com/bytedance/sonic/ast/parser.go | 766 | ||||
-rw-r--r-- | vendor/github.com/bytedance/sonic/ast/search.go | 157 | ||||
-rw-r--r-- | vendor/github.com/bytedance/sonic/ast/stubs.go | 142 | ||||
-rw-r--r-- | vendor/github.com/bytedance/sonic/ast/visitor.go | 332 |
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("") |