mirror of
https://github.com/json-iterator/go.git
synced 2025-04-23 11:37:32 +02:00
#60 support read interface{} as json.Number
This commit is contained in:
parent
77dcffe77d
commit
7a049ec79c
@ -13,9 +13,7 @@ package jsoniter
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
|
||||||
"io"
|
"io"
|
||||||
"unsafe"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Unmarshal adapts to json/encoding Unmarshal API
|
// Unmarshal adapts to json/encoding Unmarshal API
|
||||||
@ -95,13 +93,9 @@ func (adapter *AdaptedDecoder) Buffered() io.Reader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (decoder *AdaptedDecoder) UseNumber() {
|
func (decoder *AdaptedDecoder) UseNumber() {
|
||||||
RegisterTypeDecoder("interface {}", func(ptr unsafe.Pointer, iter *Iterator) {
|
origCfg := decoder.iter.cfg.configBeforeFrozen
|
||||||
if iter.WhatIsNext() == Number {
|
origCfg.UseNumber = true
|
||||||
*((*interface{})(ptr)) = json.Number(iter.readNumberAsString())
|
decoder.iter.cfg = origCfg.Froze()
|
||||||
} else {
|
|
||||||
*((*interface{})(ptr)) = iter.Read()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEncoder(writer io.Writer) *AdaptedEncoder {
|
func NewEncoder(writer io.Writer) *AdaptedEncoder {
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
"encoding/json"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
@ -14,6 +15,7 @@ type Config struct {
|
|||||||
SupportUnexportedStructFields bool
|
SupportUnexportedStructFields bool
|
||||||
EscapeHtml bool
|
EscapeHtml bool
|
||||||
SortMapKeys bool
|
SortMapKeys bool
|
||||||
|
UseNumber bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type frozenConfig struct {
|
type frozenConfig struct {
|
||||||
@ -27,7 +29,9 @@ type frozenConfig struct {
|
|||||||
iteratorPool chan *Iterator
|
iteratorPool chan *Iterator
|
||||||
}
|
}
|
||||||
|
|
||||||
var ConfigDefault = Config{}.Froze()
|
var ConfigDefault = Config{
|
||||||
|
EscapeHtml: true,
|
||||||
|
}.Froze()
|
||||||
|
|
||||||
// Trying to be 100% compatible with standard library behavior
|
// Trying to be 100% compatible with standard library behavior
|
||||||
var ConfigCompatibleWithStandardLibrary = Config{
|
var ConfigCompatibleWithStandardLibrary = Config{
|
||||||
@ -57,10 +61,23 @@ func (cfg Config) Froze() *frozenConfig {
|
|||||||
if cfg.EscapeHtml {
|
if cfg.EscapeHtml {
|
||||||
frozenConfig.escapeHtml()
|
frozenConfig.escapeHtml()
|
||||||
}
|
}
|
||||||
|
if cfg.UseNumber {
|
||||||
|
frozenConfig.useNumber()
|
||||||
|
}
|
||||||
frozenConfig.configBeforeFrozen = cfg
|
frozenConfig.configBeforeFrozen = cfg
|
||||||
return frozenConfig
|
return frozenConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cfg *frozenConfig) useNumber() {
|
||||||
|
cfg.addDecoderToCache(reflect.TypeOf((*interface{})(nil)).Elem(), &funcDecoder{func(ptr unsafe.Pointer, iter *Iterator) {
|
||||||
|
if iter.WhatIsNext() == Number {
|
||||||
|
*((*interface{})(ptr)) = json.Number(iter.readNumberAsString())
|
||||||
|
} else {
|
||||||
|
*((*interface{})(ptr)) = iter.Read()
|
||||||
|
}
|
||||||
|
}})
|
||||||
|
}
|
||||||
|
|
||||||
// RegisterExtension can register a custom extension
|
// RegisterExtension can register a custom extension
|
||||||
func (cfg *frozenConfig) registerExtension(extension ExtensionFunc) {
|
func (cfg *frozenConfig) registerExtension(extension ExtensionFunc) {
|
||||||
cfg.extensions = append(cfg.extensions, extension)
|
cfg.extensions = append(cfg.extensions, extension)
|
||||||
|
@ -152,3 +152,13 @@ func Test_nil_non_empty_interface(t *testing.T) {
|
|||||||
should.NotNil(json.Unmarshal(b, &obj))
|
should.NotNil(json.Unmarshal(b, &obj))
|
||||||
should.NotNil(Unmarshal(b, &obj))
|
should.NotNil(Unmarshal(b, &obj))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_read_large_number_as_interface(t *testing.T) {
|
||||||
|
should := require.New(t)
|
||||||
|
var val interface{}
|
||||||
|
err := Config{UseNumber: true}.Froze().UnmarshalFromString(`123456789123456789123456789`, &val)
|
||||||
|
should.Nil(err)
|
||||||
|
output, err := MarshalToString(val)
|
||||||
|
should.Nil(err)
|
||||||
|
should.Equal(`123456789123456789123456789`, output)
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user