2
0
Fork 0
mirror of https://github.com/ii64/sonic.git synced 2026-06-21 00:46:43 +08:00

fix: useint64 in decode SetOption (#268)

* fix: useint64 in decode SetOption

* doc: add comments on `sonic.Config`

Co-authored-by: liuqiang <liuqiang.06@bytedance.com>
Co-authored-by: duanyi.aster <duanyi.aster@bytedance.com>
This commit is contained in:
liu 2022-07-25 14:26:18 +08:00 committed by GitHub
parent 755c0252a9
commit 34026b9c65
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 12 deletions

44
api.go
View file

@ -22,16 +22,48 @@ import (
// Config is a combination of sonic/encoder.Options and sonic/decoder.Options // Config is a combination of sonic/encoder.Options and sonic/decoder.Options
type Config struct { type Config struct {
// EscapeHTML indicates encoder to escape all HTML characters
// after serializing into JSON (see https://pkg.go.dev/encoding/json#HTMLEscape).
// WARNING: This hurts performance A LOT, USE WITH CARE.
EscapeHTML bool EscapeHTML bool
// SortMapKeys indicates encoder that the keys of a map needs to be sorted
// before serializing into JSON.
// WARNING: This hurts performance A LOT, USE WITH CARE.
SortMapKeys bool SortMapKeys bool
// CompactMarshaler indicates encoder that the output JSON from json.Marshaler
// is always compact and needs no validation
CompactMarshaler bool CompactMarshaler bool
// NoQuoteTextMarshaler indicates encoder that the output text from encoding.TextMarshaler
// is always escaped string and needs no quoting
NoQuoteTextMarshaler bool NoQuoteTextMarshaler bool
UseInt64 bool
UseNumber bool // NoNullSliceOrMap indicates encoder that all empty Array or Object are encoded as '[]' or '{}',
UseUnicodeErrors bool // instead of 'null'
DisallowUnknownFields bool
CopyString bool
NoNullSliceOrMap bool NoNullSliceOrMap bool
// UseInt64 indicates decoder to unmarshal an integer into an interface{} as an
// int64 instead of as a float64.
UseInt64 bool
// UseNumber indicates decoder to unmarshal a number into an interface{} as a
// json.Number instead of as a float64.
UseNumber bool
// UseUnicodeErrors indicates decoder to return an error when encounter invalid
// UTF-8 escape sequences.
UseUnicodeErrors bool
// DisallowUnknownFields indicates decoder to return an error when the destination
// is a struct and the input contains object keys which do not match any
// non-ignored, exported fields in the destination.
DisallowUnknownFields bool
// CopyString indicates decoder to decode string values by copying instead of referring.
CopyString bool
} }
var ( var (
@ -53,7 +85,7 @@ import (
) )
// API a binding of specific config. // API is a binding of specific config.
// This interface is inspired by github.com/json-iterator/go, // This interface is inspired by github.com/json-iterator/go,
// and has same behaviors under equavilent config. // and has same behaviors under equavilent config.
type API interface { type API interface {

View file

@ -48,7 +48,7 @@ const (
) )
func (self *Decoder) SetOptions(opts Options) { func (self *Decoder) SetOptions(opts Options) {
if (opts & 1<<_F_use_number != 0) && (opts & 1<<_F_use_int64 != 0) { if (opts & OptionUseNumber != 0) && (opts & OptionUseInt64 != 0) {
panic("can't set OptionUseInt64 and OptionUseNumber both!") panic("can't set OptionUseInt64 and OptionUseNumber both!")
} }
self.f = uint64(opts) self.f = uint64(opts)
@ -107,34 +107,34 @@ func (self *Decoder) Decode(val interface{}) error {
return err return err
} }
// UseInt64 causes the Decoder to unmarshal an integer into an interface{} as an // UseInt64 indicates the Decoder to unmarshal an integer into an interface{} as an
// int64 instead of as a float64. // int64 instead of as a float64.
func (self *Decoder) UseInt64() { func (self *Decoder) UseInt64() {
self.f |= 1 << _F_use_int64 self.f |= 1 << _F_use_int64
self.f &^= 1 << _F_use_number self.f &^= 1 << _F_use_number
} }
// UseNumber causes the Decoder to unmarshal a number into an interface{} as a // UseNumber indicates the Decoder to unmarshal a number into an interface{} as a
// json.Number instead of as a float64. // json.Number instead of as a float64.
func (self *Decoder) UseNumber() { func (self *Decoder) UseNumber() {
self.f &^= 1 << _F_use_int64 self.f &^= 1 << _F_use_int64
self.f |= 1 << _F_use_number self.f |= 1 << _F_use_number
} }
// UseUnicodeErrors causes the Decoder to return an error when encounter invalid // UseUnicodeErrors indicates the Decoder to return an error when encounter invalid
// UTF-8 escape sequences. // UTF-8 escape sequences.
func (self *Decoder) UseUnicodeErrors() { func (self *Decoder) UseUnicodeErrors() {
self.f |= 1 << _F_disable_urc self.f |= 1 << _F_disable_urc
} }
// DisallowUnknownFields causes the Decoder to return an error when the destination // DisallowUnknownFields indicates the Decoder to return an error when the destination
// is a struct and the input contains object keys which do not match any // is a struct and the input contains object keys which do not match any
// non-ignored, exported fields in the destination. // non-ignored, exported fields in the destination.
func (self *Decoder) DisallowUnknownFields() { func (self *Decoder) DisallowUnknownFields() {
self.f |= 1 << _F_disable_unknown self.f |= 1 << _F_disable_unknown
} }
// CopyString causes the Decoder to decode string values by copying instead of referring. // CopyString indicates the Decoder to decode string values by copying instead of referring.
func (self *Decoder) CopyString() { func (self *Decoder) CopyString() {
self.f |= 1 << _F_copy_string self.f |= 1 << _F_copy_string
} }

View file

@ -275,6 +275,15 @@ func TestDecoder_Binding(t *testing.T) {
spew.Dump(v) spew.Dump(v)
} }
func TestDecoder_SetOption(t *testing.T) {
var v interface{}
d := NewDecoder("123")
d.SetOptions(OptionUseInt64)
err := d.Decode(&v)
assert.NoError(t, err)
assert.Equal(t, v, int64(123))
}
func TestDecoder_MapWithIndirectElement(t *testing.T) { func TestDecoder_MapWithIndirectElement(t *testing.T) {
var v map[string]struct { A [129]byte } var v map[string]struct { A [129]byte }
_, err := decode(`{"":{"A":[1,2,3,4,5]}}`, &v, false) _, err := decode(`{"":{"A":[1,2,3,4,5]}}`, &v, false)