.github
alerting
client
config
controller
core
docs
example
jsonpath
k8s
k8stest
metric
pattern
security
static
storage
vendor
cloud.google.com
github.com
TwinProduction
beorn7
boltdb
cespare
davecgh
go-ping
gogo
golang
google
googleapis
gorilla
imdario
json-iterator
go
.codecov.yml
.gitignore
.travis.yml
Gopkg.lock
Gopkg.toml
LICENSE
README.md
adapter.go
any.go
any_array.go
any_bool.go
any_float.go
any_int32.go
any_int64.go
any_invalid.go
any_nil.go
any_number.go
any_object.go
any_str.go
any_uint32.go
any_uint64.go
build.sh
config.go
fuzzy_mode_convert_table.md
go.mod
go.sum
iter.go
iter_array.go
iter_float.go
iter_int.go
iter_object.go
iter_skip.go
iter_skip_sloppy.go
iter_skip_strict.go
iter_str.go
jsoniter.go
pool.go
reflect.go
reflect_array.go
reflect_dynamic.go
reflect_extension.go
reflect_json_number.go
reflect_json_raw_message.go
reflect_map.go
reflect_marshaler.go
reflect_native.go
reflect_optional.go
reflect_slice.go
reflect_struct_decoder.go
reflect_struct_encoder.go
stream.go
stream_float.go
stream_int.go
stream_str.go
test.sh
matttproud
miekg
modern-go
prometheus
spf13
golang.org
google.golang.org
gopkg.in
k8s.io
sigs.k8s.io
modules.txt
watchdog
.dockerignore
.gitattributes
.gitignore
Dockerfile
LICENSE.md
README.md
config.yaml
go.mod
go.sum
main.go
100 lines
2.6 KiB
Go
100 lines
2.6 KiB
Go
package jsoniter
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/modern-go/reflect2"
|
|
"io"
|
|
"unsafe"
|
|
)
|
|
|
|
func decoderOfSlice(ctx *ctx, typ reflect2.Type) ValDecoder {
|
|
sliceType := typ.(*reflect2.UnsafeSliceType)
|
|
decoder := decoderOfType(ctx.append("[sliceElem]"), sliceType.Elem())
|
|
return &sliceDecoder{sliceType, decoder}
|
|
}
|
|
|
|
func encoderOfSlice(ctx *ctx, typ reflect2.Type) ValEncoder {
|
|
sliceType := typ.(*reflect2.UnsafeSliceType)
|
|
encoder := encoderOfType(ctx.append("[sliceElem]"), sliceType.Elem())
|
|
return &sliceEncoder{sliceType, encoder}
|
|
}
|
|
|
|
type sliceEncoder struct {
|
|
sliceType *reflect2.UnsafeSliceType
|
|
elemEncoder ValEncoder
|
|
}
|
|
|
|
func (encoder *sliceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
|
if encoder.sliceType.UnsafeIsNil(ptr) {
|
|
stream.WriteNil()
|
|
return
|
|
}
|
|
length := encoder.sliceType.UnsafeLengthOf(ptr)
|
|
if length == 0 {
|
|
stream.WriteEmptyArray()
|
|
return
|
|
}
|
|
stream.WriteArrayStart()
|
|
encoder.elemEncoder.Encode(encoder.sliceType.UnsafeGetIndex(ptr, 0), stream)
|
|
for i := 1; i < length; i++ {
|
|
stream.WriteMore()
|
|
elemPtr := encoder.sliceType.UnsafeGetIndex(ptr, i)
|
|
encoder.elemEncoder.Encode(elemPtr, stream)
|
|
}
|
|
stream.WriteArrayEnd()
|
|
if stream.Error != nil && stream.Error != io.EOF {
|
|
stream.Error = fmt.Errorf("%v: %s", encoder.sliceType, stream.Error.Error())
|
|
}
|
|
}
|
|
|
|
func (encoder *sliceEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
|
return encoder.sliceType.UnsafeLengthOf(ptr) == 0
|
|
}
|
|
|
|
type sliceDecoder struct {
|
|
sliceType *reflect2.UnsafeSliceType
|
|
elemDecoder ValDecoder
|
|
}
|
|
|
|
func (decoder *sliceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
|
decoder.doDecode(ptr, iter)
|
|
if iter.Error != nil && iter.Error != io.EOF {
|
|
iter.Error = fmt.Errorf("%v: %s", decoder.sliceType, iter.Error.Error())
|
|
}
|
|
}
|
|
|
|
func (decoder *sliceDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) {
|
|
c := iter.nextToken()
|
|
sliceType := decoder.sliceType
|
|
if c == 'n' {
|
|
iter.skipThreeBytes('u', 'l', 'l')
|
|
sliceType.UnsafeSetNil(ptr)
|
|
return
|
|
}
|
|
if c != '[' {
|
|
iter.ReportError("decode slice", "expect [ or n, but found "+string([]byte{c}))
|
|
return
|
|
}
|
|
c = iter.nextToken()
|
|
if c == ']' {
|
|
sliceType.UnsafeSet(ptr, sliceType.UnsafeMakeSlice(0, 0))
|
|
return
|
|
}
|
|
iter.unreadByte()
|
|
sliceType.UnsafeGrow(ptr, 1)
|
|
elemPtr := sliceType.UnsafeGetIndex(ptr, 0)
|
|
decoder.elemDecoder.Decode(elemPtr, iter)
|
|
length := 1
|
|
for c = iter.nextToken(); c == ','; c = iter.nextToken() {
|
|
idx := length
|
|
length += 1
|
|
sliceType.UnsafeGrow(ptr, length)
|
|
elemPtr = sliceType.UnsafeGetIndex(ptr, idx)
|
|
decoder.elemDecoder.Decode(elemPtr, iter)
|
|
}
|
|
if c != ']' {
|
|
iter.ReportError("decode slice", "expect ], but found "+string([]byte{c}))
|
|
return
|
|
}
|
|
}
|