mirror of
https://github.com/superseriousbusiness/gotosocial
synced 2025-06-05 21:59:39 +02: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:
206
vendor/github.com/bytedance/sonic/internal/encoder/alg/mapiter.go
generated
vendored
Normal file
206
vendor/github.com/bytedance/sonic/internal/encoder/alg/mapiter.go
generated
vendored
Normal file
@ -0,0 +1,206 @@
|
||||
/*
|
||||
* 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 alg
|
||||
|
||||
import (
|
||||
"encoding"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"sync"
|
||||
"unsafe"
|
||||
|
||||
"github.com/bytedance/sonic/internal/encoder/vars"
|
||||
"github.com/bytedance/sonic/internal/rt"
|
||||
)
|
||||
|
||||
type _MapPair struct {
|
||||
k string // when the map key is integer, k is pointed to m
|
||||
v unsafe.Pointer
|
||||
m [32]byte
|
||||
}
|
||||
|
||||
type MapIterator struct {
|
||||
It rt.GoMapIterator // must be the first field
|
||||
kv rt.GoSlice // slice of _MapPair
|
||||
ki int
|
||||
}
|
||||
|
||||
var (
|
||||
iteratorPool = sync.Pool{}
|
||||
iteratorPair = rt.UnpackType(reflect.TypeOf(_MapPair{}))
|
||||
)
|
||||
|
||||
func init() {
|
||||
if unsafe.Offsetof(MapIterator{}.It) != 0 {
|
||||
panic("_MapIterator.it is not the first field")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func newIterator() *MapIterator {
|
||||
if v := iteratorPool.Get(); v == nil {
|
||||
return new(MapIterator)
|
||||
} else {
|
||||
return resetIterator(v.(*MapIterator))
|
||||
}
|
||||
}
|
||||
|
||||
func resetIterator(p *MapIterator) *MapIterator {
|
||||
p.ki = 0
|
||||
p.It = rt.GoMapIterator{}
|
||||
p.kv.Len = 0
|
||||
return p
|
||||
}
|
||||
|
||||
func (self *MapIterator) at(i int) *_MapPair {
|
||||
return (*_MapPair)(unsafe.Pointer(uintptr(self.kv.Ptr) + uintptr(i) * unsafe.Sizeof(_MapPair{})))
|
||||
}
|
||||
|
||||
func (self *MapIterator) add() (p *_MapPair) {
|
||||
p = self.at(self.kv.Len)
|
||||
self.kv.Len++
|
||||
return
|
||||
}
|
||||
|
||||
func (self *MapIterator) data() (p []_MapPair) {
|
||||
*(*rt.GoSlice)(unsafe.Pointer(&p)) = self.kv
|
||||
return
|
||||
}
|
||||
|
||||
func (self *MapIterator) append(t *rt.GoType, k unsafe.Pointer, v unsafe.Pointer) (err error) {
|
||||
p := self.add()
|
||||
p.v = v
|
||||
|
||||
/* check for strings */
|
||||
if tk := t.Kind(); tk != reflect.String {
|
||||
return self.appendGeneric(p, t, tk, k)
|
||||
}
|
||||
|
||||
/* fast path for strings */
|
||||
p.k = *(*string)(k)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *MapIterator) appendGeneric(p *_MapPair, t *rt.GoType, v reflect.Kind, k unsafe.Pointer) error {
|
||||
switch v {
|
||||
case reflect.Int : p.k = rt.Mem2Str(strconv.AppendInt(p.m[:0], int64(*(*int)(k)), 10)) ; return nil
|
||||
case reflect.Int8 : p.k = rt.Mem2Str(strconv.AppendInt(p.m[:0], int64(*(*int8)(k)), 10)) ; return nil
|
||||
case reflect.Int16 : p.k = rt.Mem2Str(strconv.AppendInt(p.m[:0], int64(*(*int16)(k)), 10)) ; return nil
|
||||
case reflect.Int32 : p.k = rt.Mem2Str(strconv.AppendInt(p.m[:0], int64(*(*int32)(k)), 10)) ; return nil
|
||||
case reflect.Int64 : p.k = rt.Mem2Str(strconv.AppendInt(p.m[:0], int64(*(*int64)(k)), 10)) ; return nil
|
||||
case reflect.Uint : p.k = rt.Mem2Str(strconv.AppendUint(p.m[:0], uint64(*(*uint)(k)), 10)) ; return nil
|
||||
case reflect.Uint8 : p.k = rt.Mem2Str(strconv.AppendUint(p.m[:0], uint64(*(*uint8)(k)), 10)) ; return nil
|
||||
case reflect.Uint16 : p.k = rt.Mem2Str(strconv.AppendUint(p.m[:0], uint64(*(*uint16)(k)), 10)) ; return nil
|
||||
case reflect.Uint32 : p.k = rt.Mem2Str(strconv.AppendUint(p.m[:0], uint64(*(*uint32)(k)), 10)) ; return nil
|
||||
case reflect.Uint64 : p.k = rt.Mem2Str(strconv.AppendUint(p.m[:0], uint64(*(*uint64)(k)), 10)) ; return nil
|
||||
case reflect.Uintptr : p.k = rt.Mem2Str(strconv.AppendUint(p.m[:0], uint64(*(*uintptr)(k)), 10)) ; return nil
|
||||
case reflect.Interface : return self.appendInterface(p, t, k)
|
||||
case reflect.Struct, reflect.Ptr : return self.appendConcrete(p, t, k)
|
||||
default : panic("unexpected map key type")
|
||||
}
|
||||
}
|
||||
|
||||
func (self *MapIterator) appendConcrete(p *_MapPair, t *rt.GoType, k unsafe.Pointer) (err error) {
|
||||
// compiler has already checked that the type implements the encoding.MarshalText interface
|
||||
if !t.Indirect() {
|
||||
k = *(*unsafe.Pointer)(k)
|
||||
}
|
||||
eface := rt.GoEface{Value: k, Type: t}.Pack()
|
||||
out, err := eface.(encoding.TextMarshaler).MarshalText()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.k = rt.Mem2Str(out)
|
||||
return
|
||||
}
|
||||
|
||||
func (self *MapIterator) appendInterface(p *_MapPair, t *rt.GoType, k unsafe.Pointer) (err error) {
|
||||
if len(rt.IfaceType(t).Methods) == 0 {
|
||||
panic("unexpected map key type")
|
||||
} else if p.k, err = asText(k); err == nil {
|
||||
return nil
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func IteratorStop(p *MapIterator) {
|
||||
iteratorPool.Put(p)
|
||||
}
|
||||
|
||||
func IteratorNext(p *MapIterator) {
|
||||
i := p.ki
|
||||
t := &p.It
|
||||
|
||||
/* check for unordered iteration */
|
||||
if i < 0 {
|
||||
rt.Mapiternext(t)
|
||||
return
|
||||
}
|
||||
|
||||
/* check for end of iteration */
|
||||
if p.ki >= p.kv.Len {
|
||||
t.K = nil
|
||||
t.V = nil
|
||||
return
|
||||
}
|
||||
|
||||
/* update the key-value pair, and increase the pointer */
|
||||
t.K = unsafe.Pointer(&p.at(p.ki).k)
|
||||
t.V = p.at(p.ki).v
|
||||
p.ki++
|
||||
}
|
||||
|
||||
func IteratorStart(t *rt.GoMapType, m *rt.GoMap, fv uint64) (*MapIterator, error) {
|
||||
it := newIterator()
|
||||
rt.Mapiterinit(t, m, &it.It)
|
||||
|
||||
/* check for key-sorting, empty map don't need sorting */
|
||||
if m.Count == 0 || (fv & (1<<BitSortMapKeys)) == 0 {
|
||||
it.ki = -1
|
||||
return it, nil
|
||||
}
|
||||
|
||||
/* pre-allocate space if needed */
|
||||
if m.Count > it.kv.Cap {
|
||||
it.kv = rt.GrowSlice(iteratorPair, it.kv, m.Count)
|
||||
}
|
||||
|
||||
/* dump all the key-value pairs */
|
||||
for ; it.It.K != nil; rt.Mapiternext(&it.It) {
|
||||
if err := it.append(t.Key, it.It.K, it.It.V); err != nil {
|
||||
IteratorStop(it)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
/* sort the keys, map with only 1 item don't need sorting */
|
||||
if it.ki = 1; m.Count > 1 {
|
||||
radixQsort(it.data(), 0, maxDepth(it.kv.Len))
|
||||
}
|
||||
|
||||
/* load the first pair into iterator */
|
||||
it.It.V = it.at(0).v
|
||||
it.It.K = unsafe.Pointer(&it.at(0).k)
|
||||
return it, nil
|
||||
}
|
||||
|
||||
func asText(v unsafe.Pointer) (string, error) {
|
||||
text := rt.AssertI2I(rt.UnpackType(vars.EncodingTextMarshalerType), *(*rt.GoIface)(v))
|
||||
r, e := (*(*encoding.TextMarshaler)(unsafe.Pointer(&text))).MarshalText()
|
||||
return rt.Mem2Str(r), e
|
||||
}
|
31
vendor/github.com/bytedance/sonic/internal/encoder/alg/opts.go
generated
vendored
Normal file
31
vendor/github.com/bytedance/sonic/internal/encoder/alg/opts.go
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Copyright 2024 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 alg
|
||||
|
||||
const (
|
||||
BitSortMapKeys = iota
|
||||
BitEscapeHTML
|
||||
BitCompactMarshaler
|
||||
BitNoQuoteTextMarshaler
|
||||
BitNoNullSliceOrMap
|
||||
BitValidateString
|
||||
BitNoValidateJSONMarshaler
|
||||
BitNoEncoderNewline
|
||||
BitEncodeNullForInfOrNan
|
||||
|
||||
BitPointerValue = 63
|
||||
)
|
95
vendor/github.com/bytedance/sonic/internal/encoder/alg/primitives.go
generated
vendored
Normal file
95
vendor/github.com/bytedance/sonic/internal/encoder/alg/primitives.go
generated
vendored
Normal file
@ -0,0 +1,95 @@
|
||||
/**
|
||||
* Copyright 2024 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 alg
|
||||
|
||||
import (
|
||||
"encoding"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/bytedance/sonic/internal/encoder/vars"
|
||||
"github.com/bytedance/sonic/internal/rt"
|
||||
)
|
||||
|
||||
func Compact(p *[]byte, v []byte) error {
|
||||
buf := vars.NewBuffer()
|
||||
err := json.Compact(buf, v)
|
||||
|
||||
/* check for errors */
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
/* add to result */
|
||||
v = buf.Bytes()
|
||||
*p = append(*p, v...)
|
||||
|
||||
/* return the buffer into pool */
|
||||
vars.FreeBuffer(buf)
|
||||
return nil
|
||||
}
|
||||
|
||||
func EncodeNil(rb *[]byte) error {
|
||||
*rb = append(*rb, 'n', 'u', 'l', 'l')
|
||||
return nil
|
||||
}
|
||||
|
||||
// func Make_EncodeTypedPointer(computor func(*rt.GoType, ...interface{}) (interface{}, error)) func(*[]byte, *rt.GoType, *unsafe.Pointer, *vars.Stack, uint64) error {
|
||||
// return func(buf *[]byte, vt *rt.GoType, vp *unsafe.Pointer, sb *vars.Stack, fv uint64) error {
|
||||
// if vt == nil {
|
||||
// return EncodeNil(buf)
|
||||
// } else if fn, err := vars.FindOrCompile(vt, (fv&(1<<BitPointerValue)) != 0, computor); err != nil {
|
||||
// return err
|
||||
// } else if vt.Indirect() {
|
||||
// err := fn(buf, *vp, sb, fv)
|
||||
// return err
|
||||
// } else {
|
||||
// err := fn(buf, unsafe.Pointer(vp), sb, fv)
|
||||
// return err
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
func EncodeJsonMarshaler(buf *[]byte, val json.Marshaler, opt uint64) error {
|
||||
if ret, err := val.MarshalJSON(); err != nil {
|
||||
return err
|
||||
} else {
|
||||
if opt&(1<<BitCompactMarshaler) != 0 {
|
||||
return Compact(buf, ret)
|
||||
}
|
||||
if opt&(1<<BitNoValidateJSONMarshaler) == 0 {
|
||||
if ok, s := Valid(ret); !ok {
|
||||
return vars.Error_marshaler(ret, s)
|
||||
}
|
||||
}
|
||||
*buf = append(*buf, ret...)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func EncodeTextMarshaler(buf *[]byte, val encoding.TextMarshaler, opt uint64) error {
|
||||
if ret, err := val.MarshalText(); err != nil {
|
||||
return err
|
||||
} else {
|
||||
if opt&(1<<BitNoQuoteTextMarshaler) != 0 {
|
||||
*buf = append(*buf, ret...)
|
||||
return nil
|
||||
}
|
||||
*buf = Quote(*buf, rt.Mem2Str(ret), false)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
206
vendor/github.com/bytedance/sonic/internal/encoder/alg/sort.go
generated
vendored
Normal file
206
vendor/github.com/bytedance/sonic/internal/encoder/alg/sort.go
generated
vendored
Normal file
@ -0,0 +1,206 @@
|
||||
/*
|
||||
* 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 alg
|
||||
|
||||
// Algorithm 3-way Radix Quicksort, d means the radix.
|
||||
// Reference: https://algs4.cs.princeton.edu/51radix/Quick3string.java.html
|
||||
func radixQsort(kvs []_MapPair, d, maxDepth int) {
|
||||
for len(kvs) > 11 {
|
||||
// To avoid the worst case of quickSort (time: O(n^2)), use introsort here.
|
||||
// Reference: https://en.wikipedia.org/wiki/Introsort and
|
||||
// https://github.com/golang/go/issues/467
|
||||
if maxDepth == 0 {
|
||||
heapSort(kvs, 0, len(kvs))
|
||||
return
|
||||
}
|
||||
maxDepth--
|
||||
|
||||
p := pivot(kvs, d)
|
||||
lt, i, gt := 0, 0, len(kvs)
|
||||
for i < gt {
|
||||
c := byteAt(kvs[i].k, d)
|
||||
if c < p {
|
||||
swap(kvs, lt, i)
|
||||
i++
|
||||
lt++
|
||||
} else if c > p {
|
||||
gt--
|
||||
swap(kvs, i, gt)
|
||||
} else {
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
// kvs[0:lt] < v = kvs[lt:gt] < kvs[gt:len(kvs)]
|
||||
// Native implemention:
|
||||
// radixQsort(kvs[:lt], d, maxDepth)
|
||||
// if p > -1 {
|
||||
// radixQsort(kvs[lt:gt], d+1, maxDepth)
|
||||
// }
|
||||
// radixQsort(kvs[gt:], d, maxDepth)
|
||||
// Optimize as follows: make recursive calls only for the smaller parts.
|
||||
// Reference: https://www.geeksforgeeks.org/quicksort-tail-call-optimization-reducing-worst-case-space-log-n/
|
||||
if p == -1 {
|
||||
if lt > len(kvs) - gt {
|
||||
radixQsort(kvs[gt:], d, maxDepth)
|
||||
kvs = kvs[:lt]
|
||||
} else {
|
||||
radixQsort(kvs[:lt], d, maxDepth)
|
||||
kvs = kvs[gt:]
|
||||
}
|
||||
} else {
|
||||
ml := maxThree(lt, gt-lt, len(kvs)-gt)
|
||||
if ml == lt {
|
||||
radixQsort(kvs[lt:gt], d+1, maxDepth)
|
||||
radixQsort(kvs[gt:], d, maxDepth)
|
||||
kvs = kvs[:lt]
|
||||
} else if ml == gt-lt {
|
||||
radixQsort(kvs[:lt], d, maxDepth)
|
||||
radixQsort(kvs[gt:], d, maxDepth)
|
||||
kvs = kvs[lt:gt]
|
||||
d += 1
|
||||
} else {
|
||||
radixQsort(kvs[:lt], d, maxDepth)
|
||||
radixQsort(kvs[lt:gt], d+1, maxDepth)
|
||||
kvs = kvs[gt:]
|
||||
}
|
||||
}
|
||||
}
|
||||
insertRadixSort(kvs, d)
|
||||
}
|
||||
|
||||
func insertRadixSort(kvs []_MapPair, d int) {
|
||||
for i := 1; i < len(kvs); i++ {
|
||||
for j := i; j > 0 && lessFrom(kvs[j].k, kvs[j-1].k, d); j-- {
|
||||
swap(kvs, j, j-1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func pivot(kvs []_MapPair, d int) int {
|
||||
m := len(kvs) >> 1
|
||||
if len(kvs) > 40 {
|
||||
// Tukey's ``Ninther,'' median of three mediankvs of three.
|
||||
t := len(kvs) / 8
|
||||
return medianThree(
|
||||
medianThree(byteAt(kvs[0].k, d), byteAt(kvs[t].k, d), byteAt(kvs[2*t].k, d)),
|
||||
medianThree(byteAt(kvs[m].k, d), byteAt(kvs[m-t].k, d), byteAt(kvs[m+t].k, d)),
|
||||
medianThree(byteAt(kvs[len(kvs)-1].k, d),
|
||||
byteAt(kvs[len(kvs)-1-t].k, d),
|
||||
byteAt(kvs[len(kvs)-1-2*t].k, d)))
|
||||
}
|
||||
return medianThree(byteAt(kvs[0].k, d), byteAt(kvs[m].k, d), byteAt(kvs[len(kvs)-1].k, d))
|
||||
}
|
||||
|
||||
func medianThree(i, j, k int) int {
|
||||
if i > j {
|
||||
i, j = j, i
|
||||
} // i < j
|
||||
if k < i {
|
||||
return i
|
||||
}
|
||||
if k > j {
|
||||
return j
|
||||
}
|
||||
return k
|
||||
}
|
||||
|
||||
func maxThree(i, j, k int) int {
|
||||
max := i
|
||||
if max < j {
|
||||
max = j
|
||||
}
|
||||
if max < k {
|
||||
max = k
|
||||
}
|
||||
return max
|
||||
}
|
||||
|
||||
// maxDepth returns a threshold at which quicksort should switch
|
||||
// to heapsort. It returnkvs 2*ceil(lg(n+1)).
|
||||
func maxDepth(n int) int {
|
||||
var depth int
|
||||
for i := n; i > 0; i >>= 1 {
|
||||
depth++
|
||||
}
|
||||
return depth * 2
|
||||
}
|
||||
|
||||
// siftDown implements the heap property on kvs[lo:hi].
|
||||
// first is an offset into the array where the root of the heap lies.
|
||||
func siftDown(kvs []_MapPair, lo, hi, first int) {
|
||||
root := lo
|
||||
for {
|
||||
child := 2*root + 1
|
||||
if child >= hi {
|
||||
break
|
||||
}
|
||||
if child+1 < hi && kvs[first+child].k < kvs[first+child+1].k {
|
||||
child++
|
||||
}
|
||||
if kvs[first+root].k >= kvs[first+child].k {
|
||||
return
|
||||
}
|
||||
swap(kvs, first+root, first+child)
|
||||
root = child
|
||||
}
|
||||
}
|
||||
|
||||
func heapSort(kvs []_MapPair, a, b int) {
|
||||
first := a
|
||||
lo := 0
|
||||
hi := b - a
|
||||
|
||||
// Build heap with the greatest element at top.
|
||||
for i := (hi - 1) / 2; i >= 0; i-- {
|
||||
siftDown(kvs, i, hi, first)
|
||||
}
|
||||
|
||||
// Pop elements, the largest first, into end of kvs.
|
||||
for i := hi - 1; i >= 0; i-- {
|
||||
swap(kvs, first, first+i)
|
||||
siftDown(kvs, lo, i, first)
|
||||
}
|
||||
}
|
||||
|
||||
// Note that _MapPair.k is NOT pointed to _MapPair.m when map key is integer after swap
|
||||
func swap(kvs []_MapPair, a, b int) {
|
||||
kvs[a].k, kvs[b].k = kvs[b].k, kvs[a].k
|
||||
kvs[a].v, kvs[b].v = kvs[b].v, kvs[a].v
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
func byteAt(b string, p int) int {
|
||||
if p < len(b) {
|
||||
return int(b[p])
|
||||
}
|
||||
return -1
|
||||
}
|
198
vendor/github.com/bytedance/sonic/internal/encoder/alg/spec.go
generated
vendored
Normal file
198
vendor/github.com/bytedance/sonic/internal/encoder/alg/spec.go
generated
vendored
Normal file
@ -0,0 +1,198 @@
|
||||
//go:build (amd64 && go1.16 && !go1.24) || (arm64 && go1.20 && !go1.24)
|
||||
// +build amd64,go1.16,!go1.24 arm64,go1.20,!go1.24
|
||||
|
||||
/**
|
||||
* Copyright 2024 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 alg
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"unsafe"
|
||||
|
||||
"github.com/bytedance/sonic/internal/native"
|
||||
"github.com/bytedance/sonic/internal/native/types"
|
||||
"github.com/bytedance/sonic/internal/rt"
|
||||
)
|
||||
|
||||
// Valid validates json and returns first non-blank character position,
|
||||
// if it is only one valid json value.
|
||||
// Otherwise returns invalid character position using start.
|
||||
//
|
||||
// Note: it does not check for the invalid UTF-8 characters.
|
||||
func Valid(data []byte) (ok bool, start int) {
|
||||
n := len(data)
|
||||
if n == 0 {
|
||||
return false, -1
|
||||
}
|
||||
s := rt.Mem2Str(data)
|
||||
p := 0
|
||||
m := types.NewStateMachine()
|
||||
ret := native.ValidateOne(&s, &p, m, 0)
|
||||
types.FreeStateMachine(m)
|
||||
|
||||
if ret < 0 {
|
||||
return false, p-1
|
||||
}
|
||||
|
||||
/* check for trailing spaces */
|
||||
for ;p < n; p++ {
|
||||
if (types.SPACE_MASK & (1 << data[p])) == 0 {
|
||||
return false, p
|
||||
}
|
||||
}
|
||||
|
||||
return true, ret
|
||||
}
|
||||
|
||||
var typeByte = rt.UnpackEface(byte(0)).Type
|
||||
|
||||
//go:nocheckptr
|
||||
func Quote(buf []byte, val string, double bool) []byte {
|
||||
if len(val) == 0 {
|
||||
if double {
|
||||
return append(buf, `"\"\""`...)
|
||||
}
|
||||
return append(buf, `""`...)
|
||||
}
|
||||
|
||||
if double {
|
||||
buf = append(buf, `"\"`...)
|
||||
} else {
|
||||
buf = append(buf, `"`...)
|
||||
}
|
||||
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
|
||||
opts := uint64(0)
|
||||
if double {
|
||||
opts = types.F_DOUBLE_UNQUOTE
|
||||
}
|
||||
ret := native.Quote(sp, nb, dp, &dn, opts)
|
||||
// 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)
|
||||
if double {
|
||||
buf = append(buf, `\""`...)
|
||||
} else {
|
||||
buf = append(buf, `"`...)
|
||||
}
|
||||
|
||||
return buf
|
||||
}
|
||||
|
||||
func HtmlEscape(dst []byte, src []byte) []byte {
|
||||
var sidx int
|
||||
|
||||
dst = append(dst, src[:0]...) // avoid check nil dst
|
||||
sbuf := (*rt.GoSlice)(unsafe.Pointer(&src))
|
||||
dbuf := (*rt.GoSlice)(unsafe.Pointer(&dst))
|
||||
|
||||
/* grow dst if it is shorter */
|
||||
if cap(dst)-len(dst) < len(src)+types.BufPaddingSize {
|
||||
cap := len(src)*3/2 + types.BufPaddingSize
|
||||
*dbuf = rt.GrowSlice(typeByte, *dbuf, cap)
|
||||
}
|
||||
|
||||
for sidx < sbuf.Len {
|
||||
sp := rt.Add(sbuf.Ptr, uintptr(sidx))
|
||||
dp := rt.Add(dbuf.Ptr, uintptr(dbuf.Len))
|
||||
|
||||
sn := sbuf.Len - sidx
|
||||
dn := dbuf.Cap - dbuf.Len
|
||||
nb := native.HTMLEscape(sp, sn, dp, &dn)
|
||||
|
||||
/* check for errors */
|
||||
if dbuf.Len += dn; nb >= 0 {
|
||||
break
|
||||
}
|
||||
|
||||
/* not enough space, grow the slice and try again */
|
||||
sidx += ^nb
|
||||
*dbuf = rt.GrowSlice(typeByte, *dbuf, dbuf.Cap*2)
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
func F64toa(buf []byte, v float64) ([]byte) {
|
||||
if v == 0 {
|
||||
return append(buf, '0')
|
||||
}
|
||||
buf = rt.GuardSlice2(buf, 64)
|
||||
ret := native.F64toa((*byte)(rt.IndexByte(buf, len(buf))), v)
|
||||
if ret > 0 {
|
||||
return buf[:len(buf)+ret]
|
||||
} else {
|
||||
return buf
|
||||
}
|
||||
}
|
||||
|
||||
func F32toa(buf []byte, v float32) ([]byte) {
|
||||
if v == 0 {
|
||||
return append(buf, '0')
|
||||
}
|
||||
buf = rt.GuardSlice2(buf, 64)
|
||||
ret := native.F32toa((*byte)(rt.IndexByte(buf, len(buf))), v)
|
||||
if ret > 0 {
|
||||
return buf[:len(buf)+ret]
|
||||
} else {
|
||||
return buf
|
||||
}
|
||||
}
|
||||
|
||||
func I64toa(buf []byte, v int64) ([]byte) {
|
||||
buf = rt.GuardSlice2(buf, 32)
|
||||
ret := native.I64toa((*byte)(rt.IndexByte(buf, len(buf))), v)
|
||||
if ret > 0 {
|
||||
return buf[:len(buf)+ret]
|
||||
} else {
|
||||
return buf
|
||||
}
|
||||
}
|
||||
|
||||
func U64toa(buf []byte, v uint64) ([]byte) {
|
||||
buf = rt.GuardSlice2(buf, 32)
|
||||
ret := native.U64toa((*byte)(rt.IndexByte(buf, len(buf))), v)
|
||||
if ret > 0 {
|
||||
return buf[:len(buf)+ret]
|
||||
} else {
|
||||
return buf
|
||||
}
|
||||
}
|
||||
|
148
vendor/github.com/bytedance/sonic/internal/encoder/alg/spec_compat.go
generated
vendored
Normal file
148
vendor/github.com/bytedance/sonic/internal/encoder/alg/spec_compat.go
generated
vendored
Normal file
@ -0,0 +1,148 @@
|
||||
// +build !amd64,!arm64 go1.24 !go1.16 arm64,!go1.20
|
||||
|
||||
/**
|
||||
* Copyright 2024 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 alg
|
||||
|
||||
import (
|
||||
_ "unsafe"
|
||||
"unicode/utf8"
|
||||
"strconv"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/bytedance/sonic/internal/rt"
|
||||
)
|
||||
|
||||
// Valid validates json and returns first non-blank character position,
|
||||
// if it is only one valid json value.
|
||||
// Otherwise returns invalid character position using start.
|
||||
//
|
||||
// Note: it does not check for the invalid UTF-8 characters.
|
||||
func Valid(data []byte) (ok bool, start int) {
|
||||
ok = json.Valid(data)
|
||||
return ok, 0
|
||||
}
|
||||
|
||||
var typeByte = rt.UnpackEface(byte(0)).Type
|
||||
|
||||
func Quote(e []byte, s string, double bool) []byte {
|
||||
if len(s) == 0 {
|
||||
if double {
|
||||
return append(e, `"\"\""`...)
|
||||
}
|
||||
return append(e, `""`...)
|
||||
}
|
||||
|
||||
b := e
|
||||
ss := len(e)
|
||||
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 correct && c == utf8.RuneError && size == 1 {
|
||||
// if start < i {
|
||||
// e = append(e, s[start:i]...)
|
||||
// }
|
||||
// e = append(e, `\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, '"')
|
||||
|
||||
if double {
|
||||
return strconv.AppendQuote(b, string(e[ss:]))
|
||||
} else {
|
||||
return e
|
||||
}
|
||||
}
|
||||
|
||||
func HtmlEscape(dst []byte, src []byte) []byte {
|
||||
buf := bytes.NewBuffer(dst)
|
||||
json.HTMLEscape(buf, src)
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
func F64toa(buf []byte, v float64) ([]byte) {
|
||||
bs := bytes.NewBuffer(buf)
|
||||
_ = json.NewEncoder(bs).Encode(v)
|
||||
return bs.Bytes()
|
||||
}
|
||||
|
||||
func F32toa(buf []byte, v float32) ([]byte) {
|
||||
bs := bytes.NewBuffer(buf)
|
||||
_ = json.NewEncoder(bs).Encode(v)
|
||||
return bs.Bytes()
|
||||
}
|
||||
|
||||
func I64toa(buf []byte, v int64) ([]byte) {
|
||||
return strconv.AppendInt(buf, int64(v), 10)
|
||||
}
|
||||
|
||||
func U64toa(buf []byte, v uint64) ([]byte) {
|
||||
return strconv.AppendUint(buf, v, 10)
|
||||
}
|
Reference in New Issue
Block a user