mirror of
https://github.com/json-iterator/go.git
synced 2025-02-07 19:30:06 +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 (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Unmarshal adapts to json/encoding Unmarshal API
|
||||
@ -95,13 +93,9 @@ func (adapter *AdaptedDecoder) Buffered() io.Reader {
|
||||
}
|
||||
|
||||
func (decoder *AdaptedDecoder) UseNumber() {
|
||||
RegisterTypeDecoder("interface {}", func(ptr unsafe.Pointer, iter *Iterator) {
|
||||
if iter.WhatIsNext() == Number {
|
||||
*((*interface{})(ptr)) = json.Number(iter.readNumberAsString())
|
||||
} else {
|
||||
*((*interface{})(ptr)) = iter.Read()
|
||||
}
|
||||
})
|
||||
origCfg := decoder.iter.cfg.configBeforeFrozen
|
||||
origCfg.UseNumber = true
|
||||
decoder.iter.cfg = origCfg.Froze()
|
||||
}
|
||||
|
||||
func NewEncoder(writer io.Writer) *AdaptedEncoder {
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"reflect"
|
||||
"sync/atomic"
|
||||
"unsafe"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
@ -14,6 +15,7 @@ type Config struct {
|
||||
SupportUnexportedStructFields bool
|
||||
EscapeHtml bool
|
||||
SortMapKeys bool
|
||||
UseNumber bool
|
||||
}
|
||||
|
||||
type frozenConfig struct {
|
||||
@ -27,7 +29,9 @@ type frozenConfig struct {
|
||||
iteratorPool chan *Iterator
|
||||
}
|
||||
|
||||
var ConfigDefault = Config{}.Froze()
|
||||
var ConfigDefault = Config{
|
||||
EscapeHtml: true,
|
||||
}.Froze()
|
||||
|
||||
// Trying to be 100% compatible with standard library behavior
|
||||
var ConfigCompatibleWithStandardLibrary = Config{
|
||||
@ -57,10 +61,23 @@ func (cfg Config) Froze() *frozenConfig {
|
||||
if cfg.EscapeHtml {
|
||||
frozenConfig.escapeHtml()
|
||||
}
|
||||
if cfg.UseNumber {
|
||||
frozenConfig.useNumber()
|
||||
}
|
||||
frozenConfig.configBeforeFrozen = cfg
|
||||
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
|
||||
func (cfg *frozenConfig) registerExtension(extension ExtensionFunc) {
|
||||
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(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