mirror of
https://github.com/json-iterator/go.git
synced 2024-11-24 08:22:14 +02:00
use reflect2 to replace reflect
This commit is contained in:
parent
a3866383f5
commit
99fc16a363
12
any.go
12
any.go
@ -90,7 +90,7 @@ func Wrap(val interface{}) Any {
|
||||
if isAny {
|
||||
return asAny
|
||||
}
|
||||
typ := reflect.TypeOf(val)
|
||||
typ := reflect2.TypeOf(val)
|
||||
switch typ.Kind() {
|
||||
case reflect.Slice:
|
||||
return wrapArray(val)
|
||||
@ -245,27 +245,27 @@ func locatePath(iter *Iterator, path []interface{}) Any {
|
||||
return iter.readAny()
|
||||
}
|
||||
|
||||
var anyType = reflect.TypeOf((*Any)(nil)).Elem()
|
||||
var anyType = reflect2.TypeOfPtr((*Any)(nil)).Elem()
|
||||
|
||||
func createDecoderOfAny(ctx *ctx, typ reflect.Type) ValDecoder {
|
||||
func createDecoderOfAny(ctx *ctx, typ reflect2.Type) ValDecoder {
|
||||
if typ == anyType {
|
||||
return &directAnyCodec{}
|
||||
}
|
||||
if typ.Implements(anyType) {
|
||||
return &anyCodec{
|
||||
valType: reflect2.Type2(typ),
|
||||
valType: typ,
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func createEncoderOfAny(ctx *ctx, typ reflect.Type) ValEncoder {
|
||||
func createEncoderOfAny(ctx *ctx, typ reflect2.Type) ValEncoder {
|
||||
if typ == anyType {
|
||||
return &directAnyCodec{}
|
||||
}
|
||||
if typ.Implements(anyType) {
|
||||
return &anyCodec{
|
||||
valType: reflect2.Type2(typ),
|
||||
valType: typ,
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
14
config.go
14
config.go
@ -3,8 +3,8 @@ package jsoniter
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"reflect"
|
||||
"unsafe"
|
||||
"github.com/v2pro/plz/reflect2"
|
||||
)
|
||||
|
||||
// Config customize how the API should behave.
|
||||
@ -118,12 +118,12 @@ func (cfg *frozenConfig) validateJsonRawMessage(extension EncoderExtension) {
|
||||
}, func(ptr unsafe.Pointer) bool {
|
||||
return false
|
||||
}}
|
||||
extension[reflect.TypeOf((*json.RawMessage)(nil)).Elem()] = encoder
|
||||
extension[reflect.TypeOf((*RawMessage)(nil)).Elem()] = encoder
|
||||
extension[reflect2.TypeOfPtr((*json.RawMessage)(nil)).Elem()] = encoder
|
||||
extension[reflect2.TypeOfPtr((*RawMessage)(nil)).Elem()] = encoder
|
||||
}
|
||||
|
||||
func (cfg *frozenConfig) useNumber(extension DecoderExtension) {
|
||||
extension[reflect.TypeOf((*interface{})(nil)).Elem()] = &funcDecoder{func(ptr unsafe.Pointer, iter *Iterator) {
|
||||
extension[reflect2.TypeOfPtr((*interface{})(nil)).Elem()] = &funcDecoder{func(ptr unsafe.Pointer, iter *Iterator) {
|
||||
if iter.WhatIsNext() == NumberValue {
|
||||
*((*interface{})(ptr)) = json.Number(iter.readNumberAsString())
|
||||
} else {
|
||||
@ -169,8 +169,8 @@ func (encoder *lossyFloat64Encoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||
// for float variables for better performance.
|
||||
func (cfg *frozenConfig) marshalFloatWith6Digits(extension EncoderExtension) {
|
||||
// for better performance
|
||||
extension[reflect.TypeOf((*float32)(nil)).Elem()] = &lossyFloat32Encoder{}
|
||||
extension[reflect.TypeOf((*float64)(nil)).Elem()] = &lossyFloat64Encoder{}
|
||||
extension[reflect2.TypeOfPtr((*float32)(nil)).Elem()] = &lossyFloat32Encoder{}
|
||||
extension[reflect2.TypeOfPtr((*float64)(nil)).Elem()] = &lossyFloat64Encoder{}
|
||||
}
|
||||
|
||||
type htmlEscapedStringEncoder struct {
|
||||
@ -186,7 +186,7 @@ func (encoder *htmlEscapedStringEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||
}
|
||||
|
||||
func (cfg *frozenConfig) escapeHTML(encoderExtension EncoderExtension) {
|
||||
encoderExtension[reflect.TypeOf((*string)(nil)).Elem()] = &htmlEscapedStringEncoder{}
|
||||
encoderExtension[reflect2.TypeOfPtr((*string)(nil)).Elem()] = &htmlEscapedStringEncoder{}
|
||||
}
|
||||
|
||||
func (cfg *frozenConfig) cleanDecoders() {
|
||||
|
@ -3,7 +3,6 @@
|
||||
package jsoniter
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sync"
|
||||
)
|
||||
|
||||
@ -26,15 +25,15 @@ func (cfg *frozenConfig) initCache() {
|
||||
cfg.encoderCache = sync.Map{}
|
||||
}
|
||||
|
||||
func (cfg *frozenConfig) addDecoderToCache(cacheKey reflect.Type, decoder ValDecoder) {
|
||||
func (cfg *frozenConfig) addDecoderToCache(cacheKey uintptr, decoder ValDecoder) {
|
||||
cfg.decoderCache.Store(cacheKey, decoder)
|
||||
}
|
||||
|
||||
func (cfg *frozenConfig) addEncoderToCache(cacheKey reflect.Type, encoder ValEncoder) {
|
||||
func (cfg *frozenConfig) addEncoderToCache(cacheKey uintptr, encoder ValEncoder) {
|
||||
cfg.encoderCache.Store(cacheKey, encoder)
|
||||
}
|
||||
|
||||
func (cfg *frozenConfig) getDecoderFromCache(cacheKey reflect.Type) ValDecoder {
|
||||
func (cfg *frozenConfig) getDecoderFromCache(cacheKey uintptr) ValDecoder {
|
||||
decoder, found := cfg.decoderCache.Load(cacheKey)
|
||||
if found {
|
||||
return decoder.(ValDecoder)
|
||||
@ -42,7 +41,7 @@ func (cfg *frozenConfig) getDecoderFromCache(cacheKey reflect.Type) ValDecoder {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cfg *frozenConfig) getEncoderFromCache(cacheKey reflect.Type) ValEncoder {
|
||||
func (cfg *frozenConfig) getEncoderFromCache(cacheKey uintptr) ValEncoder {
|
||||
encoder, found := cfg.encoderCache.Load(cacheKey)
|
||||
if found {
|
||||
return encoder.(ValEncoder)
|
||||
|
@ -15,8 +15,8 @@ type frozenConfig struct {
|
||||
onlyTaggedField bool
|
||||
disallowUnknownFields bool
|
||||
cacheLock *sync.RWMutex
|
||||
decoderCache map[reflect.Type]ValDecoder
|
||||
encoderCache map[reflect.Type]ValEncoder
|
||||
decoderCache map[reflect2.Type]ValDecoder
|
||||
encoderCache map[reflect2.Type]ValEncoder
|
||||
extensions []Extension
|
||||
streamPool chan *Stream
|
||||
iteratorPool chan *Iterator
|
||||
@ -24,30 +24,30 @@ type frozenConfig struct {
|
||||
|
||||
func (cfg *frozenConfig) initCache() {
|
||||
cfg.cacheLock = &sync.RWMutex{}
|
||||
cfg.decoderCache = map[reflect.Type]ValDecoder{}
|
||||
cfg.encoderCache = map[reflect.Type]ValEncoder{}
|
||||
cfg.decoderCache = map[reflect2.Type]ValDecoder{}
|
||||
cfg.encoderCache = map[reflect2.Type]ValEncoder{}
|
||||
}
|
||||
|
||||
func (cfg *frozenConfig) addDecoderToCache(cacheKey reflect.Type, decoder ValDecoder) {
|
||||
func (cfg *frozenConfig) addDecoderToCache(cacheKey reflect2.Type, decoder ValDecoder) {
|
||||
cfg.cacheLock.Lock()
|
||||
cfg.decoderCache[cacheKey] = decoder
|
||||
cfg.cacheLock.Unlock()
|
||||
}
|
||||
|
||||
func (cfg *frozenConfig) addEncoderToCache(cacheKey reflect.Type, encoder ValEncoder) {
|
||||
func (cfg *frozenConfig) addEncoderToCache(cacheKey reflect2.Type, encoder ValEncoder) {
|
||||
cfg.cacheLock.Lock()
|
||||
cfg.encoderCache[cacheKey] = encoder
|
||||
cfg.cacheLock.Unlock()
|
||||
}
|
||||
|
||||
func (cfg *frozenConfig) getDecoderFromCache(cacheKey reflect.Type) ValDecoder {
|
||||
func (cfg *frozenConfig) getDecoderFromCache(cacheKey reflect2.Type) ValDecoder {
|
||||
cfg.cacheLock.RLock()
|
||||
decoder, _ := cfg.decoderCache[cacheKey].(ValDecoder)
|
||||
cfg.cacheLock.RUnlock()
|
||||
return decoder
|
||||
}
|
||||
|
||||
func (cfg *frozenConfig) getEncoderFromCache(cacheKey reflect.Type) ValEncoder {
|
||||
func (cfg *frozenConfig) getEncoderFromCache(cacheKey reflect2.Type) ValEncoder {
|
||||
cfg.cacheLock.RLock()
|
||||
encoder, _ := cfg.encoderCache[cacheKey].(ValEncoder)
|
||||
cfg.cacheLock.RUnlock()
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/json-iterator/go"
|
||||
"github.com/v2pro/plz/reflect2"
|
||||
)
|
||||
|
||||
const maxUint = ^uint(0)
|
||||
@ -148,7 +149,7 @@ type tolerateEmptyArrayExtension struct {
|
||||
jsoniter.DummyExtension
|
||||
}
|
||||
|
||||
func (extension *tolerateEmptyArrayExtension) DecorateDecoder(typ reflect.Type, decoder jsoniter.ValDecoder) jsoniter.ValDecoder {
|
||||
func (extension *tolerateEmptyArrayExtension) DecorateDecoder(typ reflect2.Type, decoder jsoniter.ValDecoder) jsoniter.ValDecoder {
|
||||
if typ.Kind() == reflect.Struct || typ.Kind() == reflect.Map {
|
||||
return &tolerateEmptyArrayDecoder{decoder}
|
||||
}
|
||||
|
@ -17,8 +17,8 @@ type namingStrategyExtension struct {
|
||||
|
||||
func (extension *namingStrategyExtension) UpdateStructDescriptor(structDescriptor *jsoniter.StructDescriptor) {
|
||||
for _, binding := range structDescriptor.Fields {
|
||||
binding.ToNames = []string{extension.translate(binding.Field.Name)}
|
||||
binding.FromNames = []string{extension.translate(binding.Field.Name)}
|
||||
binding.ToNames = []string{extension.translate(binding.Field.Name())}
|
||||
binding.FromNames = []string{extension.translate(binding.Field.Name())}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,10 +16,10 @@ type privateFieldsExtension struct {
|
||||
|
||||
func (extension *privateFieldsExtension) UpdateStructDescriptor(structDescriptor *jsoniter.StructDescriptor) {
|
||||
for _, binding := range structDescriptor.Fields {
|
||||
isPrivate := unicode.IsLower(rune(binding.Field.Name[0]))
|
||||
isPrivate := unicode.IsLower(rune(binding.Field.Name()[0]))
|
||||
if isPrivate {
|
||||
binding.FromNames = []string{binding.Field.Name}
|
||||
binding.ToNames = []string{binding.Field.Name}
|
||||
binding.FromNames = []string{binding.Field.Name()}
|
||||
binding.ToNames = []string{binding.Field.Name()}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
51
reflect.go
51
reflect.go
@ -36,8 +36,8 @@ type checkIsEmpty interface {
|
||||
type ctx struct {
|
||||
*frozenConfig
|
||||
prefix string
|
||||
encoders map[reflect.Type]ValEncoder
|
||||
decoders map[reflect.Type]ValDecoder
|
||||
encoders map[reflect2.Type]ValEncoder
|
||||
decoders map[reflect2.Type]ValDecoder
|
||||
}
|
||||
|
||||
func (b *ctx) append(prefix string) *ctx {
|
||||
@ -51,7 +51,7 @@ func (b *ctx) append(prefix string) *ctx {
|
||||
|
||||
// ReadVal copy the underlying JSON into go interface, same as json.Unmarshal
|
||||
func (iter *Iterator) ReadVal(obj interface{}) {
|
||||
typ := reflect.TypeOf(obj)
|
||||
typ := reflect2.TypeOf(obj)
|
||||
if typ.Kind() != reflect.Ptr {
|
||||
iter.ReportError("ReadVal", "can only unmarshal into pointer")
|
||||
return
|
||||
@ -71,13 +71,13 @@ func (stream *Stream) WriteVal(val interface{}) {
|
||||
stream.WriteNil()
|
||||
return
|
||||
}
|
||||
typ := reflect.TypeOf(val)
|
||||
typ := reflect2.TypeOf(val)
|
||||
encoder := stream.cfg.EncoderOf(typ)
|
||||
encoder.Encode(reflect2.PtrOf(val), stream)
|
||||
}
|
||||
|
||||
func (cfg *frozenConfig) DecoderOf(typ reflect.Type) ValDecoder {
|
||||
cacheKey := typ
|
||||
func (cfg *frozenConfig) DecoderOf(typ reflect2.Type) ValDecoder {
|
||||
cacheKey := typ.RType()
|
||||
decoder := cfg.getDecoderFromCache(cacheKey)
|
||||
if decoder != nil {
|
||||
return decoder
|
||||
@ -85,15 +85,16 @@ func (cfg *frozenConfig) DecoderOf(typ reflect.Type) ValDecoder {
|
||||
ctx := &ctx{
|
||||
frozenConfig: cfg,
|
||||
prefix: "",
|
||||
decoders: map[reflect.Type]ValDecoder{},
|
||||
encoders: map[reflect.Type]ValEncoder{},
|
||||
decoders: map[reflect2.Type]ValDecoder{},
|
||||
encoders: map[reflect2.Type]ValEncoder{},
|
||||
}
|
||||
decoder = decoderOfType(ctx, typ.Elem())
|
||||
ptrType := typ.(*reflect2.UnsafePtrType)
|
||||
decoder = decoderOfType(ctx, ptrType.Elem())
|
||||
cfg.addDecoderToCache(cacheKey, decoder)
|
||||
return decoder
|
||||
}
|
||||
|
||||
func decoderOfType(ctx *ctx, typ reflect.Type) ValDecoder {
|
||||
func decoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder {
|
||||
decoder := getTypeDecoderFromExtension(ctx, typ)
|
||||
if decoder != nil {
|
||||
return decoder
|
||||
@ -108,7 +109,7 @@ func decoderOfType(ctx *ctx, typ reflect.Type) ValDecoder {
|
||||
return decoder
|
||||
}
|
||||
|
||||
func createDecoderOfType(ctx *ctx, typ reflect.Type) ValDecoder {
|
||||
func createDecoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder {
|
||||
decoder := ctx.decoders[typ]
|
||||
if decoder != nil {
|
||||
return decoder
|
||||
@ -120,7 +121,7 @@ func createDecoderOfType(ctx *ctx, typ reflect.Type) ValDecoder {
|
||||
return decoder
|
||||
}
|
||||
|
||||
func _createDecoderOfType(ctx *ctx, typ reflect.Type) ValDecoder {
|
||||
func _createDecoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder {
|
||||
decoder := createDecoderOfJsonRawMessage(ctx, typ)
|
||||
if decoder != nil {
|
||||
return decoder
|
||||
@ -143,8 +144,8 @@ func _createDecoderOfType(ctx *ctx, typ reflect.Type) ValDecoder {
|
||||
}
|
||||
switch typ.Kind() {
|
||||
case reflect.Interface:
|
||||
if typ.NumMethod() > 0 {
|
||||
ifaceType := reflect2.Type2(typ).(*reflect2.UnsafeIFaceType)
|
||||
ifaceType, isIFace := typ.(*reflect2.UnsafeIFaceType)
|
||||
if isIFace {
|
||||
return &ifaceDecoder{valType: ifaceType}
|
||||
}
|
||||
return &efaceDecoder{}
|
||||
@ -163,8 +164,8 @@ func _createDecoderOfType(ctx *ctx, typ reflect.Type) ValDecoder {
|
||||
}
|
||||
}
|
||||
|
||||
func (cfg *frozenConfig) EncoderOf(typ reflect.Type) ValEncoder {
|
||||
cacheKey := typ
|
||||
func (cfg *frozenConfig) EncoderOf(typ reflect2.Type) ValEncoder {
|
||||
cacheKey := typ.RType()
|
||||
encoder := cfg.getEncoderFromCache(cacheKey)
|
||||
if encoder != nil {
|
||||
return encoder
|
||||
@ -172,11 +173,11 @@ func (cfg *frozenConfig) EncoderOf(typ reflect.Type) ValEncoder {
|
||||
ctx := &ctx{
|
||||
frozenConfig: cfg,
|
||||
prefix: "",
|
||||
decoders: map[reflect.Type]ValDecoder{},
|
||||
encoders: map[reflect.Type]ValEncoder{},
|
||||
decoders: map[reflect2.Type]ValDecoder{},
|
||||
encoders: map[reflect2.Type]ValEncoder{},
|
||||
}
|
||||
encoder = encoderOfType(ctx, typ)
|
||||
if shouldFixOnePtr(typ) {
|
||||
if typ.LikePtr() {
|
||||
encoder = &onePtrEncoder{encoder}
|
||||
}
|
||||
cfg.addEncoderToCache(cacheKey, encoder)
|
||||
@ -195,11 +196,7 @@ func (encoder *onePtrEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
||||
encoder.encoder.Encode(unsafe.Pointer(&ptr), stream)
|
||||
}
|
||||
|
||||
func shouldFixOnePtr(typ reflect.Type) bool {
|
||||
return reflect2.Type2(typ).LikePtr()
|
||||
}
|
||||
|
||||
func encoderOfType(ctx *ctx, typ reflect.Type) ValEncoder {
|
||||
func encoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder {
|
||||
encoder := getTypeEncoderFromExtension(ctx, typ)
|
||||
if encoder != nil {
|
||||
return encoder
|
||||
@ -214,7 +211,7 @@ func encoderOfType(ctx *ctx, typ reflect.Type) ValEncoder {
|
||||
return encoder
|
||||
}
|
||||
|
||||
func createEncoderOfType(ctx *ctx, typ reflect.Type) ValEncoder {
|
||||
func createEncoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder {
|
||||
encoder := ctx.encoders[typ]
|
||||
if encoder != nil {
|
||||
return encoder
|
||||
@ -225,7 +222,7 @@ func createEncoderOfType(ctx *ctx, typ reflect.Type) ValEncoder {
|
||||
placeholder.encoder = encoder
|
||||
return encoder
|
||||
}
|
||||
func _createEncoderOfType(ctx *ctx, typ reflect.Type) ValEncoder {
|
||||
func _createEncoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder {
|
||||
encoder := createEncoderOfJsonRawMessage(ctx, typ)
|
||||
if encoder != nil {
|
||||
return encoder
|
||||
@ -249,7 +246,7 @@ func _createEncoderOfType(ctx *ctx, typ reflect.Type) ValEncoder {
|
||||
kind := typ.Kind()
|
||||
switch kind {
|
||||
case reflect.Interface:
|
||||
return &dynamicEncoder{reflect2.Type2(typ)}
|
||||
return &dynamicEncoder{typ}
|
||||
case reflect.Struct:
|
||||
return encoderOfStruct(ctx, typ)
|
||||
case reflect.Array:
|
||||
|
@ -3,21 +3,23 @@ package jsoniter
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"unsafe"
|
||||
"github.com/v2pro/plz/reflect2"
|
||||
)
|
||||
|
||||
func decoderOfArray(ctx *ctx, typ reflect.Type) ValDecoder {
|
||||
decoder := decoderOfType(ctx.append("[arrayElem]"), typ.Elem())
|
||||
return &arrayDecoder{typ, typ.Elem(), decoder}
|
||||
func decoderOfArray(ctx *ctx, typ reflect2.Type) ValDecoder {
|
||||
arrayType := typ.(*reflect2.UnsafeArrayType)
|
||||
decoder := decoderOfType(ctx.append("[arrayElem]"), arrayType.Elem())
|
||||
return &arrayDecoder{arrayType, decoder}
|
||||
}
|
||||
|
||||
func encoderOfArray(ctx *ctx, typ reflect.Type) ValEncoder {
|
||||
if typ.Len() == 0 {
|
||||
func encoderOfArray(ctx *ctx, typ reflect2.Type) ValEncoder {
|
||||
arrayType := typ.(*reflect2.UnsafeArrayType)
|
||||
if arrayType.Len() == 0 {
|
||||
return emptyArrayEncoder{}
|
||||
}
|
||||
encoder := encoderOfType(ctx.append("[arrayElem]"), typ.Elem())
|
||||
return &arrayEncoder{typ, typ.Elem(), encoder}
|
||||
encoder := encoderOfType(ctx.append("[arrayElem]"), arrayType.Elem())
|
||||
return &arrayEncoder{arrayType, encoder}
|
||||
}
|
||||
|
||||
type emptyArrayEncoder struct{}
|
||||
@ -31,8 +33,7 @@ func (encoder emptyArrayEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||
}
|
||||
|
||||
type arrayEncoder struct {
|
||||
arrayType reflect.Type
|
||||
elemType reflect.Type
|
||||
arrayType *reflect2.UnsafeArrayType
|
||||
elemEncoder ValEncoder
|
||||
}
|
||||
|
||||
@ -42,8 +43,8 @@ func (encoder *arrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
||||
encoder.elemEncoder.Encode(elemPtr, stream)
|
||||
for i := 1; i < encoder.arrayType.Len(); i++ {
|
||||
stream.WriteMore()
|
||||
elemPtr = unsafe.Pointer(uintptr(elemPtr) + encoder.elemType.Size())
|
||||
encoder.elemEncoder.Encode(unsafe.Pointer(elemPtr), stream)
|
||||
elemPtr = encoder.arrayType.UnsafeGetIndex(ptr, i)
|
||||
encoder.elemEncoder.Encode(elemPtr, stream)
|
||||
}
|
||||
stream.WriteArrayEnd()
|
||||
if stream.Error != nil && stream.Error != io.EOF {
|
||||
@ -56,8 +57,7 @@ func (encoder *arrayEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||
}
|
||||
|
||||
type arrayDecoder struct {
|
||||
arrayType reflect.Type
|
||||
elemType reflect.Type
|
||||
arrayType *reflect2.UnsafeArrayType
|
||||
elemDecoder ValDecoder
|
||||
}
|
||||
|
||||
@ -69,14 +69,36 @@ func (decoder *arrayDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
||||
}
|
||||
|
||||
func (decoder *arrayDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) {
|
||||
offset := uintptr(0)
|
||||
iter.ReadArrayCB(func(iter *Iterator) bool {
|
||||
if offset < decoder.arrayType.Size() {
|
||||
decoder.elemDecoder.Decode(unsafe.Pointer(uintptr(ptr)+offset), iter)
|
||||
offset += decoder.elemType.Size()
|
||||
} else {
|
||||
c := iter.nextToken()
|
||||
arrayType := decoder.arrayType
|
||||
if c == 'n' {
|
||||
iter.skipThreeBytes('u', 'l', 'l')
|
||||
return
|
||||
}
|
||||
if c != '[' {
|
||||
iter.ReportError("decode array", "expect [ or n, but found "+string([]byte{c}))
|
||||
return
|
||||
}
|
||||
c = iter.nextToken()
|
||||
if c == ']' {
|
||||
return
|
||||
}
|
||||
iter.unreadByte()
|
||||
elemPtr := arrayType.UnsafeGetIndex(ptr, 0)
|
||||
decoder.elemDecoder.Decode(elemPtr, iter)
|
||||
length := 1
|
||||
for c = iter.nextToken(); c == ','; c = iter.nextToken() {
|
||||
if length >= arrayType.Len() {
|
||||
iter.Skip()
|
||||
continue
|
||||
}
|
||||
return true
|
||||
})
|
||||
idx := length
|
||||
length += 1
|
||||
elemPtr = arrayType.UnsafeGetIndex(ptr, idx)
|
||||
decoder.elemDecoder.Decode(elemPtr, iter)
|
||||
}
|
||||
if c != ']' {
|
||||
iter.ReportError("decode array", "expect ], but found "+string([]byte{c}))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ var extensions = []Extension{}
|
||||
|
||||
// StructDescriptor describe how should we encode/decode the struct
|
||||
type StructDescriptor struct {
|
||||
Type reflect.Type
|
||||
Type reflect2.Type
|
||||
Fields []*Binding
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ type StructDescriptor struct {
|
||||
// Can not use map here to keep field orders.
|
||||
func (structDescriptor *StructDescriptor) GetField(fieldName string) *Binding {
|
||||
for _, binding := range structDescriptor.Fields {
|
||||
if binding.Field.Name == fieldName {
|
||||
if binding.Field.Name() == fieldName {
|
||||
return binding
|
||||
}
|
||||
}
|
||||
@ -36,7 +36,7 @@ func (structDescriptor *StructDescriptor) GetField(fieldName string) *Binding {
|
||||
// Binding describe how should we encode/decode the struct field
|
||||
type Binding struct {
|
||||
levels []int
|
||||
Field *reflect.StructField
|
||||
Field reflect2.StructField
|
||||
FromNames []string
|
||||
ToNames []string
|
||||
Encoder ValEncoder
|
||||
@ -47,10 +47,10 @@ type Binding struct {
|
||||
// Can also rename fields by UpdateStructDescriptor.
|
||||
type Extension interface {
|
||||
UpdateStructDescriptor(structDescriptor *StructDescriptor)
|
||||
CreateDecoder(typ reflect.Type) ValDecoder
|
||||
CreateEncoder(typ reflect.Type) ValEncoder
|
||||
DecorateDecoder(typ reflect.Type, decoder ValDecoder) ValDecoder
|
||||
DecorateEncoder(typ reflect.Type, encoder ValEncoder) ValEncoder
|
||||
CreateDecoder(typ reflect2.Type) ValDecoder
|
||||
CreateEncoder(typ reflect2.Type) ValEncoder
|
||||
DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder
|
||||
DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder
|
||||
}
|
||||
|
||||
// DummyExtension embed this type get dummy implementation for all methods of Extension
|
||||
@ -62,74 +62,74 @@ func (extension *DummyExtension) UpdateStructDescriptor(structDescriptor *Struct
|
||||
}
|
||||
|
||||
// CreateDecoder No-op
|
||||
func (extension *DummyExtension) CreateDecoder(typ reflect.Type) ValDecoder {
|
||||
func (extension *DummyExtension) CreateDecoder(typ reflect2.Type) ValDecoder {
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateEncoder No-op
|
||||
func (extension *DummyExtension) CreateEncoder(typ reflect.Type) ValEncoder {
|
||||
func (extension *DummyExtension) CreateEncoder(typ reflect2.Type) ValEncoder {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DecorateDecoder No-op
|
||||
func (extension *DummyExtension) DecorateDecoder(typ reflect.Type, decoder ValDecoder) ValDecoder {
|
||||
func (extension *DummyExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder {
|
||||
return decoder
|
||||
}
|
||||
|
||||
// DecorateEncoder No-op
|
||||
func (extension *DummyExtension) DecorateEncoder(typ reflect.Type, encoder ValEncoder) ValEncoder {
|
||||
func (extension *DummyExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder {
|
||||
return encoder
|
||||
}
|
||||
|
||||
type EncoderExtension map[reflect.Type]ValEncoder
|
||||
type EncoderExtension map[reflect2.Type]ValEncoder
|
||||
|
||||
// UpdateStructDescriptor No-op
|
||||
func (extension EncoderExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) {
|
||||
}
|
||||
|
||||
// CreateDecoder No-op
|
||||
func (extension EncoderExtension) CreateDecoder(typ reflect.Type) ValDecoder {
|
||||
func (extension EncoderExtension) CreateDecoder(typ reflect2.Type) ValDecoder {
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateEncoder get encoder from map
|
||||
func (extension EncoderExtension) CreateEncoder(typ reflect.Type) ValEncoder {
|
||||
func (extension EncoderExtension) CreateEncoder(typ reflect2.Type) ValEncoder {
|
||||
return extension[typ]
|
||||
}
|
||||
|
||||
// DecorateDecoder No-op
|
||||
func (extension EncoderExtension) DecorateDecoder(typ reflect.Type, decoder ValDecoder) ValDecoder {
|
||||
func (extension EncoderExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder {
|
||||
return decoder
|
||||
}
|
||||
|
||||
// DecorateEncoder No-op
|
||||
func (extension EncoderExtension) DecorateEncoder(typ reflect.Type, encoder ValEncoder) ValEncoder {
|
||||
func (extension EncoderExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder {
|
||||
return encoder
|
||||
}
|
||||
|
||||
type DecoderExtension map[reflect.Type]ValDecoder
|
||||
type DecoderExtension map[reflect2.Type]ValDecoder
|
||||
|
||||
// UpdateStructDescriptor No-op
|
||||
func (extension DecoderExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) {
|
||||
}
|
||||
|
||||
// CreateDecoder get decoder from map
|
||||
func (extension DecoderExtension) CreateDecoder(typ reflect.Type) ValDecoder {
|
||||
func (extension DecoderExtension) CreateDecoder(typ reflect2.Type) ValDecoder {
|
||||
return extension[typ]
|
||||
}
|
||||
|
||||
// CreateEncoder No-op
|
||||
func (extension DecoderExtension) CreateEncoder(typ reflect.Type) ValEncoder {
|
||||
func (extension DecoderExtension) CreateEncoder(typ reflect2.Type) ValEncoder {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DecorateDecoder No-op
|
||||
func (extension DecoderExtension) DecorateDecoder(typ reflect.Type, decoder ValDecoder) ValDecoder {
|
||||
func (extension DecoderExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder {
|
||||
return decoder
|
||||
}
|
||||
|
||||
// DecorateEncoder No-op
|
||||
func (extension DecoderExtension) DecorateEncoder(typ reflect.Type, encoder ValEncoder) ValEncoder {
|
||||
func (extension DecoderExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder {
|
||||
return encoder
|
||||
}
|
||||
|
||||
@ -208,7 +208,7 @@ func RegisterExtension(extension Extension) {
|
||||
extensions = append(extensions, extension)
|
||||
}
|
||||
|
||||
func getTypeDecoderFromExtension(ctx *ctx, typ reflect.Type) ValDecoder {
|
||||
func getTypeDecoderFromExtension(ctx *ctx, typ reflect2.Type) ValDecoder {
|
||||
decoder := _getTypeDecoderFromExtension(ctx, typ)
|
||||
if decoder != nil {
|
||||
for _, extension := range extensions {
|
||||
@ -220,7 +220,7 @@ func getTypeDecoderFromExtension(ctx *ctx, typ reflect.Type) ValDecoder {
|
||||
}
|
||||
return decoder
|
||||
}
|
||||
func _getTypeDecoderFromExtension(ctx *ctx, typ reflect.Type) ValDecoder {
|
||||
func _getTypeDecoderFromExtension(ctx *ctx, typ reflect2.Type) ValDecoder {
|
||||
for _, extension := range extensions {
|
||||
decoder := extension.CreateDecoder(typ)
|
||||
if decoder != nil {
|
||||
@ -239,15 +239,16 @@ func _getTypeDecoderFromExtension(ctx *ctx, typ reflect.Type) ValDecoder {
|
||||
return decoder
|
||||
}
|
||||
if typ.Kind() == reflect.Ptr {
|
||||
decoder := typeDecoders[typ.Elem().String()]
|
||||
ptrType := typ.(*reflect2.UnsafePtrType)
|
||||
decoder := typeDecoders[ptrType.Elem().String()]
|
||||
if decoder != nil {
|
||||
return &OptionalDecoder{reflect2.Type2(typ.Elem()), decoder}
|
||||
return &OptionalDecoder{ptrType.Elem(), decoder}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getTypeEncoderFromExtension(ctx *ctx, typ reflect.Type) ValEncoder {
|
||||
func getTypeEncoderFromExtension(ctx *ctx, typ reflect2.Type) ValEncoder {
|
||||
encoder := _getTypeEncoderFromExtension(ctx, typ)
|
||||
if encoder != nil {
|
||||
for _, extension := range extensions {
|
||||
@ -260,7 +261,7 @@ func getTypeEncoderFromExtension(ctx *ctx, typ reflect.Type) ValEncoder {
|
||||
return encoder
|
||||
}
|
||||
|
||||
func _getTypeEncoderFromExtension(ctx *ctx, typ reflect.Type) ValEncoder {
|
||||
func _getTypeEncoderFromExtension(ctx *ctx, typ reflect2.Type) ValEncoder {
|
||||
for _, extension := range extensions {
|
||||
encoder := extension.CreateEncoder(typ)
|
||||
if encoder != nil {
|
||||
@ -279,7 +280,8 @@ func _getTypeEncoderFromExtension(ctx *ctx, typ reflect.Type) ValEncoder {
|
||||
return encoder
|
||||
}
|
||||
if typ.Kind() == reflect.Ptr {
|
||||
encoder := typeEncoders[typ.Elem().String()]
|
||||
typePtr := typ.(*reflect2.UnsafePtrType)
|
||||
encoder := typeEncoders[typePtr.Elem().String()]
|
||||
if encoder != nil {
|
||||
return &OptionalEncoder{encoder}
|
||||
}
|
||||
@ -287,12 +289,13 @@ func _getTypeEncoderFromExtension(ctx *ctx, typ reflect.Type) ValEncoder {
|
||||
return nil
|
||||
}
|
||||
|
||||
func describeStruct(ctx *ctx, typ reflect.Type) *StructDescriptor {
|
||||
func describeStruct(ctx *ctx, typ reflect2.Type) *StructDescriptor {
|
||||
structType := typ.(*reflect2.UnsafeStructType)
|
||||
embeddedBindings := []*Binding{}
|
||||
bindings := []*Binding{}
|
||||
for i := 0; i < typ.NumField(); i++ {
|
||||
field := typ.Field(i)
|
||||
tag, hastag := field.Tag.Lookup(ctx.getTagKey())
|
||||
for i := 0; i < structType.NumField(); i++ {
|
||||
field := structType.Field(i)
|
||||
tag, hastag := field.Tag().Lookup(ctx.getTagKey())
|
||||
if ctx.onlyTaggedField && !hastag {
|
||||
continue
|
||||
}
|
||||
@ -300,43 +303,46 @@ func describeStruct(ctx *ctx, typ reflect.Type) *StructDescriptor {
|
||||
if tag == "-" {
|
||||
continue
|
||||
}
|
||||
if field.Anonymous && (tag == "" || tagParts[0] == "") {
|
||||
if field.Type.Kind() == reflect.Struct {
|
||||
structDescriptor := describeStruct(ctx, field.Type)
|
||||
if field.Anonymous() && (tag == "" || tagParts[0] == "") {
|
||||
if field.Type().Kind() == reflect.Struct {
|
||||
structDescriptor := describeStruct(ctx, field.Type())
|
||||
for _, binding := range structDescriptor.Fields {
|
||||
binding.levels = append([]int{i}, binding.levels...)
|
||||
omitempty := binding.Encoder.(*structFieldEncoder).omitempty
|
||||
binding.Encoder = &structFieldEncoder{&field, binding.Encoder, omitempty}
|
||||
binding.Decoder = &structFieldDecoder{&field, binding.Decoder}
|
||||
binding.Encoder = &structFieldEncoder{field, binding.Encoder, omitempty}
|
||||
binding.Decoder = &structFieldDecoder{field, binding.Decoder}
|
||||
embeddedBindings = append(embeddedBindings, binding)
|
||||
}
|
||||
continue
|
||||
} else if field.Type.Kind() == reflect.Ptr && field.Type.Elem().Kind() == reflect.Struct {
|
||||
structDescriptor := describeStruct(ctx, field.Type.Elem())
|
||||
for _, binding := range structDescriptor.Fields {
|
||||
binding.levels = append([]int{i}, binding.levels...)
|
||||
omitempty := binding.Encoder.(*structFieldEncoder).omitempty
|
||||
binding.Encoder = &dereferenceEncoder{binding.Encoder}
|
||||
binding.Encoder = &structFieldEncoder{&field, binding.Encoder, omitempty}
|
||||
binding.Decoder = &dereferenceDecoder{reflect2.Type2(field.Type.Elem()), binding.Decoder}
|
||||
binding.Decoder = &structFieldDecoder{&field, binding.Decoder}
|
||||
embeddedBindings = append(embeddedBindings, binding)
|
||||
} else if field.Type().Kind() == reflect.Ptr {
|
||||
ptrType := field.Type().(*reflect2.UnsafePtrType)
|
||||
if ptrType.Elem().Kind() == reflect.Struct {
|
||||
structDescriptor := describeStruct(ctx, ptrType.Elem())
|
||||
for _, binding := range structDescriptor.Fields {
|
||||
binding.levels = append([]int{i}, binding.levels...)
|
||||
omitempty := binding.Encoder.(*structFieldEncoder).omitempty
|
||||
binding.Encoder = &dereferenceEncoder{binding.Encoder}
|
||||
binding.Encoder = &structFieldEncoder{field, binding.Encoder, omitempty}
|
||||
binding.Decoder = &dereferenceDecoder{ptrType.Elem(), binding.Decoder}
|
||||
binding.Decoder = &structFieldDecoder{field, binding.Decoder}
|
||||
embeddedBindings = append(embeddedBindings, binding)
|
||||
}
|
||||
continue
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
fieldNames := calcFieldNames(field.Name, tagParts[0], tag)
|
||||
fieldCacheKey := fmt.Sprintf("%s/%s", typ.String(), field.Name)
|
||||
fieldNames := calcFieldNames(field.Name(), tagParts[0], tag)
|
||||
fieldCacheKey := fmt.Sprintf("%s/%s", typ.String(), field.Name())
|
||||
decoder := fieldDecoders[fieldCacheKey]
|
||||
if decoder == nil {
|
||||
decoder = decoderOfType(ctx.append(field.Name), field.Type)
|
||||
decoder = decoderOfType(ctx.append(field.Name()), field.Type())
|
||||
}
|
||||
encoder := fieldEncoders[fieldCacheKey]
|
||||
if encoder == nil {
|
||||
encoder = encoderOfType(ctx.append(field.Name), field.Type)
|
||||
encoder = encoderOfType(ctx.append(field.Name()), field.Type())
|
||||
}
|
||||
binding := &Binding{
|
||||
Field: &field,
|
||||
Field: field,
|
||||
FromNames: fieldNames,
|
||||
ToNames: fieldNames,
|
||||
Decoder: decoder,
|
||||
@ -347,7 +353,7 @@ func describeStruct(ctx *ctx, typ reflect.Type) *StructDescriptor {
|
||||
}
|
||||
return createStructDescriptor(ctx, typ, bindings, embeddedBindings)
|
||||
}
|
||||
func createStructDescriptor(ctx *ctx, typ reflect.Type, bindings []*Binding, embeddedBindings []*Binding) *StructDescriptor {
|
||||
func createStructDescriptor(ctx *ctx, typ reflect2.Type, bindings []*Binding, embeddedBindings []*Binding) *StructDescriptor {
|
||||
structDescriptor := &StructDescriptor{
|
||||
Type: typ,
|
||||
Fields: bindings,
|
||||
@ -366,21 +372,6 @@ func createStructDescriptor(ctx *ctx, typ reflect.Type, bindings []*Binding, emb
|
||||
return structDescriptor
|
||||
}
|
||||
|
||||
func isStructOnePtr(typ reflect.Type) bool {
|
||||
if typ.NumField() == 1 {
|
||||
firstField := typ.Field(0)
|
||||
switch firstField.Type.Kind() {
|
||||
case reflect.Ptr:
|
||||
return true
|
||||
case reflect.Map:
|
||||
return true
|
||||
case reflect.Struct:
|
||||
return isStructOnePtr(firstField.Type)
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type sortableBindings []*Binding
|
||||
|
||||
func (bindings sortableBindings) Len() int {
|
||||
@ -408,12 +399,12 @@ func (bindings sortableBindings) Swap(i, j int) {
|
||||
func processTags(structDescriptor *StructDescriptor, cfg *frozenConfig) {
|
||||
for _, binding := range structDescriptor.Fields {
|
||||
shouldOmitEmpty := false
|
||||
tagParts := strings.Split(binding.Field.Tag.Get(cfg.getTagKey()), ",")
|
||||
tagParts := strings.Split(binding.Field.Tag().Get(cfg.getTagKey()), ",")
|
||||
for _, tagPart := range tagParts[1:] {
|
||||
if tagPart == "omitempty" {
|
||||
shouldOmitEmpty = true
|
||||
} else if tagPart == "string" {
|
||||
if binding.Field.Type.Kind() == reflect.String {
|
||||
if binding.Field.Type().Kind() == reflect.String {
|
||||
binding.Decoder = &stringModeStringDecoder{binding.Decoder, cfg}
|
||||
binding.Encoder = &stringModeStringEncoder{binding.Encoder, cfg}
|
||||
} else {
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"unsafe"
|
||||
"reflect"
|
||||
"github.com/v2pro/plz/reflect2"
|
||||
)
|
||||
|
||||
type Number string
|
||||
@ -32,10 +32,10 @@ func CastJsonNumber(val interface{}) (string, bool) {
|
||||
return "", false
|
||||
}
|
||||
|
||||
var jsonNumberType = reflect.TypeOf((*json.Number)(nil)).Elem()
|
||||
var jsoniterNumberType = reflect.TypeOf((*Number)(nil)).Elem()
|
||||
var jsonNumberType = reflect2.TypeOfPtr((*json.Number)(nil)).Elem()
|
||||
var jsoniterNumberType = reflect2.TypeOfPtr((*Number)(nil)).Elem()
|
||||
|
||||
func createDecoderOfJsonNumber(ctx *ctx, typ reflect.Type) ValDecoder {
|
||||
func createDecoderOfJsonNumber(ctx *ctx, typ reflect2.Type) ValDecoder {
|
||||
if typ.AssignableTo(jsonNumberType) {
|
||||
return &jsonNumberCodec{}
|
||||
}
|
||||
@ -45,7 +45,7 @@ func createDecoderOfJsonNumber(ctx *ctx, typ reflect.Type) ValDecoder {
|
||||
return nil
|
||||
}
|
||||
|
||||
func createEncoderOfJsonNumber(ctx *ctx, typ reflect.Type) ValEncoder {
|
||||
func createEncoderOfJsonNumber(ctx *ctx, typ reflect2.Type) ValEncoder {
|
||||
if typ.AssignableTo(jsonNumberType) {
|
||||
return &jsonNumberCodec{}
|
||||
}
|
||||
|
@ -3,13 +3,13 @@ package jsoniter
|
||||
import (
|
||||
"unsafe"
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"github.com/v2pro/plz/reflect2"
|
||||
)
|
||||
|
||||
var jsonRawMessageType = reflect.TypeOf((*json.RawMessage)(nil)).Elem()
|
||||
var jsoniterRawMessageType = reflect.TypeOf((*RawMessage)(nil)).Elem()
|
||||
var jsonRawMessageType = reflect2.TypeOfPtr((*json.RawMessage)(nil)).Elem()
|
||||
var jsoniterRawMessageType = reflect2.TypeOfPtr((*RawMessage)(nil)).Elem()
|
||||
|
||||
func createEncoderOfJsonRawMessage(ctx *ctx, typ reflect.Type) ValEncoder {
|
||||
func createEncoderOfJsonRawMessage(ctx *ctx, typ reflect2.Type) ValEncoder {
|
||||
if typ == jsonRawMessageType {
|
||||
return &jsonRawMessageCodec{}
|
||||
}
|
||||
@ -19,7 +19,7 @@ func createEncoderOfJsonRawMessage(ctx *ctx, typ reflect.Type) ValEncoder {
|
||||
return nil
|
||||
}
|
||||
|
||||
func createDecoderOfJsonRawMessage(ctx *ctx, typ reflect.Type) ValDecoder {
|
||||
func createDecoderOfJsonRawMessage(ctx *ctx, typ reflect2.Type) ValDecoder {
|
||||
if typ == jsonRawMessageType {
|
||||
return &jsonRawMessageCodec{}
|
||||
}
|
||||
|
@ -8,10 +8,10 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func decoderOfMap(ctx *ctx, typ reflect.Type) ValDecoder {
|
||||
keyDecoder := decoderOfMapKey(ctx.append("[mapKey]"), typ.Key())
|
||||
elemDecoder := decoderOfType(ctx.append("[mapElem]"), typ.Elem())
|
||||
mapType := reflect2.Type2(typ).(*reflect2.UnsafeMapType)
|
||||
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(),
|
||||
@ -21,25 +21,26 @@ func decoderOfMap(ctx *ctx, typ reflect.Type) ValDecoder {
|
||||
}
|
||||
}
|
||||
|
||||
func encoderOfMap(ctx *ctx, typ reflect.Type) ValEncoder {
|
||||
func encoderOfMap(ctx *ctx, typ reflect2.Type) ValEncoder {
|
||||
mapType := typ.(*reflect2.UnsafeMapType)
|
||||
if ctx.sortMapKeys {
|
||||
return &sortKeysMapEncoder{
|
||||
mapType: reflect2.Type2(typ).(*reflect2.UnsafeMapType),
|
||||
keyEncoder: encoderOfMapKey(ctx.append("[mapKey]"), typ.Key()),
|
||||
elemEncoder: encoderOfType(ctx.append("[mapElem]"), typ.Elem()),
|
||||
mapType: mapType,
|
||||
keyEncoder: encoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()),
|
||||
elemEncoder: encoderOfType(ctx.append("[mapElem]"), mapType.Elem()),
|
||||
}
|
||||
}
|
||||
return &mapEncoder{
|
||||
mapType: reflect2.Type2(typ).(*reflect2.UnsafeMapType),
|
||||
keyEncoder: encoderOfMapKey(ctx.append("[mapKey]"), typ.Key()),
|
||||
elemEncoder: encoderOfType(ctx.append("[mapElem]"), typ.Elem()),
|
||||
mapType: mapType,
|
||||
keyEncoder: encoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()),
|
||||
elemEncoder: encoderOfType(ctx.append("[mapElem]"), mapType.Elem()),
|
||||
}
|
||||
}
|
||||
|
||||
func decoderOfMapKey(ctx *ctx, typ reflect.Type) ValDecoder {
|
||||
func decoderOfMapKey(ctx *ctx, typ reflect2.Type) ValDecoder {
|
||||
switch typ.Kind() {
|
||||
case reflect.String:
|
||||
return decoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String).Type1())
|
||||
return decoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String))
|
||||
case reflect.Bool,
|
||||
reflect.Uint8, reflect.Int8,
|
||||
reflect.Uint16, reflect.Int16,
|
||||
@ -48,30 +49,30 @@ func decoderOfMapKey(ctx *ctx, typ reflect.Type) ValDecoder {
|
||||
reflect.Uint, reflect.Int,
|
||||
reflect.Float32, reflect.Float64,
|
||||
reflect.Uintptr:
|
||||
typ = reflect2.DefaultTypeOfKind(typ.Kind()).Type1()
|
||||
typ = reflect2.DefaultTypeOfKind(typ.Kind())
|
||||
return &numericMapKeyDecoder{decoderOfType(ctx, typ)}
|
||||
default:
|
||||
ptrType := reflect.PtrTo(typ)
|
||||
ptrType := reflect2.PtrTo(typ)
|
||||
if ptrType.Implements(textMarshalerType) {
|
||||
return &referenceDecoder{
|
||||
&textUnmarshalerDecoder{
|
||||
valType: reflect2.Type2(ptrType),
|
||||
valType: ptrType,
|
||||
},
|
||||
}
|
||||
}
|
||||
if typ.Implements(textMarshalerType) {
|
||||
return &textUnmarshalerDecoder{
|
||||
valType: reflect2.Type2(typ),
|
||||
valType: typ,
|
||||
}
|
||||
}
|
||||
return &lazyErrorDecoder{err: fmt.Errorf("unsupported map key type: %v", typ)}
|
||||
}
|
||||
}
|
||||
|
||||
func encoderOfMapKey(ctx *ctx, typ reflect.Type) ValEncoder {
|
||||
func encoderOfMapKey(ctx *ctx, typ reflect2.Type) ValEncoder {
|
||||
switch typ.Kind() {
|
||||
case reflect.String:
|
||||
return encoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String).Type1())
|
||||
return encoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String))
|
||||
case reflect.Bool,
|
||||
reflect.Uint8, reflect.Int8,
|
||||
reflect.Uint16, reflect.Int16,
|
||||
@ -80,18 +81,18 @@ func encoderOfMapKey(ctx *ctx, typ reflect.Type) ValEncoder {
|
||||
reflect.Uint, reflect.Int,
|
||||
reflect.Float32, reflect.Float64,
|
||||
reflect.Uintptr:
|
||||
typ = reflect2.DefaultTypeOfKind(typ.Kind()).Type1()
|
||||
typ = reflect2.DefaultTypeOfKind(typ.Kind())
|
||||
return &numericMapKeyEncoder{encoderOfType(ctx, typ)}
|
||||
default:
|
||||
if typ == textMarshalerType {
|
||||
return &directTextMarshalerEncoder{
|
||||
stringEncoder: ctx.EncoderOf(reflect.TypeOf("")),
|
||||
stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")),
|
||||
}
|
||||
}
|
||||
if typ.Implements(textMarshalerType) {
|
||||
return &textMarshalerEncoder{
|
||||
valType: reflect2.Type2(typ),
|
||||
stringEncoder: ctx.EncoderOf(reflect.TypeOf("")),
|
||||
valType: typ,
|
||||
stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")),
|
||||
}
|
||||
}
|
||||
return &lazyErrorEncoder{err: fmt.Errorf("unsupported map key type: %v", typ)}
|
||||
|
@ -5,30 +5,29 @@ import (
|
||||
"unsafe"
|
||||
"encoding"
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
var marshalerType = reflect.TypeOf((*json.Marshaler)(nil)).Elem()
|
||||
var unmarshalerType = reflect.TypeOf((*json.Unmarshaler)(nil)).Elem()
|
||||
var textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
|
||||
var textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
|
||||
var marshalerType = reflect2.TypeOfPtr((*json.Marshaler)(nil)).Elem()
|
||||
var unmarshalerType = reflect2.TypeOfPtr((*json.Unmarshaler)(nil)).Elem()
|
||||
var textMarshalerType = reflect2.TypeOfPtr((*encoding.TextMarshaler)(nil)).Elem()
|
||||
var textUnmarshalerType = reflect2.TypeOfPtr((*encoding.TextUnmarshaler)(nil)).Elem()
|
||||
|
||||
func createDecoderOfMarshaler(ctx *ctx, typ reflect.Type) ValDecoder {
|
||||
ptrType := reflect.PtrTo(typ)
|
||||
func createDecoderOfMarshaler(ctx *ctx, typ reflect2.Type) ValDecoder {
|
||||
ptrType := reflect2.PtrTo(typ)
|
||||
if ptrType.Implements(unmarshalerType) {
|
||||
return &referenceDecoder{
|
||||
&unmarshalerDecoder{reflect2.Type2(ptrType)},
|
||||
&unmarshalerDecoder{ptrType},
|
||||
}
|
||||
}
|
||||
if ptrType.Implements(textUnmarshalerType) {
|
||||
return &referenceDecoder{
|
||||
&textUnmarshalerDecoder{reflect2.Type2(ptrType)},
|
||||
&textUnmarshalerDecoder{ptrType},
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func createEncoderOfMarshaler(ctx *ctx, typ reflect.Type) ValEncoder {
|
||||
func createEncoderOfMarshaler(ctx *ctx, typ reflect2.Type) ValEncoder {
|
||||
if typ == marshalerType {
|
||||
checkIsEmpty := createCheckIsEmpty(ctx, typ)
|
||||
var encoder ValEncoder = &directMarshalerEncoder{
|
||||
@ -39,16 +38,16 @@ func createEncoderOfMarshaler(ctx *ctx, typ reflect.Type) ValEncoder {
|
||||
if typ.Implements(marshalerType) {
|
||||
checkIsEmpty := createCheckIsEmpty(ctx, typ)
|
||||
var encoder ValEncoder = &marshalerEncoder{
|
||||
valType: reflect2.Type2(typ),
|
||||
valType: typ,
|
||||
checkIsEmpty: checkIsEmpty,
|
||||
}
|
||||
return encoder
|
||||
}
|
||||
ptrType := reflect.PtrTo(typ)
|
||||
ptrType := reflect2.PtrTo(typ)
|
||||
if ctx.prefix != "" && ptrType.Implements(marshalerType) {
|
||||
checkIsEmpty := createCheckIsEmpty(ctx, ptrType)
|
||||
var encoder ValEncoder = &marshalerEncoder{
|
||||
valType: reflect2.Type2(ptrType),
|
||||
valType: ptrType,
|
||||
checkIsEmpty: checkIsEmpty,
|
||||
}
|
||||
return &referenceEncoder{encoder}
|
||||
@ -57,15 +56,15 @@ func createEncoderOfMarshaler(ctx *ctx, typ reflect.Type) ValEncoder {
|
||||
checkIsEmpty := createCheckIsEmpty(ctx, typ)
|
||||
var encoder ValEncoder = &directTextMarshalerEncoder{
|
||||
checkIsEmpty: checkIsEmpty,
|
||||
stringEncoder: ctx.EncoderOf(reflect.TypeOf("")),
|
||||
stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")),
|
||||
}
|
||||
return encoder
|
||||
}
|
||||
if typ.Implements(textMarshalerType) {
|
||||
checkIsEmpty := createCheckIsEmpty(ctx, typ)
|
||||
var encoder ValEncoder = &textMarshalerEncoder{
|
||||
valType: reflect2.Type2(typ),
|
||||
stringEncoder: ctx.EncoderOf(reflect.TypeOf("")),
|
||||
valType: typ,
|
||||
stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")),
|
||||
checkIsEmpty: checkIsEmpty,
|
||||
}
|
||||
return encoder
|
||||
@ -74,8 +73,8 @@ func createEncoderOfMarshaler(ctx *ctx, typ reflect.Type) ValEncoder {
|
||||
if ctx.prefix != "" && ptrType.Implements(textMarshalerType) {
|
||||
checkIsEmpty := createCheckIsEmpty(ctx, ptrType)
|
||||
var encoder ValEncoder = &textMarshalerEncoder{
|
||||
valType: reflect2.Type2(ptrType),
|
||||
stringEncoder: ctx.EncoderOf(reflect.TypeOf("")),
|
||||
valType: ptrType,
|
||||
stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")),
|
||||
checkIsEmpty: checkIsEmpty,
|
||||
}
|
||||
return &referenceEncoder{encoder}
|
||||
|
@ -7,8 +7,8 @@ import (
|
||||
"github.com/v2pro/plz/reflect2"
|
||||
)
|
||||
|
||||
func createEncoderOfNative(ctx *ctx, typ reflect.Type) ValEncoder {
|
||||
if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 {
|
||||
func createEncoderOfNative(ctx *ctx, typ reflect2.Type) ValEncoder {
|
||||
if typ.Kind() == reflect.Slice && typ.(reflect2.SliceType).Elem().Kind() == reflect.Uint8 {
|
||||
sliceDecoder := decoderOfSlice(ctx, typ)
|
||||
return &base64Codec{sliceDecoder: sliceDecoder}
|
||||
}
|
||||
@ -17,85 +17,85 @@ func createEncoderOfNative(ctx *ctx, typ reflect.Type) ValEncoder {
|
||||
switch kind {
|
||||
case reflect.String:
|
||||
if typeName != "string" {
|
||||
return encoderOfType(ctx, reflect.TypeOf((*string)(nil)).Elem())
|
||||
return encoderOfType(ctx, reflect2.TypeOfPtr((*string)(nil)).Elem())
|
||||
}
|
||||
return &stringCodec{}
|
||||
case reflect.Int:
|
||||
if typeName != "int" {
|
||||
return encoderOfType(ctx, reflect.TypeOf((*int)(nil)).Elem())
|
||||
return encoderOfType(ctx, reflect2.TypeOfPtr((*int)(nil)).Elem())
|
||||
}
|
||||
return &intCodec{}
|
||||
case reflect.Int8:
|
||||
if typeName != "int8" {
|
||||
return encoderOfType(ctx, reflect.TypeOf((*int8)(nil)).Elem())
|
||||
return encoderOfType(ctx, reflect2.TypeOfPtr((*int8)(nil)).Elem())
|
||||
}
|
||||
return &int8Codec{}
|
||||
case reflect.Int16:
|
||||
if typeName != "int16" {
|
||||
return encoderOfType(ctx, reflect.TypeOf((*int16)(nil)).Elem())
|
||||
return encoderOfType(ctx, reflect2.TypeOfPtr((*int16)(nil)).Elem())
|
||||
}
|
||||
return &int16Codec{}
|
||||
case reflect.Int32:
|
||||
if typeName != "int32" {
|
||||
return encoderOfType(ctx, reflect.TypeOf((*int32)(nil)).Elem())
|
||||
return encoderOfType(ctx, reflect2.TypeOfPtr((*int32)(nil)).Elem())
|
||||
}
|
||||
return &int32Codec{}
|
||||
case reflect.Int64:
|
||||
if typeName != "int64" {
|
||||
return encoderOfType(ctx, reflect.TypeOf((*int64)(nil)).Elem())
|
||||
return encoderOfType(ctx, reflect2.TypeOfPtr((*int64)(nil)).Elem())
|
||||
}
|
||||
return &int64Codec{}
|
||||
case reflect.Uint:
|
||||
if typeName != "uint" {
|
||||
return encoderOfType(ctx, reflect.TypeOf((*uint)(nil)).Elem())
|
||||
return encoderOfType(ctx, reflect2.TypeOfPtr((*uint)(nil)).Elem())
|
||||
}
|
||||
return &uintCodec{}
|
||||
case reflect.Uint8:
|
||||
if typeName != "uint8" {
|
||||
return encoderOfType(ctx, reflect.TypeOf((*uint8)(nil)).Elem())
|
||||
return encoderOfType(ctx, reflect2.TypeOfPtr((*uint8)(nil)).Elem())
|
||||
}
|
||||
return &uint8Codec{}
|
||||
case reflect.Uint16:
|
||||
if typeName != "uint16" {
|
||||
return encoderOfType(ctx, reflect.TypeOf((*uint16)(nil)).Elem())
|
||||
return encoderOfType(ctx, reflect2.TypeOfPtr((*uint16)(nil)).Elem())
|
||||
}
|
||||
return &uint16Codec{}
|
||||
case reflect.Uint32:
|
||||
if typeName != "uint32" {
|
||||
return encoderOfType(ctx, reflect.TypeOf((*uint32)(nil)).Elem())
|
||||
return encoderOfType(ctx, reflect2.TypeOfPtr((*uint32)(nil)).Elem())
|
||||
}
|
||||
return &uint32Codec{}
|
||||
case reflect.Uintptr:
|
||||
if typeName != "uintptr" {
|
||||
return encoderOfType(ctx, reflect.TypeOf((*uintptr)(nil)).Elem())
|
||||
return encoderOfType(ctx, reflect2.TypeOfPtr((*uintptr)(nil)).Elem())
|
||||
}
|
||||
return &uintptrCodec{}
|
||||
case reflect.Uint64:
|
||||
if typeName != "uint64" {
|
||||
return encoderOfType(ctx, reflect.TypeOf((*uint64)(nil)).Elem())
|
||||
return encoderOfType(ctx, reflect2.TypeOfPtr((*uint64)(nil)).Elem())
|
||||
}
|
||||
return &uint64Codec{}
|
||||
case reflect.Float32:
|
||||
if typeName != "float32" {
|
||||
return encoderOfType(ctx, reflect.TypeOf((*float32)(nil)).Elem())
|
||||
return encoderOfType(ctx, reflect2.TypeOfPtr((*float32)(nil)).Elem())
|
||||
}
|
||||
return &float32Codec{}
|
||||
case reflect.Float64:
|
||||
if typeName != "float64" {
|
||||
return encoderOfType(ctx, reflect.TypeOf((*float64)(nil)).Elem())
|
||||
return encoderOfType(ctx, reflect2.TypeOfPtr((*float64)(nil)).Elem())
|
||||
}
|
||||
return &float64Codec{}
|
||||
case reflect.Bool:
|
||||
if typeName != "bool" {
|
||||
return encoderOfType(ctx, reflect.TypeOf((*bool)(nil)).Elem())
|
||||
return encoderOfType(ctx, reflect2.TypeOfPtr((*bool)(nil)).Elem())
|
||||
}
|
||||
return &boolCodec{}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func createDecoderOfNative(ctx *ctx, typ reflect.Type) ValDecoder {
|
||||
if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 {
|
||||
func createDecoderOfNative(ctx *ctx, typ reflect2.Type) ValDecoder {
|
||||
if typ.Kind() == reflect.Slice && typ.(reflect2.SliceType).Elem().Kind() == reflect.Uint8 {
|
||||
sliceDecoder := decoderOfSlice(ctx, typ)
|
||||
return &base64Codec{sliceDecoder: sliceDecoder}
|
||||
}
|
||||
@ -103,77 +103,77 @@ func createDecoderOfNative(ctx *ctx, typ reflect.Type) ValDecoder {
|
||||
switch typ.Kind() {
|
||||
case reflect.String:
|
||||
if typeName != "string" {
|
||||
return decoderOfType(ctx, reflect.TypeOf((*string)(nil)).Elem())
|
||||
return decoderOfType(ctx, reflect2.TypeOfPtr((*string)(nil)).Elem())
|
||||
}
|
||||
return &stringCodec{}
|
||||
case reflect.Int:
|
||||
if typeName != "int" {
|
||||
return decoderOfType(ctx, reflect.TypeOf((*int)(nil)).Elem())
|
||||
return decoderOfType(ctx, reflect2.TypeOfPtr((*int)(nil)).Elem())
|
||||
}
|
||||
return &intCodec{}
|
||||
case reflect.Int8:
|
||||
if typeName != "int8" {
|
||||
return decoderOfType(ctx, reflect.TypeOf((*int8)(nil)).Elem())
|
||||
return decoderOfType(ctx, reflect2.TypeOfPtr((*int8)(nil)).Elem())
|
||||
}
|
||||
return &int8Codec{}
|
||||
case reflect.Int16:
|
||||
if typeName != "int16" {
|
||||
return decoderOfType(ctx, reflect.TypeOf((*int16)(nil)).Elem())
|
||||
return decoderOfType(ctx, reflect2.TypeOfPtr((*int16)(nil)).Elem())
|
||||
}
|
||||
return &int16Codec{}
|
||||
case reflect.Int32:
|
||||
if typeName != "int32" {
|
||||
return decoderOfType(ctx, reflect.TypeOf((*int32)(nil)).Elem())
|
||||
return decoderOfType(ctx, reflect2.TypeOfPtr((*int32)(nil)).Elem())
|
||||
}
|
||||
return &int32Codec{}
|
||||
case reflect.Int64:
|
||||
if typeName != "int64" {
|
||||
return decoderOfType(ctx, reflect.TypeOf((*int64)(nil)).Elem())
|
||||
return decoderOfType(ctx, reflect2.TypeOfPtr((*int64)(nil)).Elem())
|
||||
}
|
||||
return &int64Codec{}
|
||||
case reflect.Uint:
|
||||
if typeName != "uint" {
|
||||
return decoderOfType(ctx, reflect.TypeOf((*uint)(nil)).Elem())
|
||||
return decoderOfType(ctx, reflect2.TypeOfPtr((*uint)(nil)).Elem())
|
||||
}
|
||||
return &uintCodec{}
|
||||
case reflect.Uint8:
|
||||
if typeName != "uint8" {
|
||||
return decoderOfType(ctx, reflect.TypeOf((*uint8)(nil)).Elem())
|
||||
return decoderOfType(ctx, reflect2.TypeOfPtr((*uint8)(nil)).Elem())
|
||||
}
|
||||
return &uint8Codec{}
|
||||
case reflect.Uint16:
|
||||
if typeName != "uint16" {
|
||||
return decoderOfType(ctx, reflect.TypeOf((*uint16)(nil)).Elem())
|
||||
return decoderOfType(ctx, reflect2.TypeOfPtr((*uint16)(nil)).Elem())
|
||||
}
|
||||
return &uint16Codec{}
|
||||
case reflect.Uint32:
|
||||
if typeName != "uint32" {
|
||||
return decoderOfType(ctx, reflect.TypeOf((*uint32)(nil)).Elem())
|
||||
return decoderOfType(ctx, reflect2.TypeOfPtr((*uint32)(nil)).Elem())
|
||||
}
|
||||
return &uint32Codec{}
|
||||
case reflect.Uintptr:
|
||||
if typeName != "uintptr" {
|
||||
return decoderOfType(ctx, reflect.TypeOf((*uintptr)(nil)).Elem())
|
||||
return decoderOfType(ctx, reflect2.TypeOfPtr((*uintptr)(nil)).Elem())
|
||||
}
|
||||
return &uintptrCodec{}
|
||||
case reflect.Uint64:
|
||||
if typeName != "uint64" {
|
||||
return decoderOfType(ctx, reflect.TypeOf((*uint64)(nil)).Elem())
|
||||
return decoderOfType(ctx, reflect2.TypeOfPtr((*uint64)(nil)).Elem())
|
||||
}
|
||||
return &uint64Codec{}
|
||||
case reflect.Float32:
|
||||
if typeName != "float32" {
|
||||
return decoderOfType(ctx, reflect.TypeOf((*float32)(nil)).Elem())
|
||||
return decoderOfType(ctx, reflect2.TypeOfPtr((*float32)(nil)).Elem())
|
||||
}
|
||||
return &float32Codec{}
|
||||
case reflect.Float64:
|
||||
if typeName != "float64" {
|
||||
return decoderOfType(ctx, reflect.TypeOf((*float64)(nil)).Elem())
|
||||
return decoderOfType(ctx, reflect2.TypeOfPtr((*float64)(nil)).Elem())
|
||||
}
|
||||
return &float64Codec{}
|
||||
case reflect.Bool:
|
||||
if typeName != "bool" {
|
||||
return decoderOfType(ctx, reflect.TypeOf((*bool)(nil)).Elem())
|
||||
return decoderOfType(ctx, reflect2.TypeOfPtr((*bool)(nil)).Elem())
|
||||
}
|
||||
return &boolCodec{}
|
||||
}
|
||||
|
@ -6,17 +6,19 @@ import (
|
||||
"github.com/v2pro/plz/reflect2"
|
||||
)
|
||||
|
||||
func decoderOfOptional(ctx *ctx, typ reflect.Type) ValDecoder {
|
||||
elemType := typ.Elem()
|
||||
func decoderOfOptional(ctx *ctx, typ reflect2.Type) ValDecoder {
|
||||
ptrType := typ.(*reflect2.UnsafePtrType)
|
||||
elemType := ptrType.Elem()
|
||||
decoder := decoderOfType(ctx, elemType)
|
||||
if ctx.prefix == "" && elemType.Kind() == reflect.Ptr {
|
||||
return &dereferenceDecoder{reflect2.Type2(elemType), decoder}
|
||||
return &dereferenceDecoder{elemType, decoder}
|
||||
}
|
||||
return &OptionalDecoder{reflect2.Type2(elemType), decoder}
|
||||
return &OptionalDecoder{elemType, decoder}
|
||||
}
|
||||
|
||||
func encoderOfOptional(ctx *ctx, typ reflect.Type) ValEncoder {
|
||||
elemType := typ.Elem()
|
||||
func encoderOfOptional(ctx *ctx, typ reflect2.Type) ValEncoder {
|
||||
ptrType := typ.(*reflect2.UnsafePtrType)
|
||||
elemType := ptrType.Elem()
|
||||
elemEncoder := encoderOfType(ctx, elemType)
|
||||
encoder := &OptionalEncoder{elemEncoder}
|
||||
return encoder
|
||||
|
@ -3,20 +3,19 @@ package jsoniter
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"unsafe"
|
||||
"github.com/v2pro/plz/reflect2"
|
||||
)
|
||||
|
||||
func decoderOfSlice(ctx *ctx, typ reflect.Type) ValDecoder {
|
||||
decoder := decoderOfType(ctx.append("[sliceElem]"), typ.Elem())
|
||||
sliceType := reflect2.Type2(typ).(*reflect2.UnsafeSliceType)
|
||||
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 reflect.Type) ValEncoder {
|
||||
encoder := encoderOfType(ctx.append("[sliceElem]"), typ.Elem())
|
||||
sliceType := reflect2.Type2(typ).(*reflect2.UnsafeSliceType)
|
||||
func encoderOfSlice(ctx *ctx, typ reflect2.Type) ValEncoder {
|
||||
sliceType := typ.(*reflect2.UnsafeSliceType)
|
||||
encoder := encoderOfType(ctx.append("[sliceElem]"), sliceType.Elem())
|
||||
return &sliceEncoder{sliceType, encoder}
|
||||
}
|
||||
|
||||
@ -73,7 +72,7 @@ func (decoder *sliceDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) {
|
||||
return
|
||||
}
|
||||
if c != '[' {
|
||||
iter.ReportError("decode array", "expect [ or n, but found "+string([]byte{c}))
|
||||
iter.ReportError("decode slice", "expect [ or n, but found "+string([]byte{c}))
|
||||
return
|
||||
}
|
||||
c = iter.nextToken()
|
||||
@ -94,7 +93,7 @@ func (decoder *sliceDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) {
|
||||
decoder.elemDecoder.Decode(elemPtr, iter)
|
||||
}
|
||||
if c != ']' {
|
||||
iter.ReportError("decode array", "expect ], but found "+string([]byte{c}))
|
||||
iter.ReportError("decode slice", "expect ], but found "+string([]byte{c}))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -3,12 +3,12 @@ package jsoniter
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"strings"
|
||||
"unsafe"
|
||||
"github.com/v2pro/plz/reflect2"
|
||||
)
|
||||
|
||||
func decoderOfStruct(ctx *ctx, typ reflect.Type) ValDecoder {
|
||||
func decoderOfStruct(ctx *ctx, typ reflect2.Type) ValDecoder {
|
||||
bindings := map[string]*Binding{}
|
||||
structDescriptor := describeStruct(ctx, typ)
|
||||
for _, binding := range structDescriptor.Fields {
|
||||
@ -34,7 +34,7 @@ func decoderOfStruct(ctx *ctx, typ reflect.Type) ValDecoder {
|
||||
return createStructDecoder(ctx, typ, fields)
|
||||
}
|
||||
|
||||
func createStructDecoder(ctx *ctx, typ reflect.Type, fields map[string]*structFieldDecoder) ValDecoder {
|
||||
func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structFieldDecoder) ValDecoder {
|
||||
if ctx.disallowUnknownFields {
|
||||
return &generalStructDecoder{typ: typ, fields: fields, disallowUnknownFields: true}
|
||||
}
|
||||
@ -480,7 +480,7 @@ func createStructDecoder(ctx *ctx, typ reflect.Type, fields map[string]*structFi
|
||||
}
|
||||
|
||||
type generalStructDecoder struct {
|
||||
typ reflect.Type
|
||||
typ reflect2.Type
|
||||
fields map[string]*structFieldDecoder
|
||||
disallowUnknownFields bool
|
||||
}
|
||||
@ -535,7 +535,7 @@ func (decoder *generalStructDecoder) decodeOneField(ptr unsafe.Pointer, iter *It
|
||||
}
|
||||
|
||||
type skipObjectDecoder struct {
|
||||
typ reflect.Type
|
||||
typ reflect2.Type
|
||||
}
|
||||
|
||||
func (decoder *skipObjectDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
||||
@ -548,7 +548,7 @@ func (decoder *skipObjectDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
||||
}
|
||||
|
||||
type oneFieldStructDecoder struct {
|
||||
typ reflect.Type
|
||||
typ reflect2.Type
|
||||
fieldHash int64
|
||||
fieldDecoder *structFieldDecoder
|
||||
}
|
||||
@ -573,7 +573,7 @@ func (decoder *oneFieldStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator)
|
||||
}
|
||||
|
||||
type twoFieldsStructDecoder struct {
|
||||
typ reflect.Type
|
||||
typ reflect2.Type
|
||||
fieldHash1 int64
|
||||
fieldDecoder1 *structFieldDecoder
|
||||
fieldHash2 int64
|
||||
@ -603,7 +603,7 @@ func (decoder *twoFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator
|
||||
}
|
||||
|
||||
type threeFieldsStructDecoder struct {
|
||||
typ reflect.Type
|
||||
typ reflect2.Type
|
||||
fieldHash1 int64
|
||||
fieldDecoder1 *structFieldDecoder
|
||||
fieldHash2 int64
|
||||
@ -637,7 +637,7 @@ func (decoder *threeFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterat
|
||||
}
|
||||
|
||||
type fourFieldsStructDecoder struct {
|
||||
typ reflect.Type
|
||||
typ reflect2.Type
|
||||
fieldHash1 int64
|
||||
fieldDecoder1 *structFieldDecoder
|
||||
fieldHash2 int64
|
||||
@ -675,7 +675,7 @@ func (decoder *fourFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterato
|
||||
}
|
||||
|
||||
type fiveFieldsStructDecoder struct {
|
||||
typ reflect.Type
|
||||
typ reflect2.Type
|
||||
fieldHash1 int64
|
||||
fieldDecoder1 *structFieldDecoder
|
||||
fieldHash2 int64
|
||||
@ -717,7 +717,7 @@ func (decoder *fiveFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterato
|
||||
}
|
||||
|
||||
type sixFieldsStructDecoder struct {
|
||||
typ reflect.Type
|
||||
typ reflect2.Type
|
||||
fieldHash1 int64
|
||||
fieldDecoder1 *structFieldDecoder
|
||||
fieldHash2 int64
|
||||
@ -763,7 +763,7 @@ func (decoder *sixFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator
|
||||
}
|
||||
|
||||
type sevenFieldsStructDecoder struct {
|
||||
typ reflect.Type
|
||||
typ reflect2.Type
|
||||
fieldHash1 int64
|
||||
fieldDecoder1 *structFieldDecoder
|
||||
fieldHash2 int64
|
||||
@ -813,7 +813,7 @@ func (decoder *sevenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterat
|
||||
}
|
||||
|
||||
type eightFieldsStructDecoder struct {
|
||||
typ reflect.Type
|
||||
typ reflect2.Type
|
||||
fieldHash1 int64
|
||||
fieldDecoder1 *structFieldDecoder
|
||||
fieldHash2 int64
|
||||
@ -867,7 +867,7 @@ func (decoder *eightFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterat
|
||||
}
|
||||
|
||||
type nineFieldsStructDecoder struct {
|
||||
typ reflect.Type
|
||||
typ reflect2.Type
|
||||
fieldHash1 int64
|
||||
fieldDecoder1 *structFieldDecoder
|
||||
fieldHash2 int64
|
||||
@ -925,7 +925,7 @@ func (decoder *nineFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterato
|
||||
}
|
||||
|
||||
type tenFieldsStructDecoder struct {
|
||||
typ reflect.Type
|
||||
typ reflect2.Type
|
||||
fieldHash1 int64
|
||||
fieldDecoder1 *structFieldDecoder
|
||||
fieldHash2 int64
|
||||
@ -987,12 +987,12 @@ func (decoder *tenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator
|
||||
}
|
||||
|
||||
type structFieldDecoder struct {
|
||||
field *reflect.StructField
|
||||
field reflect2.StructField
|
||||
fieldDecoder ValDecoder
|
||||
}
|
||||
|
||||
func (decoder *structFieldDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
||||
fieldPtr := unsafe.Pointer(uintptr(ptr) + decoder.field.Offset)
|
||||
fieldPtr := decoder.field.UnsafeGet(ptr)
|
||||
decoder.fieldDecoder.Decode(fieldPtr, iter)
|
||||
if iter.Error != nil && iter.Error != io.EOF {
|
||||
iter.Error = fmt.Errorf("%s: %s", decoder.field.Name, iter.Error.Error())
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
"github.com/v2pro/plz/reflect2"
|
||||
)
|
||||
|
||||
func encoderOfStruct(ctx *ctx, typ reflect.Type) ValEncoder {
|
||||
func encoderOfStruct(ctx *ctx, typ reflect2.Type) ValEncoder {
|
||||
type bindingTo struct {
|
||||
binding *Binding
|
||||
toName string
|
||||
@ -46,7 +46,7 @@ func encoderOfStruct(ctx *ctx, typ reflect.Type) ValEncoder {
|
||||
return &structEncoder{typ, finalOrderedFields}
|
||||
}
|
||||
|
||||
func createCheckIsEmpty(ctx *ctx, typ reflect.Type) checkIsEmpty {
|
||||
func createCheckIsEmpty(ctx *ctx, typ reflect2.Type) checkIsEmpty {
|
||||
kind := typ.Kind()
|
||||
switch kind {
|
||||
case reflect.String:
|
||||
@ -80,7 +80,7 @@ func createCheckIsEmpty(ctx *ctx, typ reflect.Type) checkIsEmpty {
|
||||
case reflect.Bool:
|
||||
return &boolCodec{}
|
||||
case reflect.Interface:
|
||||
return &dynamicEncoder{reflect2.Type2(typ)}
|
||||
return &dynamicEncoder{typ}
|
||||
case reflect.Struct:
|
||||
return &structEncoder{typ: typ}
|
||||
case reflect.Array:
|
||||
@ -97,8 +97,8 @@ func createCheckIsEmpty(ctx *ctx, typ reflect.Type) checkIsEmpty {
|
||||
}
|
||||
|
||||
func resolveConflictBinding(cfg *frozenConfig, old, new *Binding) (ignoreOld, ignoreNew bool) {
|
||||
newTagged := new.Field.Tag.Get(cfg.getTagKey()) != ""
|
||||
oldTagged := old.Field.Tag.Get(cfg.getTagKey()) != ""
|
||||
newTagged := new.Field.Tag().Get(cfg.getTagKey()) != ""
|
||||
oldTagged := old.Field.Tag().Get(cfg.getTagKey()) != ""
|
||||
if newTagged {
|
||||
if oldTagged {
|
||||
if len(old.levels) > len(new.levels) {
|
||||
@ -126,21 +126,21 @@ func resolveConflictBinding(cfg *frozenConfig, old, new *Binding) (ignoreOld, ig
|
||||
}
|
||||
|
||||
type structFieldEncoder struct {
|
||||
field *reflect.StructField
|
||||
field reflect2.StructField
|
||||
fieldEncoder ValEncoder
|
||||
omitempty bool
|
||||
}
|
||||
|
||||
func (encoder *structFieldEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
||||
fieldPtr := unsafe.Pointer(uintptr(ptr) + encoder.field.Offset)
|
||||
fieldPtr := encoder.field.UnsafeGet(ptr)
|
||||
encoder.fieldEncoder.Encode(fieldPtr, stream)
|
||||
if stream.Error != nil && stream.Error != io.EOF {
|
||||
stream.Error = fmt.Errorf("%s: %s", encoder.field.Name, stream.Error.Error())
|
||||
stream.Error = fmt.Errorf("%s: %s", encoder.field.Name(), stream.Error.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func (encoder *structFieldEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||
fieldPtr := unsafe.Pointer(uintptr(ptr) + encoder.field.Offset)
|
||||
fieldPtr := encoder.field.UnsafeGet(ptr)
|
||||
return encoder.fieldEncoder.IsEmpty(fieldPtr)
|
||||
}
|
||||
|
||||
@ -149,7 +149,7 @@ func (encoder *structFieldEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool {
|
||||
if !converted {
|
||||
return false
|
||||
}
|
||||
fieldPtr := unsafe.Pointer(uintptr(ptr) + encoder.field.Offset)
|
||||
fieldPtr := encoder.field.UnsafeGet(ptr)
|
||||
return isEmbeddedPtrNil.IsEmbeddedPtrNil(fieldPtr)
|
||||
}
|
||||
|
||||
@ -158,7 +158,7 @@ type IsEmbeddedPtrNil interface {
|
||||
}
|
||||
|
||||
type structEncoder struct {
|
||||
typ reflect.Type
|
||||
typ reflect2.Type
|
||||
fields []structFieldTo
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@ import (
|
||||
)
|
||||
|
||||
type testCase struct {
|
||||
ptr interface{}
|
||||
ptr interface{}
|
||||
inputs []string
|
||||
}
|
||||
|
||||
|
@ -7,4 +7,14 @@ func init() {
|
||||
[1]*float64{&two},
|
||||
[2]*float64{},
|
||||
)
|
||||
unmarshalCases = append(unmarshalCases, unmarshalCase{
|
||||
ptr: (*[0]int)(nil),
|
||||
input: `[1]`,
|
||||
}, unmarshalCase{
|
||||
ptr: (*[1]int)(nil),
|
||||
input: `[2]`,
|
||||
}, unmarshalCase{
|
||||
ptr: (*[1]int)(nil),
|
||||
input: `[]`,
|
||||
})
|
||||
}
|
||||
|
@ -2,11 +2,11 @@ package test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"reflect"
|
||||
"encoding/json"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/json-iterator/go"
|
||||
"fmt"
|
||||
"github.com/v2pro/plz/reflect2"
|
||||
)
|
||||
|
||||
type unmarshalCase struct {
|
||||
@ -42,9 +42,9 @@ func Test_unmarshal(t *testing.T) {
|
||||
obj1 = testCase.obj()
|
||||
obj2 = testCase.obj()
|
||||
} else {
|
||||
valType := reflect.TypeOf(testCase.ptr).Elem()
|
||||
obj1 = reflect.New(valType).Interface()
|
||||
obj2 = reflect.New(valType).Interface()
|
||||
valType := reflect2.TypeOfPtr(testCase.ptr).Elem()
|
||||
obj1 = valType.New()
|
||||
obj2 = valType.New()
|
||||
}
|
||||
err1 := json.Unmarshal([]byte(testCase.input), obj1)
|
||||
should.NoError(err1, "json")
|
||||
@ -66,7 +66,7 @@ func Test_marshal(t *testing.T) {
|
||||
for i, testCase := range marshalCases {
|
||||
var name string
|
||||
if testCase != nil {
|
||||
name = fmt.Sprintf("[%v]%v/%s", i, testCase, reflect.TypeOf(testCase).String())
|
||||
name = fmt.Sprintf("[%v]%v/%s", i, testCase, reflect2.TypeOf(testCase).String())
|
||||
}
|
||||
t.Run(name, func(t *testing.T) {
|
||||
should := require.New(t)
|
||||
|
Loading…
Reference in New Issue
Block a user