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