1
0
mirror of https://github.com/json-iterator/go.git synced 2025-06-24 23:16:47 +02:00

#68 empty array to object/map

This commit is contained in:
Tao Wen
2017-06-20 16:36:22 +08:00
parent 086001225d
commit 85be06b145
4 changed files with 84 additions and 6 deletions

View File

@ -6,6 +6,7 @@ import (
"encoding/json" "encoding/json"
"strings" "strings"
"math" "math"
"reflect"
) )
const MaxUint = ^uint(0) const MaxUint = ^uint(0)
@ -13,6 +14,7 @@ const MaxInt = int(MaxUint >> 1)
const MinInt = -MaxInt - 1 const MinInt = -MaxInt - 1
func RegisterFuzzyDecoders() { func RegisterFuzzyDecoders() {
jsoniter.RegisterExtension(&tolerateEmptyArrayExtension{})
jsoniter.RegisterTypeDecoder("string", &FuzzyStringDecoder{}) jsoniter.RegisterTypeDecoder("string", &FuzzyStringDecoder{})
jsoniter.RegisterTypeDecoder("float32", &FuzzyFloat32Decoder{}) jsoniter.RegisterTypeDecoder("float32", &FuzzyFloat32Decoder{})
jsoniter.RegisterTypeDecoder("float64", &FuzzyFloat64Decoder{}) jsoniter.RegisterTypeDecoder("float64", &FuzzyFloat64Decoder{})
@ -138,6 +140,32 @@ func RegisterFuzzyDecoders() {
}}) }})
} }
type tolerateEmptyArrayExtension struct {
jsoniter.DummyExtension
}
func (extension *tolerateEmptyArrayExtension) DecorateDecoder(typ reflect.Type, decoder jsoniter.ValDecoder) jsoniter.ValDecoder {
if typ.Kind() == reflect.Struct || typ.Kind() == reflect.Map {
return &tolerateEmptyArrayDecoder{decoder}
}
return decoder
}
type tolerateEmptyArrayDecoder struct {
valDecoder jsoniter.ValDecoder
}
func (decoder *tolerateEmptyArrayDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
if iter.WhatIsNext() == jsoniter.Array {
iter.Skip()
newIter := iter.Config().BorrowIterator([]byte("{}"))
defer iter.Config().ReturnIterator(newIter)
decoder.valDecoder.Decode(ptr, newIter)
} else {
decoder.valDecoder.Decode(ptr, iter)
}
}
type FuzzyStringDecoder struct { type FuzzyStringDecoder struct {
} }

View File

@ -85,3 +85,17 @@ func Test_float_to_float64(t *testing.T) {
should.Nil(jsoniter.UnmarshalFromString(`1.23`, &val)) should.Nil(jsoniter.UnmarshalFromString(`1.23`, &val))
should.Equal(float64(1.23), val) should.Equal(float64(1.23), val)
} }
func Test_empty_array_as_map(t *testing.T) {
should := require.New(t)
var val map[string]interface{}
should.Nil(jsoniter.UnmarshalFromString(`[]`, &val))
should.Equal(map[string]interface{}{}, val)
}
func Test_empty_array_as_object(t *testing.T) {
should := require.New(t)
var val struct{}
should.Nil(jsoniter.UnmarshalFromString(`[]`, &val))
should.Equal(struct{}{}, val)
}

View File

@ -238,6 +238,9 @@ func decoderOfType(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) {
decoder = &placeholderDecoder{cfg: cfg, cacheKey: cacheKey} decoder = &placeholderDecoder{cfg: cfg, cacheKey: cacheKey}
cfg.addDecoderToCache(cacheKey, decoder) cfg.addDecoderToCache(cacheKey, decoder)
decoder, err := createDecoderOfType(cfg, typ) decoder, err := createDecoderOfType(cfg, typ)
for _, extension := range extensions {
decoder = extension.DecorateDecoder(typ, decoder)
}
cfg.addDecoderToCache(cacheKey, decoder) cfg.addDecoderToCache(cacheKey, decoder)
return decoder, err return decoder, err
} }
@ -330,6 +333,9 @@ func encoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
encoder = &placeholderEncoder{cfg: cfg, cacheKey: cacheKey} encoder = &placeholderEncoder{cfg: cfg, cacheKey: cacheKey}
cfg.addEncoderToCache(cacheKey, encoder) cfg.addEncoderToCache(cacheKey, encoder)
encoder, err := createEncoderOfType(cfg, typ) encoder, err := createEncoderOfType(cfg, typ)
for _, extension := range extensions {
encoder = extension.DecorateEncoder(typ, encoder)
}
cfg.addEncoderToCache(cacheKey, encoder) cfg.addEncoderToCache(cacheKey, encoder)
return encoder, err return encoder, err
} }

View File

@ -40,6 +40,8 @@ type Extension interface {
UpdateStructDescriptor(structDescriptor *StructDescriptor) UpdateStructDescriptor(structDescriptor *StructDescriptor)
CreateDecoder(typ reflect.Type) ValDecoder CreateDecoder(typ reflect.Type) ValDecoder
CreateEncoder(typ reflect.Type) ValEncoder CreateEncoder(typ reflect.Type) ValEncoder
DecorateDecoder(typ reflect.Type, decoder ValDecoder) ValDecoder
DecorateEncoder(typ reflect.Type, encoder ValEncoder) ValEncoder
} }
type DummyExtension struct { type DummyExtension struct {
@ -56,9 +58,18 @@ func (extension *DummyExtension) CreateEncoder(typ reflect.Type) ValEncoder {
return nil return nil
} }
func (extension *DummyExtension) DecorateDecoder(typ reflect.Type, decoder ValDecoder) ValDecoder {
return decoder
}
func (extension *DummyExtension) DecorateEncoder(typ reflect.Type, encoder ValEncoder) ValEncoder {
return encoder
}
type funcDecoder struct { type funcDecoder struct {
fun DecoderFunc fun DecoderFunc
} }
func (decoder *funcDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { func (decoder *funcDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
decoder.fun(ptr, iter) decoder.fun(ptr, iter)
} }
@ -120,6 +131,15 @@ func RegisterExtension(extension Extension) {
} }
func getTypeDecoderFromExtension(typ reflect.Type) ValDecoder { func getTypeDecoderFromExtension(typ reflect.Type) ValDecoder {
decoder := _getTypeDecoderFromExtension(typ)
if decoder != nil {
for _, extension := range extensions {
decoder = extension.DecorateDecoder(typ, decoder)
}
}
return decoder
}
func _getTypeDecoderFromExtension(typ reflect.Type) ValDecoder {
for _, extension := range extensions { for _, extension := range extensions {
decoder := extension.CreateDecoder(typ) decoder := extension.CreateDecoder(typ)
if decoder != nil { if decoder != nil {
@ -141,6 +161,16 @@ func getTypeDecoderFromExtension(typ reflect.Type) ValDecoder {
} }
func getTypeEncoderFromExtension(typ reflect.Type) ValEncoder { func getTypeEncoderFromExtension(typ reflect.Type) ValEncoder {
encoder := _getTypeEncoderFromExtension(typ)
if encoder != nil {
for _, extension := range extensions {
encoder = extension.DecorateEncoder(typ, encoder)
}
}
return encoder
}
func _getTypeEncoderFromExtension(typ reflect.Type) ValEncoder {
for _, extension := range extensions { for _, extension := range extensions {
encoder := extension.CreateEncoder(typ) encoder := extension.CreateEncoder(typ)
if encoder != nil { if encoder != nil {