.github
alerting
client
config
controller
core
docs
example
jsonpath
k8s
k8stest
metric
pattern
security
storage
util
vendor
cloud.google.com
github.com
TwinProduction
beorn7
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
go.etcd.io
golang.org
google.golang.org
gopkg.in
k8s.io
sigs.k8s.io
modules.txt
watchdog
web
.dockerignore
.gitattributes
.gitignore
Dockerfile
LICENSE.md
Makefile
README.md
config.yaml
go.mod
go.sum
main.go
347 lines
8.9 KiB
Go
347 lines
8.9 KiB
Go
package jsoniter
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/modern-go/reflect2"
|
|
"io"
|
|
"reflect"
|
|
"sort"
|
|
"unsafe"
|
|
)
|
|
|
|
func decoderOfMap(ctx *ctx, typ reflect2.Type) ValDecoder {
|
|
mapType := typ.(*reflect2.UnsafeMapType)
|
|
keyDecoder := decoderOfMapKey(ctx.append("[mapKey]"), mapType.Key())
|
|
elemDecoder := decoderOfType(ctx.append("[mapElem]"), mapType.Elem())
|
|
return &mapDecoder{
|
|
mapType: mapType,
|
|
keyType: mapType.Key(),
|
|
elemType: mapType.Elem(),
|
|
keyDecoder: keyDecoder,
|
|
elemDecoder: elemDecoder,
|
|
}
|
|
}
|
|
|
|
func encoderOfMap(ctx *ctx, typ reflect2.Type) ValEncoder {
|
|
mapType := typ.(*reflect2.UnsafeMapType)
|
|
if ctx.sortMapKeys {
|
|
return &sortKeysMapEncoder{
|
|
mapType: mapType,
|
|
keyEncoder: encoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()),
|
|
elemEncoder: encoderOfType(ctx.append("[mapElem]"), mapType.Elem()),
|
|
}
|
|
}
|
|
return &mapEncoder{
|
|
mapType: mapType,
|
|
keyEncoder: encoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()),
|
|
elemEncoder: encoderOfType(ctx.append("[mapElem]"), mapType.Elem()),
|
|
}
|
|
}
|
|
|
|
func decoderOfMapKey(ctx *ctx, typ reflect2.Type) ValDecoder {
|
|
decoder := ctx.decoderExtension.CreateMapKeyDecoder(typ)
|
|
if decoder != nil {
|
|
return decoder
|
|
}
|
|
for _, extension := range ctx.extraExtensions {
|
|
decoder := extension.CreateMapKeyDecoder(typ)
|
|
if decoder != nil {
|
|
return decoder
|
|
}
|
|
}
|
|
|
|
ptrType := reflect2.PtrTo(typ)
|
|
if ptrType.Implements(unmarshalerType) {
|
|
return &referenceDecoder{
|
|
&unmarshalerDecoder{
|
|
valType: ptrType,
|
|
},
|
|
}
|
|
}
|
|
if typ.Implements(unmarshalerType) {
|
|
return &unmarshalerDecoder{
|
|
valType: typ,
|
|
}
|
|
}
|
|
if ptrType.Implements(textUnmarshalerType) {
|
|
return &referenceDecoder{
|
|
&textUnmarshalerDecoder{
|
|
valType: ptrType,
|
|
},
|
|
}
|
|
}
|
|
if typ.Implements(textUnmarshalerType) {
|
|
return &textUnmarshalerDecoder{
|
|
valType: typ,
|
|
}
|
|
}
|
|
|
|
switch typ.Kind() {
|
|
case reflect.String:
|
|
return decoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String))
|
|
case reflect.Bool,
|
|
reflect.Uint8, reflect.Int8,
|
|
reflect.Uint16, reflect.Int16,
|
|
reflect.Uint32, reflect.Int32,
|
|
reflect.Uint64, reflect.Int64,
|
|
reflect.Uint, reflect.Int,
|
|
reflect.Float32, reflect.Float64,
|
|
reflect.Uintptr:
|
|
typ = reflect2.DefaultTypeOfKind(typ.Kind())
|
|
return &numericMapKeyDecoder{decoderOfType(ctx, typ)}
|
|
default:
|
|
return &lazyErrorDecoder{err: fmt.Errorf("unsupported map key type: %v", typ)}
|
|
}
|
|
}
|
|
|
|
func encoderOfMapKey(ctx *ctx, typ reflect2.Type) ValEncoder {
|
|
encoder := ctx.encoderExtension.CreateMapKeyEncoder(typ)
|
|
if encoder != nil {
|
|
return encoder
|
|
}
|
|
for _, extension := range ctx.extraExtensions {
|
|
encoder := extension.CreateMapKeyEncoder(typ)
|
|
if encoder != nil {
|
|
return encoder
|
|
}
|
|
}
|
|
|
|
if typ == textMarshalerType {
|
|
return &directTextMarshalerEncoder{
|
|
stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")),
|
|
}
|
|
}
|
|
if typ.Implements(textMarshalerType) {
|
|
return &textMarshalerEncoder{
|
|
valType: typ,
|
|
stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")),
|
|
}
|
|
}
|
|
|
|
switch typ.Kind() {
|
|
case reflect.String:
|
|
return encoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String))
|
|
case reflect.Bool,
|
|
reflect.Uint8, reflect.Int8,
|
|
reflect.Uint16, reflect.Int16,
|
|
reflect.Uint32, reflect.Int32,
|
|
reflect.Uint64, reflect.Int64,
|
|
reflect.Uint, reflect.Int,
|
|
reflect.Float32, reflect.Float64,
|
|
reflect.Uintptr:
|
|
typ = reflect2.DefaultTypeOfKind(typ.Kind())
|
|
return &numericMapKeyEncoder{encoderOfType(ctx, typ)}
|
|
default:
|
|
if typ.Kind() == reflect.Interface {
|
|
return &dynamicMapKeyEncoder{ctx, typ}
|
|
}
|
|
return &lazyErrorEncoder{err: fmt.Errorf("unsupported map key type: %v", typ)}
|
|
}
|
|
}
|
|
|
|
type mapDecoder struct {
|
|
mapType *reflect2.UnsafeMapType
|
|
keyType reflect2.Type
|
|
elemType reflect2.Type
|
|
keyDecoder ValDecoder
|
|
elemDecoder ValDecoder
|
|
}
|
|
|
|
func (decoder *mapDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
|
mapType := decoder.mapType
|
|
c := iter.nextToken()
|
|
if c == 'n' {
|
|
iter.skipThreeBytes('u', 'l', 'l')
|
|
*(*unsafe.Pointer)(ptr) = nil
|
|
mapType.UnsafeSet(ptr, mapType.UnsafeNew())
|
|
return
|
|
}
|
|
if mapType.UnsafeIsNil(ptr) {
|
|
mapType.UnsafeSet(ptr, mapType.UnsafeMakeMap(0))
|
|
}
|
|
if c != '{' {
|
|
iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c}))
|
|
return
|
|
}
|
|
c = iter.nextToken()
|
|
if c == '}' {
|
|
return
|
|
}
|
|
iter.unreadByte()
|
|
key := decoder.keyType.UnsafeNew()
|
|
decoder.keyDecoder.Decode(key, iter)
|
|
c = iter.nextToken()
|
|
if c != ':' {
|
|
iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
|
|
return
|
|
}
|
|
elem := decoder.elemType.UnsafeNew()
|
|
decoder.elemDecoder.Decode(elem, iter)
|
|
decoder.mapType.UnsafeSetIndex(ptr, key, elem)
|
|
for c = iter.nextToken(); c == ','; c = iter.nextToken() {
|
|
key := decoder.keyType.UnsafeNew()
|
|
decoder.keyDecoder.Decode(key, iter)
|
|
c = iter.nextToken()
|
|
if c != ':' {
|
|
iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
|
|
return
|
|
}
|
|
elem := decoder.elemType.UnsafeNew()
|
|
decoder.elemDecoder.Decode(elem, iter)
|
|
decoder.mapType.UnsafeSetIndex(ptr, key, elem)
|
|
}
|
|
if c != '}' {
|
|
iter.ReportError("ReadMapCB", `expect }, but found `+string([]byte{c}))
|
|
}
|
|
}
|
|
|
|
type numericMapKeyDecoder struct {
|
|
decoder ValDecoder
|
|
}
|
|
|
|
func (decoder *numericMapKeyDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
|
c := iter.nextToken()
|
|
if c != '"' {
|
|
iter.ReportError("ReadMapCB", `expect ", but found `+string([]byte{c}))
|
|
return
|
|
}
|
|
decoder.decoder.Decode(ptr, iter)
|
|
c = iter.nextToken()
|
|
if c != '"' {
|
|
iter.ReportError("ReadMapCB", `expect ", but found `+string([]byte{c}))
|
|
return
|
|
}
|
|
}
|
|
|
|
type numericMapKeyEncoder struct {
|
|
encoder ValEncoder
|
|
}
|
|
|
|
func (encoder *numericMapKeyEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
|
stream.writeByte('"')
|
|
encoder.encoder.Encode(ptr, stream)
|
|
stream.writeByte('"')
|
|
}
|
|
|
|
func (encoder *numericMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
|
return false
|
|
}
|
|
|
|
type dynamicMapKeyEncoder struct {
|
|
ctx *ctx
|
|
valType reflect2.Type
|
|
}
|
|
|
|
func (encoder *dynamicMapKeyEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
|
obj := encoder.valType.UnsafeIndirect(ptr)
|
|
encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).Encode(reflect2.PtrOf(obj), stream)
|
|
}
|
|
|
|
func (encoder *dynamicMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
|
obj := encoder.valType.UnsafeIndirect(ptr)
|
|
return encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).IsEmpty(reflect2.PtrOf(obj))
|
|
}
|
|
|
|
type mapEncoder struct {
|
|
mapType *reflect2.UnsafeMapType
|
|
keyEncoder ValEncoder
|
|
elemEncoder ValEncoder
|
|
}
|
|
|
|
func (encoder *mapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
|
if *(*unsafe.Pointer)(ptr) == nil {
|
|
stream.WriteNil()
|
|
return
|
|
}
|
|
stream.WriteObjectStart()
|
|
iter := encoder.mapType.UnsafeIterate(ptr)
|
|
for i := 0; iter.HasNext(); i++ {
|
|
if i != 0 {
|
|
stream.WriteMore()
|
|
}
|
|
key, elem := iter.UnsafeNext()
|
|
encoder.keyEncoder.Encode(key, stream)
|
|
if stream.indention > 0 {
|
|
stream.writeTwoBytes(byte(':'), byte(' '))
|
|
} else {
|
|
stream.writeByte(':')
|
|
}
|
|
encoder.elemEncoder.Encode(elem, stream)
|
|
}
|
|
stream.WriteObjectEnd()
|
|
}
|
|
|
|
func (encoder *mapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
|
iter := encoder.mapType.UnsafeIterate(ptr)
|
|
return !iter.HasNext()
|
|
}
|
|
|
|
type sortKeysMapEncoder struct {
|
|
mapType *reflect2.UnsafeMapType
|
|
keyEncoder ValEncoder
|
|
elemEncoder ValEncoder
|
|
}
|
|
|
|
func (encoder *sortKeysMapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
|
if *(*unsafe.Pointer)(ptr) == nil {
|
|
stream.WriteNil()
|
|
return
|
|
}
|
|
stream.WriteObjectStart()
|
|
mapIter := encoder.mapType.UnsafeIterate(ptr)
|
|
subStream := stream.cfg.BorrowStream(nil)
|
|
subStream.Attachment = stream.Attachment
|
|
subIter := stream.cfg.BorrowIterator(nil)
|
|
keyValues := encodedKeyValues{}
|
|
for mapIter.HasNext() {
|
|
key, elem := mapIter.UnsafeNext()
|
|
subStreamIndex := subStream.Buffered()
|
|
encoder.keyEncoder.Encode(key, subStream)
|
|
if subStream.Error != nil && subStream.Error != io.EOF && stream.Error == nil {
|
|
stream.Error = subStream.Error
|
|
}
|
|
encodedKey := subStream.Buffer()[subStreamIndex:]
|
|
subIter.ResetBytes(encodedKey)
|
|
decodedKey := subIter.ReadString()
|
|
if stream.indention > 0 {
|
|
subStream.writeTwoBytes(byte(':'), byte(' '))
|
|
} else {
|
|
subStream.writeByte(':')
|
|
}
|
|
encoder.elemEncoder.Encode(elem, subStream)
|
|
keyValues = append(keyValues, encodedKV{
|
|
key: decodedKey,
|
|
keyValue: subStream.Buffer()[subStreamIndex:],
|
|
})
|
|
}
|
|
sort.Sort(keyValues)
|
|
for i, keyValue := range keyValues {
|
|
if i != 0 {
|
|
stream.WriteMore()
|
|
}
|
|
stream.Write(keyValue.keyValue)
|
|
}
|
|
if subStream.Error != nil && stream.Error == nil {
|
|
stream.Error = subStream.Error
|
|
}
|
|
stream.WriteObjectEnd()
|
|
stream.cfg.ReturnStream(subStream)
|
|
stream.cfg.ReturnIterator(subIter)
|
|
}
|
|
|
|
func (encoder *sortKeysMapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
|
iter := encoder.mapType.UnsafeIterate(ptr)
|
|
return !iter.HasNext()
|
|
}
|
|
|
|
type encodedKeyValues []encodedKV
|
|
|
|
type encodedKV struct {
|
|
key string
|
|
keyValue []byte
|
|
}
|
|
|
|
func (sv encodedKeyValues) Len() int { return len(sv) }
|
|
func (sv encodedKeyValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] }
|
|
func (sv encodedKeyValues) Less(i, j int) bool { return sv[i].key < sv[j].key }
|