mirror of
https://github.com/json-iterator/go.git
synced 2025-04-20 11:28:49 +02:00
#53 move current config EnableXXX
This commit is contained in:
parent
48e9f6ec84
commit
d0418857ce
@ -172,9 +172,7 @@ func (decoder *AdaptedDecoder) UseNumber() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewEncoder(writer io.Writer) *AdaptedEncoder {
|
func NewEncoder(writer io.Writer) *AdaptedEncoder {
|
||||||
newCfg := &Config{}
|
stream := NewStream(&Config{}, writer, 512)
|
||||||
initConfig(newCfg)
|
|
||||||
stream := NewStream(newCfg, writer, 512)
|
|
||||||
return &AdaptedEncoder{stream}
|
return &AdaptedEncoder{stream}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package jsoniter
|
package jsoniter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
@ -8,20 +9,58 @@ import (
|
|||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
IndentionStep int
|
IndentionStep int
|
||||||
|
MarshalFloatWith6Digits bool
|
||||||
|
SupportUnexportedStructFields bool
|
||||||
decoderCache unsafe.Pointer
|
decoderCache unsafe.Pointer
|
||||||
encoderCache unsafe.Pointer
|
encoderCache unsafe.Pointer
|
||||||
|
extensions []ExtensionFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
var DEFAULT_CONFIG = &Config{}
|
var DEFAULT_CONFIG = &Config{}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
initConfig(DEFAULT_CONFIG)
|
DEFAULT_CONFIG.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
func initConfig(cfg *Config) {
|
func (cfg *Config) init() *Config {
|
||||||
|
if cfg.encoderCache == nil {
|
||||||
atomic.StorePointer(&cfg.decoderCache, unsafe.Pointer(&map[string]Decoder{}))
|
atomic.StorePointer(&cfg.decoderCache, unsafe.Pointer(&map[string]Decoder{}))
|
||||||
atomic.StorePointer(&cfg.encoderCache, unsafe.Pointer(&map[string]Encoder{}))
|
atomic.StorePointer(&cfg.encoderCache, unsafe.Pointer(&map[string]Encoder{}))
|
||||||
|
if cfg.MarshalFloatWith6Digits {
|
||||||
|
cfg.marshalFloatWith6Digits()
|
||||||
|
}
|
||||||
|
if cfg.SupportUnexportedStructFields {
|
||||||
|
cfg.supportUnexportedStructFields()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RegisterExtension can register a custom extension
|
||||||
|
func (cfg *Config) RegisterExtension(extension ExtensionFunc) {
|
||||||
|
cfg.extensions = append(cfg.extensions, extension)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *Config) supportUnexportedStructFields() {
|
||||||
|
cfg.RegisterExtension(func(type_ reflect.Type, field *reflect.StructField) ([]string, EncoderFunc, DecoderFunc) {
|
||||||
|
return []string{field.Name}, nil, nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnableLossyFloatMarshalling keeps 10**(-6) precision
|
||||||
|
// for float variables for better performance.
|
||||||
|
func (cfg *Config) marshalFloatWith6Digits() {
|
||||||
|
// for better performance
|
||||||
|
cfg.addEncoderToCache(reflect.TypeOf((*float32)(nil)).Elem(), &funcEncoder{func(ptr unsafe.Pointer, stream *Stream) {
|
||||||
|
val := *((*float32)(ptr))
|
||||||
|
stream.WriteFloat32Lossy(val)
|
||||||
|
}})
|
||||||
|
cfg.addEncoderToCache(reflect.TypeOf((*float64)(nil)).Elem(), &funcEncoder{func(ptr unsafe.Pointer, stream *Stream) {
|
||||||
|
val := *((*float64)(ptr))
|
||||||
|
stream.WriteFloat64Lossy(val)
|
||||||
|
}})
|
||||||
|
}
|
||||||
|
|
||||||
func (cfg *Config) addDecoderToCache(cacheKey reflect.Type, decoder Decoder) {
|
func (cfg *Config) addDecoderToCache(cacheKey reflect.Type, decoder Decoder) {
|
||||||
done := false
|
done := false
|
||||||
for !done {
|
for !done {
|
||||||
@ -75,3 +114,38 @@ func (cfg *Config) CleanEncoders() {
|
|||||||
fieldEncoders = map[string]Encoder{}
|
fieldEncoders = map[string]Encoder{}
|
||||||
atomic.StorePointer(&cfg.encoderCache, unsafe.Pointer(&map[string]Encoder{}))
|
atomic.StorePointer(&cfg.encoderCache, unsafe.Pointer(&map[string]Encoder{}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cfg *Config) MarshalToString(v interface{}) (string, error) {
|
||||||
|
buf, err := cfg.Marshal(v)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return string(buf), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *Config) Marshal(v interface{}) ([]byte, error) {
|
||||||
|
cfg.init()
|
||||||
|
stream := NewStream(cfg, nil, 256)
|
||||||
|
stream.WriteVal(v)
|
||||||
|
if stream.Error != nil {
|
||||||
|
return nil, stream.Error
|
||||||
|
}
|
||||||
|
return stream.Buffer(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *Config) UnmarshalFromString(str string, v interface{}) error {
|
||||||
|
data := []byte(str)
|
||||||
|
data = data[:lastNotSpacePos(data)]
|
||||||
|
iter := ParseBytes(cfg, data)
|
||||||
|
iter.ReadVal(v)
|
||||||
|
if iter.head == iter.tail {
|
||||||
|
iter.loadMore()
|
||||||
|
}
|
||||||
|
if iter.Error == io.EOF {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if iter.Error == nil {
|
||||||
|
iter.reportError("UnmarshalFromString", "there are bytes left after unmarshal")
|
||||||
|
}
|
||||||
|
return iter.Error
|
||||||
|
}
|
||||||
|
@ -76,6 +76,7 @@ type Iterator struct {
|
|||||||
|
|
||||||
// Create creates an empty Iterator instance
|
// Create creates an empty Iterator instance
|
||||||
func NewIterator(cfg *Config) *Iterator {
|
func NewIterator(cfg *Config) *Iterator {
|
||||||
|
cfg.init()
|
||||||
return &Iterator{
|
return &Iterator{
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
reader: nil,
|
reader: nil,
|
||||||
@ -87,6 +88,7 @@ func NewIterator(cfg *Config) *Iterator {
|
|||||||
|
|
||||||
// Parse parses a json buffer in io.Reader into an Iterator instance
|
// Parse parses a json buffer in io.Reader into an Iterator instance
|
||||||
func Parse(cfg *Config, reader io.Reader, bufSize int) *Iterator {
|
func Parse(cfg *Config, reader io.Reader, bufSize int) *Iterator {
|
||||||
|
cfg.init()
|
||||||
return &Iterator{
|
return &Iterator{
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
reader: reader,
|
reader: reader,
|
||||||
@ -98,6 +100,7 @@ func Parse(cfg *Config, reader io.Reader, bufSize int) *Iterator {
|
|||||||
|
|
||||||
// ParseBytes parses a json byte slice into an Iterator instance
|
// ParseBytes parses a json byte slice into an Iterator instance
|
||||||
func ParseBytes(cfg *Config, input []byte) *Iterator {
|
func ParseBytes(cfg *Config, input []byte) *Iterator {
|
||||||
|
cfg.init()
|
||||||
return &Iterator{
|
return &Iterator{
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
reader: nil,
|
reader: nil,
|
||||||
|
@ -102,9 +102,9 @@ non_decimal_loop:
|
|||||||
ind := floatDigits[c]
|
ind := floatDigits[c]
|
||||||
switch ind {
|
switch ind {
|
||||||
case endOfNumber:
|
case endOfNumber:
|
||||||
if decimalPlaces > 0 && decimalPlaces < len(POW10) {
|
if decimalPlaces > 0 && decimalPlaces < len(_POW10) {
|
||||||
iter.head = i
|
iter.head = i
|
||||||
return float32(float64(value) / float64(POW10[decimalPlaces]))
|
return float32(float64(value) / float64(_POW10[decimalPlaces]))
|
||||||
}
|
}
|
||||||
// too many decimal places
|
// too many decimal places
|
||||||
return iter.readFloat32SlowPath()
|
return iter.readFloat32SlowPath()
|
||||||
@ -205,9 +205,9 @@ non_decimal_loop:
|
|||||||
ind := floatDigits[c]
|
ind := floatDigits[c]
|
||||||
switch ind {
|
switch ind {
|
||||||
case endOfNumber:
|
case endOfNumber:
|
||||||
if decimalPlaces > 0 && decimalPlaces < len(POW10) {
|
if decimalPlaces > 0 && decimalPlaces < len(_POW10) {
|
||||||
iter.head = i
|
iter.head = i
|
||||||
return float64(value) / float64(POW10[decimalPlaces])
|
return float64(value) / float64(_POW10[decimalPlaces])
|
||||||
}
|
}
|
||||||
// too many decimal places
|
// too many decimal places
|
||||||
return iter.readFloat64SlowPath()
|
return iter.readFloat64SlowPath()
|
||||||
|
@ -24,6 +24,15 @@ func encoderOfStruct(cfg *Config, typ reflect.Type) (Encoder, error) {
|
|||||||
fieldEncoders[fieldEncoderKey] = &funcEncoder{fun}
|
fieldEncoders[fieldEncoderKey] = &funcEncoder{fun}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for _, extension := range cfg.extensions {
|
||||||
|
alternativeFieldNames, fun, _ := extension(typ, field)
|
||||||
|
if alternativeFieldNames != nil {
|
||||||
|
extensionProvidedFieldNames = alternativeFieldNames
|
||||||
|
}
|
||||||
|
if fun != nil {
|
||||||
|
fieldEncoders[fieldEncoderKey] = &funcEncoder{fun}
|
||||||
|
}
|
||||||
|
}
|
||||||
tagParts := strings.Split(field.Tag.Get("json"), ",")
|
tagParts := strings.Split(field.Tag.Get("json"), ",")
|
||||||
// if fieldNames set by extension, use theirs, otherwise try tags
|
// if fieldNames set by extension, use theirs, otherwise try tags
|
||||||
fieldNames := calcFieldNames(field.Name, tagParts[0], extensionProvidedFieldNames)
|
fieldNames := calcFieldNames(field.Name, tagParts[0], extensionProvidedFieldNames)
|
||||||
@ -86,6 +95,15 @@ func decoderOfStruct(cfg *Config, typ reflect.Type) (Decoder, error) {
|
|||||||
fieldDecoders[fieldDecoderKey] = &funcDecoder{fun}
|
fieldDecoders[fieldDecoderKey] = &funcDecoder{fun}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for _, extension := range cfg.extensions {
|
||||||
|
alternativeFieldNames, _, fun := extension(typ, &field)
|
||||||
|
if alternativeFieldNames != nil {
|
||||||
|
extensionProviedFieldNames = alternativeFieldNames
|
||||||
|
}
|
||||||
|
if fun != nil {
|
||||||
|
fieldDecoders[fieldDecoderKey] = &funcDecoder{fun}
|
||||||
|
}
|
||||||
|
}
|
||||||
decoder := fieldDecoders[fieldDecoderKey]
|
decoder := fieldDecoders[fieldDecoderKey]
|
||||||
tagParts := strings.Split(field.Tag.Get("json"), ",")
|
tagParts := strings.Split(field.Tag.Get("json"), ",")
|
||||||
fieldNames := calcFieldNames(field.Name, tagParts[0], extensionProviedFieldNames)
|
fieldNames := calcFieldNames(field.Name, tagParts[0], extensionProviedFieldNames)
|
||||||
@ -130,12 +148,6 @@ func calcFieldNames(originalFieldName string, tagProvidedFieldName string, exten
|
|||||||
return fieldNames
|
return fieldNames
|
||||||
}
|
}
|
||||||
|
|
||||||
func EnableUnexportedStructFieldsSupport() {
|
|
||||||
RegisterExtension(func(type_ reflect.Type, field *reflect.StructField) ([]string, EncoderFunc, DecoderFunc) {
|
|
||||||
return []string{field.Name}, nil, nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder) (Decoder, error) {
|
func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder) (Decoder, error) {
|
||||||
knownHash := map[int32]struct{}{
|
knownHash := map[int32]struct{}{
|
||||||
0: {},
|
0: {},
|
||||||
|
@ -14,6 +14,7 @@ type Stream struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewStream(cfg *Config, out io.Writer, bufSize int) *Stream {
|
func NewStream(cfg *Config, out io.Writer, bufSize int) *Stream {
|
||||||
|
cfg.init()
|
||||||
return &Stream{
|
return &Stream{
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
out: out,
|
out: out,
|
||||||
|
@ -2,13 +2,12 @@ package jsoniter
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"unsafe"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var POW10 []uint64
|
var _POW10 []uint64
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
POW10 = []uint64{1, 10, 100, 1000, 10000, 100000, 1000000}
|
_POW10 = []uint64{1, 10, 100, 1000, 10000, 100000, 1000000}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (stream *Stream) WriteFloat32(val float32) {
|
func (stream *Stream) WriteFloat32(val float32) {
|
||||||
@ -34,7 +33,7 @@ func (stream *Stream) WriteFloat32Lossy(val float32) {
|
|||||||
}
|
}
|
||||||
stream.writeByte('.')
|
stream.writeByte('.')
|
||||||
stream.ensure(10)
|
stream.ensure(10)
|
||||||
for p := precision - 1; p > 0 && fval < POW10[p]; p-- {
|
for p := precision - 1; p > 0 && fval < _POW10[p]; p-- {
|
||||||
stream.writeByte('0')
|
stream.writeByte('0')
|
||||||
}
|
}
|
||||||
stream.WriteUint64(fval)
|
stream.WriteUint64(fval)
|
||||||
@ -66,7 +65,7 @@ func (stream *Stream) WriteFloat64Lossy(val float64) {
|
|||||||
}
|
}
|
||||||
stream.writeByte('.')
|
stream.writeByte('.')
|
||||||
stream.ensure(10)
|
stream.ensure(10)
|
||||||
for p := precision - 1; p > 0 && fval < POW10[p]; p-- {
|
for p := precision - 1; p > 0 && fval < _POW10[p]; p-- {
|
||||||
stream.writeByte('0')
|
stream.writeByte('0')
|
||||||
}
|
}
|
||||||
stream.WriteUint64(fval)
|
stream.WriteUint64(fval)
|
||||||
@ -74,17 +73,3 @@ func (stream *Stream) WriteFloat64Lossy(val float64) {
|
|||||||
stream.n--
|
stream.n--
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnableLossyFloatMarshalling keeps 10**(-6) precision
|
|
||||||
// for float variables for better performance.
|
|
||||||
func EnableLossyFloatMarshalling() {
|
|
||||||
// for better performance
|
|
||||||
RegisterTypeEncoder("float32", func(ptr unsafe.Pointer, stream *Stream) {
|
|
||||||
val := *((*float32)(ptr))
|
|
||||||
stream.WriteFloat32Lossy(val)
|
|
||||||
})
|
|
||||||
RegisterTypeEncoder("float64", func(ptr unsafe.Pointer, stream *Stream) {
|
|
||||||
val := *((*float64)(ptr))
|
|
||||||
stream.WriteFloat64Lossy(val)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
package jsoniter
|
package jsoniter
|
||||||
|
|
||||||
var DIGITS []uint32
|
var _DIGITS []uint32
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
DIGITS = make([]uint32, 1000)
|
_DIGITS = make([]uint32, 1000)
|
||||||
for i := uint32(0); i < 1000; i++ {
|
for i := uint32(0); i < 1000; i++ {
|
||||||
DIGITS[i] = (((i / 100) + '0') << 16) + ((((i / 10) % 10) + '0') << 8) + i%10 + '0'
|
_DIGITS[i] = (((i / 100) + '0') << 16) + ((((i / 10) % 10) + '0') << 8) + i%10 + '0'
|
||||||
if i < 10 {
|
if i < 10 {
|
||||||
DIGITS[i] += 2 << 24
|
_DIGITS[i] += 2 << 24
|
||||||
} else if i < 100 {
|
} else if i < 100 {
|
||||||
DIGITS[i] += 1 << 24
|
_DIGITS[i] += 1 << 24
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -38,7 +38,7 @@ func writeBuf(buf []byte, v uint32, n int) {
|
|||||||
|
|
||||||
func (stream *Stream) WriteUint8(val uint8) {
|
func (stream *Stream) WriteUint8(val uint8) {
|
||||||
stream.ensure(3)
|
stream.ensure(3)
|
||||||
stream.n = writeFirstBuf(stream.buf, DIGITS[val], stream.n)
|
stream.n = writeFirstBuf(stream.buf, _DIGITS[val], stream.n)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (stream *Stream) WriteInt8(nval int8) {
|
func (stream *Stream) WriteInt8(nval int8) {
|
||||||
@ -52,19 +52,19 @@ func (stream *Stream) WriteInt8(nval int8) {
|
|||||||
} else {
|
} else {
|
||||||
val = uint8(nval)
|
val = uint8(nval)
|
||||||
}
|
}
|
||||||
stream.n = writeFirstBuf(stream.buf, DIGITS[val], n)
|
stream.n = writeFirstBuf(stream.buf, _DIGITS[val], n)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (stream *Stream) WriteUint16(val uint16) {
|
func (stream *Stream) WriteUint16(val uint16) {
|
||||||
stream.ensure(5)
|
stream.ensure(5)
|
||||||
q1 := val / 1000
|
q1 := val / 1000
|
||||||
if q1 == 0 {
|
if q1 == 0 {
|
||||||
stream.n = writeFirstBuf(stream.buf, DIGITS[val], stream.n)
|
stream.n = writeFirstBuf(stream.buf, _DIGITS[val], stream.n)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r1 := val - q1*1000
|
r1 := val - q1*1000
|
||||||
n := writeFirstBuf(stream.buf, DIGITS[q1], stream.n)
|
n := writeFirstBuf(stream.buf, _DIGITS[q1], stream.n)
|
||||||
writeBuf(stream.buf, DIGITS[r1], n)
|
writeBuf(stream.buf, _DIGITS[r1], n)
|
||||||
stream.n = n + 3
|
stream.n = n + 3
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -82,12 +82,12 @@ func (stream *Stream) WriteInt16(nval int16) {
|
|||||||
}
|
}
|
||||||
q1 := val / 1000
|
q1 := val / 1000
|
||||||
if q1 == 0 {
|
if q1 == 0 {
|
||||||
stream.n = writeFirstBuf(stream.buf, DIGITS[val], n)
|
stream.n = writeFirstBuf(stream.buf, _DIGITS[val], n)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r1 := val - q1*1000
|
r1 := val - q1*1000
|
||||||
n = writeFirstBuf(stream.buf, DIGITS[q1], n)
|
n = writeFirstBuf(stream.buf, _DIGITS[q1], n)
|
||||||
writeBuf(stream.buf, DIGITS[r1], n)
|
writeBuf(stream.buf, _DIGITS[r1], n)
|
||||||
stream.n = n + 3
|
stream.n = n + 3
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -97,30 +97,30 @@ func (stream *Stream) WriteUint32(val uint32) {
|
|||||||
n := stream.n
|
n := stream.n
|
||||||
q1 := val / 1000
|
q1 := val / 1000
|
||||||
if q1 == 0 {
|
if q1 == 0 {
|
||||||
stream.n = writeFirstBuf(stream.buf, DIGITS[val], n)
|
stream.n = writeFirstBuf(stream.buf, _DIGITS[val], n)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r1 := val - q1*1000
|
r1 := val - q1*1000
|
||||||
q2 := q1 / 1000
|
q2 := q1 / 1000
|
||||||
if q2 == 0 {
|
if q2 == 0 {
|
||||||
n := writeFirstBuf(stream.buf, DIGITS[q1], n)
|
n := writeFirstBuf(stream.buf, _DIGITS[q1], n)
|
||||||
writeBuf(stream.buf, DIGITS[r1], n)
|
writeBuf(stream.buf, _DIGITS[r1], n)
|
||||||
stream.n = n + 3
|
stream.n = n + 3
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r2 := q1 - q2*1000
|
r2 := q1 - q2*1000
|
||||||
q3 := q2 / 1000
|
q3 := q2 / 1000
|
||||||
if q3 == 0 {
|
if q3 == 0 {
|
||||||
n = writeFirstBuf(stream.buf, DIGITS[q2], n)
|
n = writeFirstBuf(stream.buf, _DIGITS[q2], n)
|
||||||
} else {
|
} else {
|
||||||
r3 := q2 - q3*1000
|
r3 := q2 - q3*1000
|
||||||
stream.buf[n] = byte(q3 + '0')
|
stream.buf[n] = byte(q3 + '0')
|
||||||
n++
|
n++
|
||||||
writeBuf(stream.buf, DIGITS[r3], n)
|
writeBuf(stream.buf, _DIGITS[r3], n)
|
||||||
n += 3
|
n += 3
|
||||||
}
|
}
|
||||||
writeBuf(stream.buf, DIGITS[r2], n)
|
writeBuf(stream.buf, _DIGITS[r2], n)
|
||||||
writeBuf(stream.buf, DIGITS[r1], n+3)
|
writeBuf(stream.buf, _DIGITS[r1], n+3)
|
||||||
stream.n = n + 6
|
stream.n = n + 6
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,30 +137,30 @@ func (stream *Stream) WriteInt32(nval int32) {
|
|||||||
}
|
}
|
||||||
q1 := val / 1000
|
q1 := val / 1000
|
||||||
if q1 == 0 {
|
if q1 == 0 {
|
||||||
stream.n = writeFirstBuf(stream.buf, DIGITS[val], n)
|
stream.n = writeFirstBuf(stream.buf, _DIGITS[val], n)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r1 := val - q1*1000
|
r1 := val - q1*1000
|
||||||
q2 := q1 / 1000
|
q2 := q1 / 1000
|
||||||
if q2 == 0 {
|
if q2 == 0 {
|
||||||
n := writeFirstBuf(stream.buf, DIGITS[q1], n)
|
n := writeFirstBuf(stream.buf, _DIGITS[q1], n)
|
||||||
writeBuf(stream.buf, DIGITS[r1], n)
|
writeBuf(stream.buf, _DIGITS[r1], n)
|
||||||
stream.n = n + 3
|
stream.n = n + 3
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r2 := q1 - q2*1000
|
r2 := q1 - q2*1000
|
||||||
q3 := q2 / 1000
|
q3 := q2 / 1000
|
||||||
if q3 == 0 {
|
if q3 == 0 {
|
||||||
n = writeFirstBuf(stream.buf, DIGITS[q2], n)
|
n = writeFirstBuf(stream.buf, _DIGITS[q2], n)
|
||||||
} else {
|
} else {
|
||||||
r3 := q2 - q3*1000
|
r3 := q2 - q3*1000
|
||||||
stream.buf[n] = byte(q3 + '0')
|
stream.buf[n] = byte(q3 + '0')
|
||||||
n++
|
n++
|
||||||
writeBuf(stream.buf, DIGITS[r3], n)
|
writeBuf(stream.buf, _DIGITS[r3], n)
|
||||||
n += 3
|
n += 3
|
||||||
}
|
}
|
||||||
writeBuf(stream.buf, DIGITS[r2], n)
|
writeBuf(stream.buf, _DIGITS[r2], n)
|
||||||
writeBuf(stream.buf, DIGITS[r1], n+3)
|
writeBuf(stream.buf, _DIGITS[r1], n+3)
|
||||||
stream.n = n + 6
|
stream.n = n + 6
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,62 +169,62 @@ func (stream *Stream) WriteUint64(val uint64) {
|
|||||||
n := stream.n
|
n := stream.n
|
||||||
q1 := val / 1000
|
q1 := val / 1000
|
||||||
if q1 == 0 {
|
if q1 == 0 {
|
||||||
stream.n = writeFirstBuf(stream.buf, DIGITS[val], n)
|
stream.n = writeFirstBuf(stream.buf, _DIGITS[val], n)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r1 := val - q1*1000
|
r1 := val - q1*1000
|
||||||
q2 := q1 / 1000
|
q2 := q1 / 1000
|
||||||
if q2 == 0 {
|
if q2 == 0 {
|
||||||
n := writeFirstBuf(stream.buf, DIGITS[q1], n)
|
n := writeFirstBuf(stream.buf, _DIGITS[q1], n)
|
||||||
writeBuf(stream.buf, DIGITS[r1], n)
|
writeBuf(stream.buf, _DIGITS[r1], n)
|
||||||
stream.n = n + 3
|
stream.n = n + 3
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r2 := q1 - q2*1000
|
r2 := q1 - q2*1000
|
||||||
q3 := q2 / 1000
|
q3 := q2 / 1000
|
||||||
if q3 == 0 {
|
if q3 == 0 {
|
||||||
n = writeFirstBuf(stream.buf, DIGITS[q2], n)
|
n = writeFirstBuf(stream.buf, _DIGITS[q2], n)
|
||||||
writeBuf(stream.buf, DIGITS[r2], n)
|
writeBuf(stream.buf, _DIGITS[r2], n)
|
||||||
writeBuf(stream.buf, DIGITS[r1], n+3)
|
writeBuf(stream.buf, _DIGITS[r1], n+3)
|
||||||
stream.n = n + 6
|
stream.n = n + 6
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r3 := q2 - q3*1000
|
r3 := q2 - q3*1000
|
||||||
q4 := q3 / 1000
|
q4 := q3 / 1000
|
||||||
if q4 == 0 {
|
if q4 == 0 {
|
||||||
n = writeFirstBuf(stream.buf, DIGITS[q3], n)
|
n = writeFirstBuf(stream.buf, _DIGITS[q3], n)
|
||||||
writeBuf(stream.buf, DIGITS[r3], n)
|
writeBuf(stream.buf, _DIGITS[r3], n)
|
||||||
writeBuf(stream.buf, DIGITS[r2], n+3)
|
writeBuf(stream.buf, _DIGITS[r2], n+3)
|
||||||
writeBuf(stream.buf, DIGITS[r1], n+6)
|
writeBuf(stream.buf, _DIGITS[r1], n+6)
|
||||||
stream.n = n + 9
|
stream.n = n + 9
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r4 := q3 - q4*1000
|
r4 := q3 - q4*1000
|
||||||
q5 := q4 / 1000
|
q5 := q4 / 1000
|
||||||
if q5 == 0 {
|
if q5 == 0 {
|
||||||
n = writeFirstBuf(stream.buf, DIGITS[q4], n)
|
n = writeFirstBuf(stream.buf, _DIGITS[q4], n)
|
||||||
writeBuf(stream.buf, DIGITS[r4], n)
|
writeBuf(stream.buf, _DIGITS[r4], n)
|
||||||
writeBuf(stream.buf, DIGITS[r3], n+3)
|
writeBuf(stream.buf, _DIGITS[r3], n+3)
|
||||||
writeBuf(stream.buf, DIGITS[r2], n+6)
|
writeBuf(stream.buf, _DIGITS[r2], n+6)
|
||||||
writeBuf(stream.buf, DIGITS[r1], n+9)
|
writeBuf(stream.buf, _DIGITS[r1], n+9)
|
||||||
stream.n = n + 12
|
stream.n = n + 12
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r5 := q4 - q5*1000
|
r5 := q4 - q5*1000
|
||||||
q6 := q5 / 1000
|
q6 := q5 / 1000
|
||||||
if q6 == 0 {
|
if q6 == 0 {
|
||||||
n = writeFirstBuf(stream.buf, DIGITS[q5], n)
|
n = writeFirstBuf(stream.buf, _DIGITS[q5], n)
|
||||||
} else {
|
} else {
|
||||||
n = writeFirstBuf(stream.buf, DIGITS[q6], n)
|
n = writeFirstBuf(stream.buf, _DIGITS[q6], n)
|
||||||
r6 := q5 - q6*1000
|
r6 := q5 - q6*1000
|
||||||
writeBuf(stream.buf, DIGITS[r6], n)
|
writeBuf(stream.buf, _DIGITS[r6], n)
|
||||||
n += 3
|
n += 3
|
||||||
}
|
}
|
||||||
writeBuf(stream.buf, DIGITS[r5], n)
|
writeBuf(stream.buf, _DIGITS[r5], n)
|
||||||
writeBuf(stream.buf, DIGITS[r4], n+3)
|
writeBuf(stream.buf, _DIGITS[r4], n+3)
|
||||||
writeBuf(stream.buf, DIGITS[r3], n+6)
|
writeBuf(stream.buf, _DIGITS[r3], n+6)
|
||||||
writeBuf(stream.buf, DIGITS[r2], n+9)
|
writeBuf(stream.buf, _DIGITS[r2], n+9)
|
||||||
writeBuf(stream.buf, DIGITS[r1], n+12)
|
writeBuf(stream.buf, _DIGITS[r1], n+12)
|
||||||
stream.n = n + 15
|
stream.n = n + 15
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,63 +241,63 @@ func (stream *Stream) WriteInt64(nval int64) {
|
|||||||
}
|
}
|
||||||
q1 := val / 1000
|
q1 := val / 1000
|
||||||
if q1 == 0 {
|
if q1 == 0 {
|
||||||
stream.n = writeFirstBuf(stream.buf, DIGITS[val], n)
|
stream.n = writeFirstBuf(stream.buf, _DIGITS[val], n)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r1 := val - q1*1000
|
r1 := val - q1*1000
|
||||||
q2 := q1 / 1000
|
q2 := q1 / 1000
|
||||||
if q2 == 0 {
|
if q2 == 0 {
|
||||||
n := writeFirstBuf(stream.buf, DIGITS[q1], n)
|
n := writeFirstBuf(stream.buf, _DIGITS[q1], n)
|
||||||
writeBuf(stream.buf, DIGITS[r1], n)
|
writeBuf(stream.buf, _DIGITS[r1], n)
|
||||||
stream.n = n + 3
|
stream.n = n + 3
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r2 := q1 - q2*1000
|
r2 := q1 - q2*1000
|
||||||
q3 := q2 / 1000
|
q3 := q2 / 1000
|
||||||
if q3 == 0 {
|
if q3 == 0 {
|
||||||
n = writeFirstBuf(stream.buf, DIGITS[q2], n)
|
n = writeFirstBuf(stream.buf, _DIGITS[q2], n)
|
||||||
writeBuf(stream.buf, DIGITS[r2], n)
|
writeBuf(stream.buf, _DIGITS[r2], n)
|
||||||
writeBuf(stream.buf, DIGITS[r1], n+3)
|
writeBuf(stream.buf, _DIGITS[r1], n+3)
|
||||||
stream.n = n + 6
|
stream.n = n + 6
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r3 := q2 - q3*1000
|
r3 := q2 - q3*1000
|
||||||
q4 := q3 / 1000
|
q4 := q3 / 1000
|
||||||
if q4 == 0 {
|
if q4 == 0 {
|
||||||
n = writeFirstBuf(stream.buf, DIGITS[q3], n)
|
n = writeFirstBuf(stream.buf, _DIGITS[q3], n)
|
||||||
writeBuf(stream.buf, DIGITS[r3], n)
|
writeBuf(stream.buf, _DIGITS[r3], n)
|
||||||
writeBuf(stream.buf, DIGITS[r2], n+3)
|
writeBuf(stream.buf, _DIGITS[r2], n+3)
|
||||||
writeBuf(stream.buf, DIGITS[r1], n+6)
|
writeBuf(stream.buf, _DIGITS[r1], n+6)
|
||||||
stream.n = n + 9
|
stream.n = n + 9
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r4 := q3 - q4*1000
|
r4 := q3 - q4*1000
|
||||||
q5 := q4 / 1000
|
q5 := q4 / 1000
|
||||||
if q5 == 0 {
|
if q5 == 0 {
|
||||||
n = writeFirstBuf(stream.buf, DIGITS[q4], n)
|
n = writeFirstBuf(stream.buf, _DIGITS[q4], n)
|
||||||
writeBuf(stream.buf, DIGITS[r4], n)
|
writeBuf(stream.buf, _DIGITS[r4], n)
|
||||||
writeBuf(stream.buf, DIGITS[r3], n+3)
|
writeBuf(stream.buf, _DIGITS[r3], n+3)
|
||||||
writeBuf(stream.buf, DIGITS[r2], n+6)
|
writeBuf(stream.buf, _DIGITS[r2], n+6)
|
||||||
writeBuf(stream.buf, DIGITS[r1], n+9)
|
writeBuf(stream.buf, _DIGITS[r1], n+9)
|
||||||
stream.n = n + 12
|
stream.n = n + 12
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r5 := q4 - q5*1000
|
r5 := q4 - q5*1000
|
||||||
q6 := q5 / 1000
|
q6 := q5 / 1000
|
||||||
if q6 == 0 {
|
if q6 == 0 {
|
||||||
n = writeFirstBuf(stream.buf, DIGITS[q5], n)
|
n = writeFirstBuf(stream.buf, _DIGITS[q5], n)
|
||||||
} else {
|
} else {
|
||||||
stream.buf[n] = byte(q6 + '0')
|
stream.buf[n] = byte(q6 + '0')
|
||||||
n++
|
n++
|
||||||
r6 := q5 - q6*1000
|
r6 := q5 - q6*1000
|
||||||
writeBuf(stream.buf, DIGITS[r6], n)
|
writeBuf(stream.buf, _DIGITS[r6], n)
|
||||||
n += 3
|
n += 3
|
||||||
}
|
}
|
||||||
writeBuf(stream.buf, DIGITS[r5], n)
|
writeBuf(stream.buf, _DIGITS[r5], n)
|
||||||
writeBuf(stream.buf, DIGITS[r4], n+3)
|
writeBuf(stream.buf, _DIGITS[r4], n+3)
|
||||||
writeBuf(stream.buf, DIGITS[r3], n+6)
|
writeBuf(stream.buf, _DIGITS[r3], n+6)
|
||||||
writeBuf(stream.buf, DIGITS[r2], n+9)
|
writeBuf(stream.buf, _DIGITS[r2], n+9)
|
||||||
writeBuf(stream.buf, DIGITS[r1], n+12)
|
writeBuf(stream.buf, _DIGITS[r1], n+12)
|
||||||
stream.n = n + 15
|
stream.n = n + 15
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,9 +213,7 @@ func Test_whitespace_before_comma(t *testing.T) {
|
|||||||
func Test_write_array(t *testing.T) {
|
func Test_write_array(t *testing.T) {
|
||||||
should := require.New(t)
|
should := require.New(t)
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
newCfg := &Config{IndentionStep: 2}
|
stream := NewStream(&Config{IndentionStep: 2}, buf, 4096)
|
||||||
initConfig(newCfg)
|
|
||||||
stream := NewStream(newCfg, buf, 4096)
|
|
||||||
stream.WriteArrayStart()
|
stream.WriteArrayStart()
|
||||||
stream.WriteInt(1)
|
stream.WriteInt(1)
|
||||||
stream.WriteMore()
|
stream.WriteMore()
|
||||||
|
@ -60,9 +60,8 @@ func Test_customize_byte_array_encoder(t *testing.T) {
|
|||||||
|
|
||||||
func Test_customize_float_marshal(t *testing.T) {
|
func Test_customize_float_marshal(t *testing.T) {
|
||||||
should := require.New(t)
|
should := require.New(t)
|
||||||
EnableLossyFloatMarshalling()
|
json := Config{MarshalFloatWith6Digits: true}
|
||||||
defer DEFAULT_CONFIG.CleanEncoders()
|
str, err := json.MarshalToString(float32(1.23456789))
|
||||||
str, err := MarshalToString(float32(1.23456789))
|
|
||||||
should.Nil(err)
|
should.Nil(err)
|
||||||
should.Equal("1.234568", str)
|
should.Equal("1.234568", str)
|
||||||
}
|
}
|
||||||
@ -113,7 +112,7 @@ func Test_customize_field_by_extension(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_unexported_fields(t *testing.T) {
|
func Test_unexported_fields(t *testing.T) {
|
||||||
EnableUnexportedStructFieldsSupport()
|
jsoniter := &Config{SupportUnexportedStructFields: true}
|
||||||
should := require.New(t)
|
should := require.New(t)
|
||||||
type TestObject struct {
|
type TestObject struct {
|
||||||
field1 string
|
field1 string
|
||||||
@ -121,12 +120,12 @@ func Test_unexported_fields(t *testing.T) {
|
|||||||
}
|
}
|
||||||
obj := TestObject{}
|
obj := TestObject{}
|
||||||
obj.field1 = "hello"
|
obj.field1 = "hello"
|
||||||
should.Nil(UnmarshalFromString(`{}`, &obj))
|
should.Nil(jsoniter.UnmarshalFromString(`{}`, &obj))
|
||||||
should.Equal("hello", obj.field1)
|
should.Equal("hello", obj.field1)
|
||||||
should.Nil(UnmarshalFromString(`{"field1": "world", "field-2": "abc"}`, &obj))
|
should.Nil(jsoniter.UnmarshalFromString(`{"field1": "world", "field-2": "abc"}`, &obj))
|
||||||
should.Equal("world", obj.field1)
|
should.Equal("world", obj.field1)
|
||||||
should.Equal("abc", obj.field2)
|
should.Equal("abc", obj.field2)
|
||||||
str, err := MarshalToString(obj)
|
str, err := jsoniter.MarshalToString(obj)
|
||||||
should.Nil(err)
|
should.Nil(err)
|
||||||
should.Contains(str, `"field-2":"abc"`)
|
should.Contains(str, `"field-2":"abc"`)
|
||||||
}
|
}
|
||||||
|
@ -210,9 +210,7 @@ func Test_object_wrapper_any_get_all(t *testing.T) {
|
|||||||
func Test_write_object(t *testing.T) {
|
func Test_write_object(t *testing.T) {
|
||||||
should := require.New(t)
|
should := require.New(t)
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
newCfg := &Config{IndentionStep: 2}
|
stream := NewStream(&Config{IndentionStep: 2}, buf, 4096)
|
||||||
initConfig(newCfg)
|
|
||||||
stream := NewStream(newCfg, buf, 4096)
|
|
||||||
stream.WriteObjectStart()
|
stream.WriteObjectStart()
|
||||||
stream.WriteObjectField("hello")
|
stream.WriteObjectField("hello")
|
||||||
stream.WriteInt(1)
|
stream.WriteInt(1)
|
||||||
|
@ -21,26 +21,26 @@ func Test_encode_optional_int_pointer(t *testing.T) {
|
|||||||
func Test_decode_struct_with_optional_field(t *testing.T) {
|
func Test_decode_struct_with_optional_field(t *testing.T) {
|
||||||
should := require.New(t)
|
should := require.New(t)
|
||||||
type TestObject struct {
|
type TestObject struct {
|
||||||
field1 *string
|
Field1 *string
|
||||||
field2 *string
|
Field2 *string
|
||||||
}
|
}
|
||||||
obj := TestObject{}
|
obj := TestObject{}
|
||||||
UnmarshalFromString(`{"field1": null, "field2": "world"}`, &obj)
|
UnmarshalFromString(`{"field1": null, "field2": "world"}`, &obj)
|
||||||
should.Nil(obj.field1)
|
should.Nil(obj.Field1)
|
||||||
should.Equal("world", *obj.field2)
|
should.Equal("world", *obj.Field2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_encode_struct_with_optional_field(t *testing.T) {
|
func Test_encode_struct_with_optional_field(t *testing.T) {
|
||||||
should := require.New(t)
|
should := require.New(t)
|
||||||
type TestObject struct {
|
type TestObject struct {
|
||||||
field1 *string
|
Field1 *string
|
||||||
field2 *string
|
Field2 *string
|
||||||
}
|
}
|
||||||
obj := TestObject{}
|
obj := TestObject{}
|
||||||
world := "world"
|
world := "world"
|
||||||
obj.field2 = &world
|
obj.Field2 = &world
|
||||||
str, err := MarshalToString(obj)
|
str, err := MarshalToString(obj)
|
||||||
should.Nil(err)
|
should.Nil(err)
|
||||||
should.Contains(str, `"field1":null`)
|
should.Contains(str, `"Field1":null`)
|
||||||
should.Contains(str, `"field2":"world"`)
|
should.Contains(str, `"Field2":"world"`)
|
||||||
}
|
}
|
||||||
|
@ -24,8 +24,8 @@ func Test_decode_large_slice(t *testing.T) {
|
|||||||
|
|
||||||
func Test_decode_nested(t *testing.T) {
|
func Test_decode_nested(t *testing.T) {
|
||||||
type StructOfString struct {
|
type StructOfString struct {
|
||||||
field1 string
|
Field1 string
|
||||||
field2 string
|
Field2 string
|
||||||
}
|
}
|
||||||
iter := ParseString(DEFAULT_CONFIG, `[{"field1": "hello"}, null, {"field2": "world"}]`)
|
iter := ParseString(DEFAULT_CONFIG, `[{"field1": "hello"}, null, {"field2": "world"}]`)
|
||||||
slice := []*StructOfString{}
|
slice := []*StructOfString{}
|
||||||
@ -34,7 +34,7 @@ func Test_decode_nested(t *testing.T) {
|
|||||||
fmt.Println(iter.Error)
|
fmt.Println(iter.Error)
|
||||||
t.Fatal(len(slice))
|
t.Fatal(len(slice))
|
||||||
}
|
}
|
||||||
if slice[0].field1 != "hello" {
|
if slice[0].Field1 != "hello" {
|
||||||
fmt.Println(iter.Error)
|
fmt.Println(iter.Error)
|
||||||
t.Fatal(slice[0])
|
t.Fatal(slice[0])
|
||||||
}
|
}
|
||||||
@ -42,7 +42,7 @@ func Test_decode_nested(t *testing.T) {
|
|||||||
fmt.Println(iter.Error)
|
fmt.Println(iter.Error)
|
||||||
t.Fatal(slice[1])
|
t.Fatal(slice[1])
|
||||||
}
|
}
|
||||||
if slice[2].field2 != "world" {
|
if slice[2].Field2 != "world" {
|
||||||
fmt.Println(iter.Error)
|
fmt.Println(iter.Error)
|
||||||
t.Fatal(slice[2])
|
t.Fatal(slice[2])
|
||||||
}
|
}
|
||||||
|
@ -31,9 +31,7 @@ func Test_writeBytes_should_grow_buffer(t *testing.T) {
|
|||||||
|
|
||||||
func Test_writeIndention_should_grow_buffer(t *testing.T) {
|
func Test_writeIndention_should_grow_buffer(t *testing.T) {
|
||||||
should := require.New(t)
|
should := require.New(t)
|
||||||
newCfg := &Config{IndentionStep: 2}
|
stream := NewStream(&Config{IndentionStep: 2}, nil, 1)
|
||||||
initConfig(newCfg)
|
|
||||||
stream := NewStream(newCfg, nil, 1)
|
|
||||||
stream.WriteVal([]int{1, 2, 3})
|
stream.WriteVal([]int{1, 2, 3})
|
||||||
should.Equal("[\n 1,\n 2,\n 3\n]", string(stream.Buffer()))
|
should.Equal("[\n 1,\n 2,\n 3\n]", string(stream.Buffer()))
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user