mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-11-05 08:02:25 -06:00
[chore]: Bump github.com/gin-contrib/gzip from 1.0.1 to 1.1.0 (#3639)
Bumps [github.com/gin-contrib/gzip](https://github.com/gin-contrib/gzip) from 1.0.1 to 1.1.0. - [Release notes](https://github.com/gin-contrib/gzip/releases) - [Changelog](https://github.com/gin-contrib/gzip/blob/master/.goreleaser.yaml) - [Commits](https://github.com/gin-contrib/gzip/compare/v1.0.1...v1.1.0) --- updated-dependencies: - dependency-name: github.com/gin-contrib/gzip dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
parent
8cfae010a9
commit
4d423102c1
519 changed files with 156968 additions and 132058 deletions
6
vendor/github.com/bytedance/sonic/ast/api.go
generated
vendored
6
vendor/github.com/bytedance/sonic/ast/api.go
generated
vendored
|
|
@ -1,5 +1,5 @@
|
|||
//go:build (amd64 && go1.16 && !go1.23) || (arm64 && go1.20 && !go1.23)
|
||||
// +build amd64,go1.16,!go1.23 arm64,go1.20,!go1.23
|
||||
//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.
|
||||
|
|
@ -61,7 +61,7 @@ func quote(buf *[]byte, val string) {
|
|||
}
|
||||
|
||||
// double buf size
|
||||
*b = growslice(typeByte, *b, b.Cap*2)
|
||||
*b = rt.GrowSlice(typeByte, *b, b.Cap*2)
|
||||
// ret is the complement of consumed input
|
||||
ret = ^ret
|
||||
// update input buffer
|
||||
|
|
|
|||
4
vendor/github.com/bytedance/sonic/ast/api_compat.go
generated
vendored
4
vendor/github.com/bytedance/sonic/ast/api_compat.go
generated
vendored
|
|
@ -1,4 +1,4 @@
|
|||
// +build !amd64,!arm64 go1.23 !go1.16 arm64,!go1.20
|
||||
// +build !amd64,!arm64 go1.24 !go1.17 arm64,!go1.20
|
||||
|
||||
/*
|
||||
* Copyright 2022 ByteDance Inc.
|
||||
|
|
@ -27,7 +27,7 @@ import (
|
|||
)
|
||||
|
||||
func init() {
|
||||
println("WARNING:(ast) sonic only supports Go1.16~1.22, but your environment is not suitable")
|
||||
println("WARNING:(ast) sonic only supports go1.17~1.23, but your environment is not suitable")
|
||||
}
|
||||
|
||||
func quote(buf *[]byte, val string) {
|
||||
|
|
|
|||
31
vendor/github.com/bytedance/sonic/ast/b64_amd64.go
generated
vendored
31
vendor/github.com/bytedance/sonic/ast/b64_amd64.go
generated
vendored
|
|
@ -1,31 +0,0 @@
|
|||
// +build amd64,go1.16
|
||||
|
||||
/**
|
||||
* 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 (
|
||||
`github.com/cloudwego/base64x`
|
||||
)
|
||||
|
||||
func decodeBase64(src string) ([]byte, error) {
|
||||
return base64x.StdEncoding.DecodeString(src)
|
||||
}
|
||||
|
||||
func encodeBase64(src []byte) string {
|
||||
return base64x.StdEncoding.EncodeToString(src)
|
||||
}
|
||||
31
vendor/github.com/bytedance/sonic/ast/b64_compat.go
generated
vendored
31
vendor/github.com/bytedance/sonic/ast/b64_compat.go
generated
vendored
|
|
@ -1,31 +0,0 @@
|
|||
// +build !amd64 !go1.16
|
||||
|
||||
/*
|
||||
* 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`
|
||||
)
|
||||
|
||||
func decodeBase64(src string) ([]byte, error) {
|
||||
return base64.StdEncoding.DecodeString(src)
|
||||
}
|
||||
|
||||
func encodeBase64(src []byte) string {
|
||||
return base64.StdEncoding.EncodeToString(src)
|
||||
}
|
||||
89
vendor/github.com/bytedance/sonic/ast/buffer.go
generated
vendored
89
vendor/github.com/bytedance/sonic/ast/buffer.go
generated
vendored
|
|
@ -17,8 +17,10 @@
|
|||
package ast
|
||||
|
||||
import (
|
||||
`sort`
|
||||
`unsafe`
|
||||
"sort"
|
||||
"unsafe"
|
||||
|
||||
"github.com/bytedance/sonic/internal/caching"
|
||||
)
|
||||
|
||||
type nodeChunk [_DEFAULT_NODE_CAP]Node
|
||||
|
|
@ -90,18 +92,11 @@ func (self *linkedNodes) Pop() {
|
|||
self.size--
|
||||
}
|
||||
|
||||
func (self *linkedPairs) Pop() {
|
||||
if self == nil || self.size == 0 {
|
||||
return
|
||||
}
|
||||
self.Set(self.size-1, Pair{})
|
||||
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
|
||||
|
|
@ -195,11 +190,22 @@ func (self *linkedNodes) FromSlice(con []Node) {
|
|||
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
|
||||
|
|
@ -233,7 +239,31 @@ 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 {
|
||||
|
|
@ -276,6 +306,21 @@ func (self *linkedPairs) growTailLength(l int) {
|
|||
|
||||
// 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
|
||||
|
|
@ -313,15 +358,27 @@ func (self *linkedPairs) ToMap(con map[string]Node) {
|
|||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
copy(self.head[:b+1], con)
|
||||
self.copyPairs(self.head[:b+1], con, b+1)
|
||||
return
|
||||
} else {
|
||||
copy(self.head[:], con)
|
||||
self.copyPairs(self.head[:], con, len(self.head))
|
||||
con = con[_DEFAULT_NODE_CAP:]
|
||||
}
|
||||
|
||||
|
|
@ -333,12 +390,12 @@ func (self *linkedPairs) FromSlice(con []Pair) {
|
|||
|
||||
for i:=0; i<a; i++ {
|
||||
self.tail[i] = new(pairChunk)
|
||||
copy(self.tail[i][:], con)
|
||||
self.copyPairs(self.tail[i][:], con, len(self.tail[i]))
|
||||
con = con[_DEFAULT_NODE_CAP:]
|
||||
}
|
||||
|
||||
self.tail[a] = new(pairChunk)
|
||||
copy(self.tail[a][:b+1], con)
|
||||
self.copyPairs(self.tail[a][:b+1], con, b+1)
|
||||
}
|
||||
|
||||
func (self *linkedPairs) Less(i, j int) bool {
|
||||
|
|
@ -347,6 +404,10 @@ func (self *linkedPairs) Less(i, j int) bool {
|
|||
|
||||
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
|
||||
}
|
||||
|
||||
|
|
|
|||
86
vendor/github.com/bytedance/sonic/ast/decode.go
generated
vendored
86
vendor/github.com/bytedance/sonic/ast/decode.go
generated
vendored
|
|
@ -17,19 +17,23 @@
|
|||
package ast
|
||||
|
||||
import (
|
||||
`encoding/base64`
|
||||
`runtime`
|
||||
`strconv`
|
||||
`unsafe`
|
||||
"encoding/base64"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"unsafe"
|
||||
|
||||
`github.com/bytedance/sonic/internal/native/types`
|
||||
`github.com/bytedance/sonic/internal/rt`
|
||||
"github.com/bytedance/sonic/internal/native/types"
|
||||
"github.com/bytedance/sonic/internal/rt"
|
||||
"github.com/bytedance/sonic/internal/utils"
|
||||
)
|
||||
|
||||
const _blankCharsMask = (1 << ' ') | (1 << '\t') | (1 << '\r') | (1 << '\n')
|
||||
// Hack: this is used for both checking space and cause firendly 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 (
|
||||
bytesNull = "null"
|
||||
strNull = "null"
|
||||
bytesTrue = "true"
|
||||
bytesFalse = "false"
|
||||
bytesObject = "{}"
|
||||
|
|
@ -37,7 +41,7 @@ const (
|
|||
)
|
||||
|
||||
func isSpace(c byte) bool {
|
||||
return (int(1<<c) & _blankCharsMask) != 0
|
||||
return (int(1<<c) & _Sonic_Not_Support_32Bit_Arch__Checking_32Bit_Arch_Here) != 0
|
||||
}
|
||||
|
||||
//go:nocheckptr
|
||||
|
|
@ -63,7 +67,7 @@ func decodeNull(src string, pos int) (ret int) {
|
|||
if ret > len(src) {
|
||||
return -int(types.ERR_EOF)
|
||||
}
|
||||
if src[pos:ret] == bytesNull {
|
||||
if src[pos:ret] == strNull {
|
||||
return ret
|
||||
} else {
|
||||
return -int(types.ERR_INVALID_CHAR)
|
||||
|
|
@ -287,67 +291,7 @@ func decodeValue(src string, pos int, skipnum bool) (ret int, v types.JsonState)
|
|||
|
||||
//go:nocheckptr
|
||||
func skipNumber(src string, pos int) (ret int) {
|
||||
sp := uintptr(rt.IndexChar(src, pos))
|
||||
se := uintptr(rt.IndexChar(src, len(src)))
|
||||
if uintptr(sp) >= se {
|
||||
return -int(types.ERR_EOF)
|
||||
}
|
||||
|
||||
if c := *(*byte)(unsafe.Pointer(sp)); c == '-' {
|
||||
sp += 1
|
||||
}
|
||||
ss := sp
|
||||
|
||||
var pointer bool
|
||||
var exponent bool
|
||||
var lastIsDigit bool
|
||||
var nextNeedDigit = true
|
||||
|
||||
for ; sp < se; sp += uintptr(1) {
|
||||
c := *(*byte)(unsafe.Pointer(sp))
|
||||
if isDigit(c) {
|
||||
lastIsDigit = true
|
||||
nextNeedDigit = false
|
||||
continue
|
||||
} else if nextNeedDigit {
|
||||
return -int(types.ERR_INVALID_CHAR)
|
||||
} else if c == '.' {
|
||||
if !lastIsDigit || pointer || exponent || sp == ss {
|
||||
return -int(types.ERR_INVALID_CHAR)
|
||||
}
|
||||
pointer = true
|
||||
lastIsDigit = false
|
||||
nextNeedDigit = true
|
||||
continue
|
||||
} else if c == 'e' || c == 'E' {
|
||||
if !lastIsDigit || exponent {
|
||||
return -int(types.ERR_INVALID_CHAR)
|
||||
}
|
||||
if sp == se-1 {
|
||||
return -int(types.ERR_EOF)
|
||||
}
|
||||
exponent = true
|
||||
lastIsDigit = false
|
||||
nextNeedDigit = false
|
||||
continue
|
||||
} else if c == '-' || c == '+' {
|
||||
if prev := *(*byte)(unsafe.Pointer(sp - 1)); prev != 'e' && prev != 'E' {
|
||||
return -int(types.ERR_INVALID_CHAR)
|
||||
}
|
||||
lastIsDigit = false
|
||||
nextNeedDigit = true
|
||||
continue
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if nextNeedDigit {
|
||||
return -int(types.ERR_EOF)
|
||||
}
|
||||
|
||||
runtime.KeepAlive(src)
|
||||
return int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr))
|
||||
return utils.SkipNumber(src, pos)
|
||||
}
|
||||
|
||||
//go:nocheckptr
|
||||
|
|
|
|||
55
vendor/github.com/bytedance/sonic/ast/encode.go
generated
vendored
55
vendor/github.com/bytedance/sonic/ast/encode.go
generated
vendored
|
|
@ -17,12 +17,11 @@
|
|||
package ast
|
||||
|
||||
import (
|
||||
`sync`
|
||||
`unicode/utf8`
|
||||
)
|
||||
"sync"
|
||||
"unicode/utf8"
|
||||
|
||||
const (
|
||||
_MaxBuffer = 1024 // 1KB buffer size
|
||||
"github.com/bytedance/sonic/internal/rt"
|
||||
"github.com/bytedance/sonic/option"
|
||||
)
|
||||
|
||||
func quoteString(e *[]byte, s string) {
|
||||
|
|
@ -30,7 +29,7 @@ func quoteString(e *[]byte, s string) {
|
|||
start := 0
|
||||
for i := 0; i < len(s); {
|
||||
if b := s[i]; b < utf8.RuneSelf {
|
||||
if safeSet[b] {
|
||||
if rt.SafeSet[b] {
|
||||
i++
|
||||
continue
|
||||
}
|
||||
|
|
@ -54,8 +53,8 @@ func quoteString(e *[]byte, s string) {
|
|||
// user-controlled strings are rendered into JSON
|
||||
// and served to some browsers.
|
||||
*e = append(*e, `u00`...)
|
||||
*e = append(*e, hex[b>>4])
|
||||
*e = append(*e, hex[b&0xF])
|
||||
*e = append(*e, rt.Hex[b>>4])
|
||||
*e = append(*e, rt.Hex[b&0xF])
|
||||
}
|
||||
i++
|
||||
start = i
|
||||
|
|
@ -76,7 +75,7 @@ func quoteString(e *[]byte, s string) {
|
|||
*e = append(*e, s[start:i]...)
|
||||
}
|
||||
*e = append(*e, `\u202`...)
|
||||
*e = append(*e, hex[c&0xF])
|
||||
*e = append(*e, rt.Hex[c&0xF])
|
||||
i += size
|
||||
start = i
|
||||
continue
|
||||
|
|
@ -92,16 +91,24 @@ func quoteString(e *[]byte, s string) {
|
|||
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
|
||||
}
|
||||
|
||||
ret := make([]byte, len(*buf))
|
||||
copy(ret, *buf)
|
||||
freeBuffer(buf)
|
||||
var ret []byte
|
||||
if !rt.CanSizeResue(cap(*buf)) {
|
||||
ret = *buf
|
||||
} else {
|
||||
ret = make([]byte, len(*buf))
|
||||
copy(ret, *buf)
|
||||
freeBuffer(buf)
|
||||
}
|
||||
return ret, err
|
||||
}
|
||||
|
||||
|
|
@ -109,21 +116,24 @@ func newBuffer() *[]byte {
|
|||
if ret := bytesPool.Get(); ret != nil {
|
||||
return ret.(*[]byte)
|
||||
} else {
|
||||
buf := make([]byte, 0, _MaxBuffer)
|
||||
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() {
|
||||
if self.isRaw() {
|
||||
return self.encodeRaw(buf)
|
||||
}
|
||||
switch self.Type() {
|
||||
switch int(self.itype()) {
|
||||
case V_NONE : return ErrNotExist
|
||||
case V_ERROR : return self.Check()
|
||||
case V_NULL : return self.encodeNull(buf)
|
||||
|
|
@ -139,16 +149,21 @@ func (self *Node) encode(buf *[]byte) error {
|
|||
}
|
||||
|
||||
func (self *Node) encodeRaw(buf *[]byte) error {
|
||||
raw, err := self.Raw()
|
||||
if err != nil {
|
||||
return err
|
||||
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, bytesNull...)
|
||||
*buf = append(*buf, strNull...)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
6
vendor/github.com/bytedance/sonic/ast/error.go
generated
vendored
6
vendor/github.com/bytedance/sonic/ast/error.go
generated
vendored
|
|
@ -17,6 +17,10 @@ func newError(err types.ParsingError, msg string) *Node {
|
|||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
|
|
@ -79,7 +83,7 @@ func (self SyntaxError) description() string {
|
|||
|
||||
/* check for empty source */
|
||||
if self.Src == "" {
|
||||
return fmt.Sprintf("no sources available: %#v", self)
|
||||
return fmt.Sprintf("no sources available, the input json is empty: %#v", self)
|
||||
}
|
||||
|
||||
/* prevent slicing before the beginning */
|
||||
|
|
|
|||
21
vendor/github.com/bytedance/sonic/ast/iterator.go
generated
vendored
21
vendor/github.com/bytedance/sonic/ast/iterator.go
generated
vendored
|
|
@ -17,19 +17,29 @@
|
|||
package ast
|
||||
|
||||
import (
|
||||
`fmt`
|
||||
"fmt"
|
||||
|
||||
`github.com/bytedance/sonic/internal/native/types`
|
||||
"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, "an array"); err != nil {
|
||||
if err := self.should(types.V_ARRAY); err != nil {
|
||||
return ListIterator{}, err
|
||||
}
|
||||
return self.values(), nil
|
||||
|
|
@ -41,7 +51,7 @@ func (self *Node) values() ListIterator {
|
|||
|
||||
// Properties returns iterator for object's children traversal
|
||||
func (self *Node) Properties() (ObjectIterator, error) {
|
||||
if err := self.should(types.V_OBJECT, "an object"); err != nil {
|
||||
if err := self.should(types.V_OBJECT); err != nil {
|
||||
return ObjectIterator{}, err
|
||||
}
|
||||
return self.properties(), nil
|
||||
|
|
@ -168,6 +178,9 @@ type Scanner func(path Sequence, node *Node) bool
|
|||
//
|
||||
// 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()
|
||||
|
|
|
|||
303
vendor/github.com/bytedance/sonic/ast/node.go
generated
vendored
303
vendor/github.com/bytedance/sonic/ast/node.go
generated
vendored
|
|
@ -17,13 +17,15 @@
|
|||
package ast
|
||||
|
||||
import (
|
||||
`encoding/json`
|
||||
`fmt`
|
||||
`strconv`
|
||||
`unsafe`
|
||||
|
||||
`github.com/bytedance/sonic/internal/native/types`
|
||||
`github.com/bytedance/sonic/internal/rt`
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"unsafe"
|
||||
|
||||
"github.com/bytedance/sonic/internal/native/types"
|
||||
"github.com/bytedance/sonic/internal/rt"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -36,7 +38,7 @@ const (
|
|||
_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
|
||||
_MASK_RAW = _V_RAW - 1
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -56,6 +58,7 @@ type Node struct {
|
|||
t types.ValueType
|
||||
l uint
|
||||
p unsafe.Pointer
|
||||
m *sync.RWMutex
|
||||
}
|
||||
|
||||
// UnmarshalJSON is just an adapter to json.Unmarshaler.
|
||||
|
|
@ -79,17 +82,39 @@ func (self *Node) UnmarshalJSON(data []byte) (err error) {
|
|||
// 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)
|
||||
}
|
||||
|
||||
func (self Node) itype() types.ValueType {
|
||||
// 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 {
|
||||
return self.Valid() && self.t != _V_NONE
|
||||
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
|
||||
|
|
@ -97,7 +122,7 @@ func (self *Node) Valid() bool {
|
|||
if self == nil {
|
||||
return false
|
||||
}
|
||||
return self.t != V_ERROR
|
||||
return self.loadt() != V_ERROR
|
||||
}
|
||||
|
||||
// Check checks if the node itself is valid, and return:
|
||||
|
|
@ -106,24 +131,31 @@ func (self *Node) Valid() bool {
|
|||
func (self *Node) Check() error {
|
||||
if self == nil {
|
||||
return ErrNotExist
|
||||
} else if self.t != V_ERROR {
|
||||
} else if self.loadt() != V_ERROR {
|
||||
return nil
|
||||
} else {
|
||||
return self
|
||||
}
|
||||
}
|
||||
|
||||
// IsRaw returns true if node's underlying value is raw json
|
||||
// isRaw returns true if node's underlying value is raw json
|
||||
//
|
||||
// Deprecated: not concurent safe
|
||||
func (self Node) IsRaw() bool {
|
||||
return self.t&_V_RAW != 0
|
||||
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
|
||||
return self != nil && self.t & _V_LAZY != 0
|
||||
}
|
||||
|
||||
func (self *Node) isAny() bool {
|
||||
return self != nil && self.t == _V_ANY
|
||||
return self != nil && self.loadt() == _V_ANY
|
||||
}
|
||||
|
||||
/** Simple Value Methods **/
|
||||
|
|
@ -133,18 +165,26 @@ func (self *Node) Raw() (string, error) {
|
|||
if self == nil {
|
||||
return "", ErrNotExist
|
||||
}
|
||||
if !self.IsRaw() {
|
||||
lock := self.rlock()
|
||||
if !self.isRaw() {
|
||||
if lock {
|
||||
self.runlock()
|
||||
}
|
||||
buf, err := self.MarshalJSON()
|
||||
return rt.Mem2Str(buf), err
|
||||
}
|
||||
return self.toString(), nil
|
||||
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() {
|
||||
if self.isRaw() {
|
||||
self.parseRaw(false)
|
||||
}
|
||||
return self.Check()
|
||||
|
|
@ -504,7 +544,7 @@ func (self *Node) Len() (int, error) {
|
|||
}
|
||||
}
|
||||
|
||||
func (self Node) len() int {
|
||||
func (self *Node) len() int {
|
||||
return int(self.l)
|
||||
}
|
||||
|
||||
|
|
@ -527,7 +567,7 @@ func (self *Node) Cap() (int, error) {
|
|||
//
|
||||
// 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.Check(); err != nil {
|
||||
if err := self.checkRaw(); err != nil {
|
||||
return false, err
|
||||
}
|
||||
if err := node.Check(); err != nil {
|
||||
|
|
@ -535,7 +575,7 @@ func (self *Node) Set(key string, node Node) (bool, error) {
|
|||
}
|
||||
|
||||
if self.t == _V_NONE || self.t == types.V_NULL {
|
||||
*self = NewObject([]Pair{{key, node}})
|
||||
*self = NewObject([]Pair{NewPair(key, node)})
|
||||
return false, nil
|
||||
} else if self.itype() != types.V_OBJECT {
|
||||
return false, ErrUnsupportType
|
||||
|
|
@ -549,7 +589,7 @@ func (self *Node) Set(key string, node Node) (bool, error) {
|
|||
*self = newObject(new(linkedPairs))
|
||||
}
|
||||
s := (*linkedPairs)(self.p)
|
||||
s.Push(Pair{key, node})
|
||||
s.Push(NewPair(key, node))
|
||||
self.l++
|
||||
return false, nil
|
||||
|
||||
|
|
@ -568,7 +608,7 @@ func (self *Node) SetAny(key string, val interface{}) (bool, error) {
|
|||
|
||||
// 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, "an object"); err != nil {
|
||||
if err := self.should(types.V_OBJECT); err != nil {
|
||||
return false, err
|
||||
}
|
||||
// NOTICE: must get acurate length before deduct
|
||||
|
|
@ -589,7 +629,7 @@ func (self *Node) Unset(key string) (bool, error) {
|
|||
//
|
||||
// The index must be within self's children.
|
||||
func (self *Node) SetByIndex(index int, node Node) (bool, error) {
|
||||
if err := self.Check(); err != nil {
|
||||
if err := self.checkRaw(); err != nil {
|
||||
return false, err
|
||||
}
|
||||
if err := node.Check(); err != nil {
|
||||
|
|
@ -669,7 +709,7 @@ func (self *Node) UnsetByIndex(index int) (bool, error) {
|
|||
//
|
||||
// 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.Check(); err != nil {
|
||||
if err := self.checkRaw(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -677,7 +717,7 @@ func (self *Node) Add(node Node) error {
|
|||
*self = NewArray([]Node{node})
|
||||
return nil
|
||||
}
|
||||
if err := self.should(types.V_ARRAY, "an array"); err != nil {
|
||||
if err := self.should(types.V_ARRAY); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -740,7 +780,7 @@ func (self *Node) Pop() error {
|
|||
//
|
||||
// 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, "an array"); err != nil {
|
||||
if err := self.should(types.V_ARRAY); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -812,7 +852,7 @@ func (self *Node) GetByPath(path ...interface{}) *Node {
|
|||
|
||||
// Get loads given key of an object node on demands
|
||||
func (self *Node) Get(key string) *Node {
|
||||
if err := self.should(types.V_OBJECT, "an object"); err != nil {
|
||||
if err := self.should(types.V_OBJECT); err != nil {
|
||||
return unwrapError(err)
|
||||
}
|
||||
n, _ := self.skipKey(key)
|
||||
|
|
@ -845,14 +885,14 @@ func (self *Node) Index(idx int) *Node {
|
|||
// 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, "an object"); err != nil {
|
||||
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, "an object"); err != nil {
|
||||
if err := self.should(types.V_OBJECT); err != nil {
|
||||
return unwrapError(err), idx
|
||||
}
|
||||
|
||||
|
|
@ -889,10 +929,10 @@ func (self *Node) Map() (map[string]interface{}, error) {
|
|||
return nil, ErrUnsupportType
|
||||
}
|
||||
}
|
||||
if err := self.should(types.V_OBJECT, "an object"); err != nil {
|
||||
if err := self.should(types.V_OBJECT); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := self.loadAllKey(); err != nil {
|
||||
if err := self.loadAllKey(false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return self.toGenericObject()
|
||||
|
|
@ -908,10 +948,10 @@ func (self *Node) MapUseNumber() (map[string]interface{}, error) {
|
|||
return nil, ErrUnsupportType
|
||||
}
|
||||
}
|
||||
if err := self.should(types.V_OBJECT, "an object"); err != nil {
|
||||
if err := self.should(types.V_OBJECT); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := self.loadAllKey(); err != nil {
|
||||
if err := self.loadAllKey(false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return self.toGenericObjectUseNumber()
|
||||
|
|
@ -928,7 +968,7 @@ func (self *Node) MapUseNode() (map[string]Node, error) {
|
|||
return nil, ErrUnsupportType
|
||||
}
|
||||
}
|
||||
if err := self.should(types.V_OBJECT, "an object"); err != nil {
|
||||
if err := self.should(types.V_OBJECT); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := self.skipAllKey(); err != nil {
|
||||
|
|
@ -1034,10 +1074,10 @@ func (self *Node) Array() ([]interface{}, error) {
|
|||
return nil, ErrUnsupportType
|
||||
}
|
||||
}
|
||||
if err := self.should(types.V_ARRAY, "an array"); err != nil {
|
||||
if err := self.should(types.V_ARRAY); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := self.loadAllIndex(); err != nil {
|
||||
if err := self.loadAllIndex(false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return self.toGenericArray()
|
||||
|
|
@ -1053,10 +1093,10 @@ func (self *Node) ArrayUseNumber() ([]interface{}, error) {
|
|||
return nil, ErrUnsupportType
|
||||
}
|
||||
}
|
||||
if err := self.should(types.V_ARRAY, "an array"); err != nil {
|
||||
if err := self.should(types.V_ARRAY); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := self.loadAllIndex(); err != nil {
|
||||
if err := self.loadAllIndex(false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return self.toGenericArrayUseNumber()
|
||||
|
|
@ -1073,7 +1113,7 @@ func (self *Node) ArrayUseNode() ([]Node, error) {
|
|||
return nil, ErrUnsupportType
|
||||
}
|
||||
}
|
||||
if err := self.should(types.V_ARRAY, "an array"); err != nil {
|
||||
if err := self.should(types.V_ARRAY); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := self.skipAllIndex(); err != nil {
|
||||
|
|
@ -1129,12 +1169,12 @@ func (self *Node) Interface() (interface{}, error) {
|
|||
}
|
||||
return v, nil
|
||||
case _V_ARRAY_LAZY :
|
||||
if err := self.loadAllIndex(); err != nil {
|
||||
if err := self.loadAllIndex(false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return self.toGenericArray()
|
||||
case _V_OBJECT_LAZY :
|
||||
if err := self.loadAllKey(); err != nil {
|
||||
if err := self.loadAllKey(false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return self.toGenericObject()
|
||||
|
|
@ -1168,12 +1208,12 @@ func (self *Node) InterfaceUseNumber() (interface{}, error) {
|
|||
case types.V_STRING : return self.toString(), nil
|
||||
case _V_NUMBER : return self.toNumber(), nil
|
||||
case _V_ARRAY_LAZY :
|
||||
if err := self.loadAllIndex(); err != nil {
|
||||
if err := self.loadAllIndex(false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return self.toGenericArrayUseNumber()
|
||||
case _V_OBJECT_LAZY :
|
||||
if err := self.loadAllKey(); err != nil {
|
||||
if err := self.loadAllKey(false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return self.toGenericObjectUseNumber()
|
||||
|
|
@ -1205,70 +1245,30 @@ func (self *Node) InterfaceUseNode() (interface{}, error) {
|
|||
}
|
||||
}
|
||||
|
||||
// LoadAll loads all the node's children and children's children as parsed.
|
||||
// After calling it, the node can be safely used on concurrency
|
||||
// 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 {
|
||||
if self.IsRaw() {
|
||||
self.parseRaw(true)
|
||||
return self.Check()
|
||||
}
|
||||
|
||||
switch self.itype() {
|
||||
case types.V_ARRAY:
|
||||
e := self.len()
|
||||
if err := self.loadAllIndex(); err != nil {
|
||||
return err
|
||||
}
|
||||
for i := 0; i < e; i++ {
|
||||
n := self.nodeAt(i)
|
||||
if n.IsRaw() {
|
||||
n.parseRaw(true)
|
||||
}
|
||||
if err := n.Check(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
case types.V_OBJECT:
|
||||
e := self.len()
|
||||
if err := self.loadAllKey(); err != nil {
|
||||
return err
|
||||
}
|
||||
for i := 0; i < e; i++ {
|
||||
n := self.pairAt(i)
|
||||
if n.Value.IsRaw() {
|
||||
n.Value.parseRaw(true)
|
||||
}
|
||||
if err := n.Value.Check(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
return self.Check()
|
||||
}
|
||||
return self.Load()
|
||||
}
|
||||
|
||||
// Load loads the node's children as parsed.
|
||||
// After calling it, only the node itself can be used on concurrency (not include its children)
|
||||
// and ensure all its children can be READ concurrently (include its children's children)
|
||||
func (self *Node) Load() error {
|
||||
if err := self.checkRaw(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch self.t {
|
||||
case _V_ARRAY_LAZY:
|
||||
return self.skipAllIndex()
|
||||
case _V_OBJECT_LAZY:
|
||||
return self.skipAllKey()
|
||||
default:
|
||||
return self.Check()
|
||||
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, s string) error {
|
||||
func (self *Node) should(t types.ValueType) error {
|
||||
if err := self.checkRaw(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -1439,13 +1439,17 @@ func (self *Node) skipIndexPair(index int) *Pair {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (self *Node) loadAllIndex() error {
|
||||
func (self *Node) loadAllIndex(loadOnce bool) error {
|
||||
if !self.isLazy() {
|
||||
return nil
|
||||
}
|
||||
var err types.ParsingError
|
||||
parser, stack := self.getParserAndArrayStack()
|
||||
parser.noLazy = true
|
||||
if !loadOnce {
|
||||
parser.noLazy = true
|
||||
} else {
|
||||
parser.loadOnce = true
|
||||
}
|
||||
*self, err = parser.decodeArray(&stack.v)
|
||||
if err != 0 {
|
||||
return parser.ExportError(err)
|
||||
|
|
@ -1453,14 +1457,19 @@ func (self *Node) loadAllIndex() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (self *Node) loadAllKey() error {
|
||||
func (self *Node) loadAllKey(loadOnce bool) error {
|
||||
if !self.isLazy() {
|
||||
return nil
|
||||
}
|
||||
var err types.ParsingError
|
||||
parser, stack := self.getParserAndObjectStack()
|
||||
parser.noLazy = true
|
||||
*self, err = parser.decodeObject(&stack.v)
|
||||
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)
|
||||
}
|
||||
|
|
@ -1629,7 +1638,23 @@ func NewRaw(json string) Node {
|
|||
if it == _V_NONE {
|
||||
return Node{}
|
||||
}
|
||||
return newRawNode(parser.s[start:parser.p], it)
|
||||
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,
|
||||
|
|
@ -1653,7 +1678,7 @@ func NewBytes(src []byte) Node {
|
|||
if len(src) == 0 {
|
||||
panic("empty src bytes")
|
||||
}
|
||||
out := encodeBase64(src)
|
||||
out := rt.EncodeBase64(src)
|
||||
return NewString(out)
|
||||
}
|
||||
|
||||
|
|
@ -1689,15 +1714,15 @@ func NewNumber(v string) Node {
|
|||
}
|
||||
}
|
||||
|
||||
func (node Node) toNumber() json.Number {
|
||||
func (node *Node) toNumber() json.Number {
|
||||
return json.Number(rt.StrFrom(node.p, int64(node.l)))
|
||||
}
|
||||
|
||||
func (self Node) toString() string {
|
||||
func (self *Node) toString() string {
|
||||
return rt.StrFrom(self.p, int64(self.l))
|
||||
}
|
||||
|
||||
func (node Node) toFloat64() (float64, error) {
|
||||
func (node *Node) toFloat64() (float64, error) {
|
||||
ret, err := node.toNumber().Float64()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
|
|
@ -1705,7 +1730,7 @@ func (node Node) toFloat64() (float64, error) {
|
|||
return ret, nil
|
||||
}
|
||||
|
||||
func (node Node) toInt64() (int64, error) {
|
||||
func (node *Node) toInt64() (int64, error) {
|
||||
ret,err := node.toNumber().Int64()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
|
|
@ -1741,6 +1766,8 @@ func NewArray(v []Node) Node {
|
|||
return newArray(s)
|
||||
}
|
||||
|
||||
const _Threshold_Index = 16
|
||||
|
||||
func newArray(v *linkedNodes) Node {
|
||||
return Node{
|
||||
t: types.V_ARRAY,
|
||||
|
|
@ -1764,6 +1791,9 @@ func NewObject(v []Pair) Node {
|
|||
}
|
||||
|
||||
func newObject(v *linkedPairs) Node {
|
||||
if v.size > _Threshold_Index {
|
||||
v.BuildIndex()
|
||||
}
|
||||
return Node{
|
||||
t: types.V_OBJECT,
|
||||
l: uint(v.Len()),
|
||||
|
|
@ -1772,53 +1802,42 @@ func newObject(v *linkedPairs) Node {
|
|||
}
|
||||
|
||||
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 newRawNode(str string, typ types.ValueType) Node {
|
||||
return Node{
|
||||
t: _V_RAW | typ,
|
||||
p: rt.StrPtr(str),
|
||||
l: uint(len(str)),
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
parser.skipValue = false
|
||||
*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()
|
||||
}
|
||||
var e types.ParsingError
|
||||
*self, e = parser.Parse()
|
||||
if e != 0 {
|
||||
*self = *newSyntaxError(parser.syntaxError(e))
|
||||
}
|
||||
}
|
||||
|
||||
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) assign(n Node) {
|
||||
self.l = n.l
|
||||
self.p = n.p
|
||||
atomic.StoreInt64(&self.t, n.t)
|
||||
}
|
||||
|
|
|
|||
142
vendor/github.com/bytedance/sonic/ast/parser.go
generated
vendored
142
vendor/github.com/bytedance/sonic/ast/parser.go
generated
vendored
|
|
@ -17,14 +17,16 @@
|
|||
package ast
|
||||
|
||||
import (
|
||||
`fmt`
|
||||
"fmt"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
`github.com/bytedance/sonic/internal/native/types`
|
||||
`github.com/bytedance/sonic/internal/rt`
|
||||
"github.com/bytedance/sonic/internal/native/types"
|
||||
"github.com/bytedance/sonic/internal/rt"
|
||||
)
|
||||
|
||||
const (
|
||||
_DEFAULT_NODE_CAP int = 8
|
||||
_DEFAULT_NODE_CAP int = 16
|
||||
_APPEND_GROW_SHIFT = 1
|
||||
)
|
||||
|
||||
|
|
@ -45,6 +47,7 @@ type Parser struct {
|
|||
p int
|
||||
s string
|
||||
noLazy bool
|
||||
loadOnce bool
|
||||
skipValue bool
|
||||
dbuf *byte
|
||||
}
|
||||
|
|
@ -115,6 +118,10 @@ func (self *Parser) lspace(sp int) int {
|
|||
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)
|
||||
|
|
@ -148,7 +155,7 @@ func (self *Parser) decodeArray(ret *linkedNodes) (Node, types.ParsingError) {
|
|||
if t == _V_NONE {
|
||||
return Node{}, types.ERR_INVALID_CHAR
|
||||
}
|
||||
val = newRawNode(self.s[start:self.p], t)
|
||||
val = newRawNode(self.s[start:self.p], t, false)
|
||||
}else{
|
||||
/* decode the value */
|
||||
if val, err = self.Parse(); err != 0 {
|
||||
|
|
@ -234,7 +241,7 @@ func (self *Parser) decodeObject(ret *linkedPairs) (Node, types.ParsingError) {
|
|||
if t == _V_NONE {
|
||||
return Node{}, types.ERR_INVALID_CHAR
|
||||
}
|
||||
val = newRawNode(self.s[start:self.p], t)
|
||||
val = newRawNode(self.s[start:self.p], t, false)
|
||||
} else {
|
||||
/* decode the value */
|
||||
if val, err = self.Parse(); err != 0 {
|
||||
|
|
@ -244,7 +251,7 @@ func (self *Parser) decodeObject(ret *linkedPairs) (Node, types.ParsingError) {
|
|||
|
||||
/* add the value to result */
|
||||
// FIXME: ret's address may change here, thus previous referred node in ret may be invalid !!
|
||||
ret.Push(Pair{Key: key, Value: val})
|
||||
ret.Push(NewPair(key, val))
|
||||
self.p = self.lspace(self.p)
|
||||
|
||||
/* check for EOF */
|
||||
|
|
@ -291,6 +298,10 @@ 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
|
||||
|
|
@ -299,22 +310,48 @@ func (self *Parser) Parse() (Node, types.ParsingError) {
|
|||
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
|
||||
|
|
@ -471,7 +508,7 @@ func (self *Node) skipNextNode() *Node {
|
|||
if t == _V_NONE {
|
||||
return newSyntaxError(parser.syntaxError(types.ERR_INVALID_CHAR))
|
||||
}
|
||||
val = newRawNode(parser.s[start:parser.p], t)
|
||||
val = newRawNode(parser.s[start:parser.p], t, false)
|
||||
}
|
||||
|
||||
/* add the value to result */
|
||||
|
|
@ -510,7 +547,7 @@ func (self *Node) skipNextPair() (*Pair) {
|
|||
|
||||
/* check for EOF */
|
||||
if parser.p = parser.lspace(sp); parser.p >= ns {
|
||||
return &Pair{"", *newSyntaxError(parser.syntaxError(types.ERR_EOF))}
|
||||
return newErrorPair(parser.syntaxError(types.ERR_EOF))
|
||||
}
|
||||
|
||||
/* check for empty object */
|
||||
|
|
@ -527,7 +564,7 @@ func (self *Node) skipNextPair() (*Pair) {
|
|||
|
||||
/* decode the key */
|
||||
if njs = parser.decodeValue(); njs.Vt != types.V_STRING {
|
||||
return &Pair{"", *newSyntaxError(parser.syntaxError(types.ERR_INVALID_CHAR))}
|
||||
return newErrorPair(parser.syntaxError(types.ERR_INVALID_CHAR))
|
||||
}
|
||||
|
||||
/* extract the key */
|
||||
|
|
@ -537,34 +574,34 @@ func (self *Node) skipNextPair() (*Pair) {
|
|||
/* check for escape sequence */
|
||||
if njs.Ep != -1 {
|
||||
if key, err = unquote(key); err != 0 {
|
||||
return &Pair{key, *newSyntaxError(parser.syntaxError(err))}
|
||||
return newErrorPair(parser.syntaxError(err))
|
||||
}
|
||||
}
|
||||
|
||||
/* expect a ':' delimiter */
|
||||
if err = parser.delim(); err != 0 {
|
||||
return &Pair{key, *newSyntaxError(parser.syntaxError(err))}
|
||||
return newErrorPair(parser.syntaxError(err))
|
||||
}
|
||||
|
||||
/* skip the value */
|
||||
if start, err := parser.skipFast(); err != 0 {
|
||||
return &Pair{key, *newSyntaxError(parser.syntaxError(err))}
|
||||
return newErrorPair(parser.syntaxError(err))
|
||||
} else {
|
||||
t := switchRawType(parser.s[start])
|
||||
if t == _V_NONE {
|
||||
return &Pair{key, *newSyntaxError(parser.syntaxError(types.ERR_INVALID_CHAR))}
|
||||
return newErrorPair(parser.syntaxError(types.ERR_INVALID_CHAR))
|
||||
}
|
||||
val = newRawNode(parser.s[start:parser.p], t)
|
||||
val = newRawNode(parser.s[start:parser.p], t, false)
|
||||
}
|
||||
|
||||
/* add the value to result */
|
||||
ret.Push(Pair{Key: key, Value: val})
|
||||
ret.Push(NewPair(key, val))
|
||||
self.l++
|
||||
parser.p = parser.lspace(parser.p)
|
||||
|
||||
/* check for EOF */
|
||||
if parser.p >= ns {
|
||||
return &Pair{key, *newSyntaxError(parser.syntaxError(types.ERR_EOF))}
|
||||
return newErrorPair(parser.syntaxError(types.ERR_EOF))
|
||||
}
|
||||
|
||||
/* check for the next character */
|
||||
|
|
@ -577,7 +614,7 @@ func (self *Node) skipNextPair() (*Pair) {
|
|||
self.setObject(ret)
|
||||
return ret.At(ret.Len()-1)
|
||||
default:
|
||||
return &Pair{key, *newSyntaxError(parser.syntaxError(types.ERR_INVALID_CHAR))}
|
||||
return newErrorPair(parser.syntaxError(types.ERR_INVALID_CHAR))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -658,3 +695,72 @@ 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()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
31
vendor/github.com/bytedance/sonic/ast/search.go
generated
vendored
31
vendor/github.com/bytedance/sonic/ast/search.go
generated
vendored
|
|
@ -21,8 +21,23 @@ import (
|
|||
`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 {
|
||||
|
|
@ -31,12 +46,16 @@ func NewSearcher(str string) *Searcher {
|
|||
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) {
|
||||
return self.getByPath(true, true, path...)
|
||||
self.CopyReturn = true
|
||||
return self.getByPath(path...)
|
||||
}
|
||||
|
||||
// GetByPathNoCopy search in depth from top json and returns a **Referenced** json node at the path location
|
||||
|
|
@ -44,15 +63,15 @@ func (self *Searcher) GetByPathCopy(path ...interface{}) (Node, error) {
|
|||
// 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(false, true, path...)
|
||||
return self.getByPath(path...)
|
||||
}
|
||||
|
||||
func (self *Searcher) getByPath(copystring bool, validate bool, path ...interface{}) (Node, error) {
|
||||
func (self *Searcher) getByPath(path ...interface{}) (Node, error) {
|
||||
var err types.ParsingError
|
||||
var start int
|
||||
|
||||
self.parser.p = 0
|
||||
start, err = self.parser.getByPath(validate, path...)
|
||||
start, err = self.parser.getByPath(self.ValidateJSON, path...)
|
||||
if err != 0 {
|
||||
// for compatibility with old version
|
||||
if err == types.ERR_NOT_FOUND {
|
||||
|
|
@ -71,12 +90,12 @@ func (self *Searcher) getByPath(copystring bool, validate bool, path ...interfac
|
|||
|
||||
// copy string to reducing memory usage
|
||||
var raw string
|
||||
if copystring {
|
||||
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), nil
|
||||
return newRawNode(raw, t, self.ConcurrentRead), nil
|
||||
}
|
||||
|
||||
// GetByPath searches a path and returns relaction and types of target
|
||||
|
|
|
|||
142
vendor/github.com/bytedance/sonic/ast/stubs.go
generated
vendored
Normal file
142
vendor/github.com/bytedance/sonic/ast/stubs.go
generated
vendored
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* 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)
|
||||
55
vendor/github.com/bytedance/sonic/ast/stubs_go115.go
generated
vendored
55
vendor/github.com/bytedance/sonic/ast/stubs_go115.go
generated
vendored
|
|
@ -1,55 +0,0 @@
|
|||
// +build !go1.20
|
||||
|
||||
/*
|
||||
* 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 (
|
||||
`unsafe`
|
||||
`unicode/utf8`
|
||||
|
||||
`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:linkname growslice runtime.growslice
|
||||
//goland:noinspection GoUnusedParameter
|
||||
func growslice(et *rt.GoType, old rt.GoSlice, cap int) rt.GoSlice
|
||||
|
||||
//go:nosplit
|
||||
func mem2ptr(s []byte) unsafe.Pointer {
|
||||
return (*rt.GoSlice)(unsafe.Pointer(&s)).Ptr
|
||||
}
|
||||
|
||||
var (
|
||||
//go:linkname safeSet encoding/json.safeSet
|
||||
safeSet [utf8.RuneSelf]bool
|
||||
|
||||
//go:linkname hex encoding/json.hex
|
||||
hex string
|
||||
)
|
||||
|
||||
//go:linkname unquoteBytes encoding/json.unquoteBytes
|
||||
func unquoteBytes(s []byte) (t []byte, ok bool)
|
||||
55
vendor/github.com/bytedance/sonic/ast/stubs_go120.go
generated
vendored
55
vendor/github.com/bytedance/sonic/ast/stubs_go120.go
generated
vendored
|
|
@ -1,55 +0,0 @@
|
|||
// +build go1.20
|
||||
|
||||
/*
|
||||
* 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 (
|
||||
`unsafe`
|
||||
`unicode/utf8`
|
||||
|
||||
`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:linkname growslice reflect.growslice
|
||||
//goland:noinspection GoUnusedParameter
|
||||
func growslice(et *rt.GoType, old rt.GoSlice, cap int) rt.GoSlice
|
||||
|
||||
//go:nosplit
|
||||
func mem2ptr(s []byte) unsafe.Pointer {
|
||||
return (*rt.GoSlice)(unsafe.Pointer(&s)).Ptr
|
||||
}
|
||||
|
||||
var (
|
||||
//go:linkname safeSet encoding/json.safeSet
|
||||
safeSet [utf8.RuneSelf]bool
|
||||
|
||||
//go:linkname hex encoding/json.hex
|
||||
hex string
|
||||
)
|
||||
|
||||
//go:linkname unquoteBytes encoding/json.unquoteBytes
|
||||
func unquoteBytes(s []byte) (t []byte, ok bool)
|
||||
45
vendor/github.com/bytedance/sonic/ast/visitor.go
generated
vendored
45
vendor/github.com/bytedance/sonic/ast/visitor.go
generated
vendored
|
|
@ -18,6 +18,7 @@ package ast
|
|||
|
||||
import (
|
||||
`encoding/json`
|
||||
`errors`
|
||||
|
||||
`github.com/bytedance/sonic/internal/native/types`
|
||||
)
|
||||
|
|
@ -174,6 +175,19 @@ 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 {
|
||||
|
|
@ -183,16 +197,9 @@ func (self *traverser) decodeArray() error {
|
|||
/* check for empty array */
|
||||
if self.parser.s[self.parser.p] == ']' {
|
||||
self.parser.p++
|
||||
if err := self.visitor.OnArrayBegin(0); err != nil {
|
||||
return err
|
||||
}
|
||||
return self.visitor.OnArrayEnd()
|
||||
}
|
||||
|
||||
/* allocate array space and parse every element */
|
||||
if err := self.visitor.OnArrayBegin(_DEFAULT_NODE_CAP); err != nil {
|
||||
return err
|
||||
}
|
||||
for {
|
||||
/* decode the value */
|
||||
if err := self.decodeValue(); err != nil {
|
||||
|
|
@ -223,6 +230,19 @@ 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 {
|
||||
|
|
@ -232,16 +252,9 @@ func (self *traverser) decodeObject() error {
|
|||
/* check for empty object */
|
||||
if self.parser.s[self.parser.p] == '}' {
|
||||
self.parser.p++
|
||||
if err := self.visitor.OnObjectBegin(0); err != nil {
|
||||
return err
|
||||
}
|
||||
return self.visitor.OnObjectEnd()
|
||||
}
|
||||
|
||||
/* allocate object space and decode each pair */
|
||||
if err := self.visitor.OnObjectBegin(_DEFAULT_NODE_CAP); err != nil {
|
||||
return err
|
||||
}
|
||||
for {
|
||||
var njs types.JsonState
|
||||
var err types.ParsingError
|
||||
|
|
@ -313,3 +326,7 @@ func (self *traverser) decodeString(iv int64, ep int) error {
|
|||
}
|
||||
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("")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue