forked from mirror/go-json
Merge pull request #23 from goccy/feature/fix-disallow-unknown-fields
Fix implementation of DisallowUnknownFields for improvement performance
This commit is contained in:
commit
901128a986
|
@ -18,7 +18,6 @@ func (d Delim) String() string {
|
||||||
type decoder interface {
|
type decoder interface {
|
||||||
decode([]byte, int64, uintptr) (int64, error)
|
decode([]byte, int64, uintptr) (int64, error)
|
||||||
decodeStream(*stream, uintptr) error
|
decodeStream(*stream, uintptr) error
|
||||||
setDisallowUnknownFields(bool)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Decoder struct {
|
type Decoder struct {
|
||||||
|
@ -99,7 +98,6 @@ func (d *Decoder) decode(src []byte, header *interfaceHeader) error {
|
||||||
cachedDecoder.set(typeptr, compiledDec)
|
cachedDecoder.set(typeptr, compiledDec)
|
||||||
dec = compiledDec
|
dec = compiledDec
|
||||||
}
|
}
|
||||||
dec.setDisallowUnknownFields(d.disallowUnknownFields)
|
|
||||||
if _, err := dec.decode(src, 0, ptr); err != nil {
|
if _, err := dec.decode(src, 0, ptr); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -164,7 +162,6 @@ func (d *Decoder) Decode(v interface{}) error {
|
||||||
cachedDecoder.set(typeptr, compiledDec)
|
cachedDecoder.set(typeptr, compiledDec)
|
||||||
dec = compiledDec
|
dec = compiledDec
|
||||||
}
|
}
|
||||||
dec.setDisallowUnknownFields(d.disallowUnknownFields)
|
|
||||||
if err := d.prepareForDecode(); err != nil {
|
if err := d.prepareForDecode(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -252,7 +249,7 @@ func (d *Decoder) Token() (Token, error) {
|
||||||
// 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 (d *Decoder) DisallowUnknownFields() {
|
func (d *Decoder) DisallowUnknownFields() {
|
||||||
d.disallowUnknownFields = true
|
d.s.disallowUnknownFields = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) InputOffset() int64 {
|
func (d *Decoder) InputOffset() int64 {
|
||||||
|
|
|
@ -16,10 +16,6 @@ func newArrayDecoder(dec decoder, elemType *rtype, alen int) *arrayDecoder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *arrayDecoder) setDisallowUnknownFields(disallowUnknownFields bool) {
|
|
||||||
d.valueDecoder.setDisallowUnknownFields(disallowUnknownFields)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *arrayDecoder) decodeStream(s *stream, p uintptr) error {
|
func (d *arrayDecoder) decodeStream(s *stream, p uintptr) error {
|
||||||
for {
|
for {
|
||||||
switch s.char() {
|
switch s.char() {
|
||||||
|
|
|
@ -58,8 +58,6 @@ func falseBytes(s *stream) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *boolDecoder) setDisallowUnknownFields(_ bool) {}
|
|
||||||
|
|
||||||
func (d *boolDecoder) decodeStream(s *stream, p uintptr) error {
|
func (d *boolDecoder) decodeStream(s *stream, p uintptr) error {
|
||||||
s.skipWhiteSpace()
|
s.skipWhiteSpace()
|
||||||
for {
|
for {
|
||||||
|
|
|
@ -47,8 +47,6 @@ func floatBytes(s *stream) []byte {
|
||||||
return s.buf[start:s.cursor]
|
return s.buf[start:s.cursor]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *floatDecoder) setDisallowUnknownFields(_ bool) {}
|
|
||||||
|
|
||||||
func (d *floatDecoder) decodeStreamByte(s *stream) ([]byte, error) {
|
func (d *floatDecoder) decodeStreamByte(s *stream) ([]byte, error) {
|
||||||
for {
|
for {
|
||||||
switch s.char() {
|
switch s.char() {
|
||||||
|
|
|
@ -49,8 +49,6 @@ var (
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func (d *intDecoder) setDisallowUnknownFields(_ bool) {}
|
|
||||||
|
|
||||||
func (d *intDecoder) decodeStreamByte(s *stream) ([]byte, error) {
|
func (d *intDecoder) decodeStreamByte(s *stream) ([]byte, error) {
|
||||||
for {
|
for {
|
||||||
switch s.char() {
|
switch s.char() {
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
type interfaceDecoder struct {
|
type interfaceDecoder struct {
|
||||||
typ *rtype
|
typ *rtype
|
||||||
dummy unsafe.Pointer // for escape value
|
dummy unsafe.Pointer // for escape value
|
||||||
disallowUnknownFields bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newInterfaceDecoder(typ *rtype) *interfaceDecoder {
|
func newInterfaceDecoder(typ *rtype) *interfaceDecoder {
|
||||||
|
@ -17,10 +16,6 @@ func newInterfaceDecoder(typ *rtype) *interfaceDecoder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *interfaceDecoder) setDisallowUnknownFields(disallowUnknownFields bool) {
|
|
||||||
d.disallowUnknownFields = disallowUnknownFields
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *interfaceDecoder) numDecoder(s *stream) decoder {
|
func (d *interfaceDecoder) numDecoder(s *stream) decoder {
|
||||||
if s.useNumber {
|
if s.useNumber {
|
||||||
return newNumberDecoder(func(p uintptr, v Number) {
|
return newNumberDecoder(func(p uintptr, v Number) {
|
||||||
|
@ -46,13 +41,11 @@ func (d *interfaceDecoder) decodeStream(s *stream, p uintptr) error {
|
||||||
var v map[interface{}]interface{}
|
var v map[interface{}]interface{}
|
||||||
ptr := unsafe.Pointer(&v)
|
ptr := unsafe.Pointer(&v)
|
||||||
d.dummy = ptr
|
d.dummy = ptr
|
||||||
dec := newMapDecoder(
|
if err := newMapDecoder(
|
||||||
interfaceMapType,
|
interfaceMapType,
|
||||||
newInterfaceDecoder(d.typ),
|
newInterfaceDecoder(d.typ),
|
||||||
newInterfaceDecoder(d.typ),
|
newInterfaceDecoder(d.typ),
|
||||||
)
|
).decodeStream(s, uintptr(ptr)); err != nil {
|
||||||
dec.setDisallowUnknownFields(d.disallowUnknownFields)
|
|
||||||
if err := dec.decodeStream(s, uintptr(ptr)); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
*(*interface{})(unsafe.Pointer(p)) = v
|
*(*interface{})(unsafe.Pointer(p)) = v
|
||||||
|
@ -61,13 +54,11 @@ func (d *interfaceDecoder) decodeStream(s *stream, p uintptr) error {
|
||||||
var v []interface{}
|
var v []interface{}
|
||||||
ptr := unsafe.Pointer(&v)
|
ptr := unsafe.Pointer(&v)
|
||||||
d.dummy = ptr // escape ptr
|
d.dummy = ptr // escape ptr
|
||||||
dec := newSliceDecoder(
|
if err := newSliceDecoder(
|
||||||
newInterfaceDecoder(d.typ),
|
newInterfaceDecoder(d.typ),
|
||||||
d.typ,
|
d.typ,
|
||||||
d.typ.Size(),
|
d.typ.Size(),
|
||||||
)
|
).decodeStream(s, uintptr(ptr)); err != nil {
|
||||||
dec.setDisallowUnknownFields(d.disallowUnknownFields)
|
|
||||||
if err := dec.decodeStream(s, uintptr(ptr)); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
*(*interface{})(unsafe.Pointer(p)) = v
|
*(*interface{})(unsafe.Pointer(p)) = v
|
||||||
|
@ -135,7 +126,6 @@ func (d *interfaceDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, e
|
||||||
newInterfaceDecoder(d.typ),
|
newInterfaceDecoder(d.typ),
|
||||||
newInterfaceDecoder(d.typ),
|
newInterfaceDecoder(d.typ),
|
||||||
)
|
)
|
||||||
dec.setDisallowUnknownFields(d.disallowUnknownFields)
|
|
||||||
cursor, err := dec.decode(buf, cursor, uintptr(ptr))
|
cursor, err := dec.decode(buf, cursor, uintptr(ptr))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@ -151,7 +141,6 @@ func (d *interfaceDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, e
|
||||||
d.typ,
|
d.typ,
|
||||||
d.typ.Size(),
|
d.typ.Size(),
|
||||||
)
|
)
|
||||||
dec.setDisallowUnknownFields(d.disallowUnknownFields)
|
|
||||||
cursor, err := dec.decode(buf, cursor, uintptr(ptr))
|
cursor, err := dec.decode(buf, cursor, uintptr(ptr))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
|
|
@ -26,11 +26,6 @@ func makemap(*rtype, int) unsafe.Pointer
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func mapassign(t *rtype, m unsafe.Pointer, key, val unsafe.Pointer)
|
func mapassign(t *rtype, m unsafe.Pointer, key, val unsafe.Pointer)
|
||||||
|
|
||||||
func (d *mapDecoder) setDisallowUnknownFields(disallowUnknownFields bool) {
|
|
||||||
d.keyDecoder.setDisallowUnknownFields(disallowUnknownFields)
|
|
||||||
d.valueDecoder.setDisallowUnknownFields(disallowUnknownFields)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *mapDecoder) setKey(buf []byte, cursor int64, key interface{}) (int64, error) {
|
func (d *mapDecoder) setKey(buf []byte, cursor int64, key interface{}) (int64, error) {
|
||||||
header := (*interfaceHeader)(unsafe.Pointer(&key))
|
header := (*interfaceHeader)(unsafe.Pointer(&key))
|
||||||
return d.keyDecoder.decode(buf, cursor, uintptr(header.ptr))
|
return d.keyDecoder.decode(buf, cursor, uintptr(header.ptr))
|
||||||
|
|
|
@ -16,8 +16,6 @@ func newNumberDecoder(op func(uintptr, Number)) *numberDecoder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *numberDecoder) setDisallowUnknownFields(_ bool) {}
|
|
||||||
|
|
||||||
func (d *numberDecoder) decodeStream(s *stream, p uintptr) error {
|
func (d *numberDecoder) decodeStream(s *stream, p uintptr) error {
|
||||||
bytes, err := d.floatDecoder.decodeStreamByte(s)
|
bytes, err := d.floatDecoder.decodeStreamByte(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -16,10 +16,6 @@ func newPtrDecoder(dec decoder, typ *rtype) *ptrDecoder {
|
||||||
//go:linkname unsafe_New reflect.unsafe_New
|
//go:linkname unsafe_New reflect.unsafe_New
|
||||||
func unsafe_New(*rtype) uintptr
|
func unsafe_New(*rtype) uintptr
|
||||||
|
|
||||||
func (d *ptrDecoder) setDisallowUnknownFields(disallowUnknownFields bool) {
|
|
||||||
d.dec.setDisallowUnknownFields(disallowUnknownFields)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *ptrDecoder) decodeStream(s *stream, p uintptr) error {
|
func (d *ptrDecoder) decodeStream(s *stream, p uintptr) error {
|
||||||
newptr := unsafe_New(d.typ)
|
newptr := unsafe_New(d.typ)
|
||||||
if err := d.dec.decodeStream(s, newptr); err != nil {
|
if err := d.dec.decodeStream(s, newptr); err != nil {
|
||||||
|
|
|
@ -56,10 +56,6 @@ func copySlice(elemType *rtype, dst, src reflect.SliceHeader) int
|
||||||
//go:linkname newArray reflect.unsafe_NewArray
|
//go:linkname newArray reflect.unsafe_NewArray
|
||||||
func newArray(*rtype, int) unsafe.Pointer
|
func newArray(*rtype, int) unsafe.Pointer
|
||||||
|
|
||||||
func (d *sliceDecoder) setDisallowUnknownFields(disallowUnknownFields bool) {
|
|
||||||
d.valueDecoder.setDisallowUnknownFields(disallowUnknownFields)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *sliceDecoder) decodeStream(s *stream, p uintptr) error {
|
func (d *sliceDecoder) decodeStream(s *stream, p uintptr) error {
|
||||||
for {
|
for {
|
||||||
switch s.char() {
|
switch s.char() {
|
||||||
|
|
|
@ -17,6 +17,7 @@ type stream struct {
|
||||||
cursor int64
|
cursor int64
|
||||||
allRead bool
|
allRead bool
|
||||||
useNumber bool
|
useNumber bool
|
||||||
|
disallowUnknownFields bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *stream) buffered() io.Reader {
|
func (s *stream) buffered() io.Reader {
|
||||||
|
|
|
@ -11,8 +11,6 @@ func newStringDecoder() *stringDecoder {
|
||||||
return &stringDecoder{}
|
return &stringDecoder{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *stringDecoder) setDisallowUnknownFields(_ bool) {}
|
|
||||||
|
|
||||||
func (d *stringDecoder) decodeStream(s *stream, p uintptr) error {
|
func (d *stringDecoder) decodeStream(s *stream, p uintptr) error {
|
||||||
bytes, err := d.decodeStreamByte(s)
|
bytes, err := d.decodeStreamByte(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -13,7 +13,6 @@ type structFieldSet struct {
|
||||||
type structDecoder struct {
|
type structDecoder struct {
|
||||||
fieldMap map[string]*structFieldSet
|
fieldMap map[string]*structFieldSet
|
||||||
keyDecoder *stringDecoder
|
keyDecoder *stringDecoder
|
||||||
disallowUnknownFields bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newStructDecoder(fieldMap map[string]*structFieldSet) *structDecoder {
|
func newStructDecoder(fieldMap map[string]*structFieldSet) *structDecoder {
|
||||||
|
@ -23,13 +22,6 @@ func newStructDecoder(fieldMap map[string]*structFieldSet) *structDecoder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *structDecoder) setDisallowUnknownFields(disallowUnknownFields bool) {
|
|
||||||
d.disallowUnknownFields = disallowUnknownFields
|
|
||||||
for _, field := range d.fieldMap {
|
|
||||||
field.dec.setDisallowUnknownFields(disallowUnknownFields)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *structDecoder) decodeStream(s *stream, p uintptr) error {
|
func (d *structDecoder) decodeStream(s *stream, p uintptr) error {
|
||||||
s.skipWhiteSpace()
|
s.skipWhiteSpace()
|
||||||
if s.char() == nul {
|
if s.char() == nul {
|
||||||
|
@ -65,7 +57,7 @@ func (d *structDecoder) decodeStream(s *stream, p uintptr) error {
|
||||||
if err := field.dec.decodeStream(s, p+field.offset); err != nil {
|
if err := field.dec.decodeStream(s, p+field.offset); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else if d.disallowUnknownFields {
|
} else if s.disallowUnknownFields {
|
||||||
return fmt.Errorf("json: unknown field %q", k)
|
return fmt.Errorf("json: unknown field %q", k)
|
||||||
} else {
|
} else {
|
||||||
if err := s.skipValue(); err != nil {
|
if err := s.skipValue(); err != nil {
|
||||||
|
@ -121,8 +113,6 @@ func (d *structDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, erro
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
cursor = c
|
cursor = c
|
||||||
} else if d.disallowUnknownFields {
|
|
||||||
return 0, fmt.Errorf("json: unknown field %q", k)
|
|
||||||
} else {
|
} else {
|
||||||
c, err := skipValue(buf, cursor)
|
c, err := skipValue(buf, cursor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -24,8 +24,6 @@ func (d *uintDecoder) parseUint(b []byte) uint64 {
|
||||||
return sum
|
return sum
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *uintDecoder) setDisallowUnknownFields(_ bool) {}
|
|
||||||
|
|
||||||
func (d *uintDecoder) decodeStreamByte(s *stream) ([]byte, error) {
|
func (d *uintDecoder) decodeStreamByte(s *stream) ([]byte, error) {
|
||||||
for {
|
for {
|
||||||
switch s.char() {
|
switch s.char() {
|
||||||
|
|
|
@ -12,8 +12,6 @@ func newUnmarshalJSONDecoder(typ *rtype) *unmarshalJSONDecoder {
|
||||||
return &unmarshalJSONDecoder{typ: typ}
|
return &unmarshalJSONDecoder{typ: typ}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *unmarshalJSONDecoder) setDisallowUnknownFields(_ bool) {}
|
|
||||||
|
|
||||||
func (d *unmarshalJSONDecoder) decodeStream(s *stream, p uintptr) error {
|
func (d *unmarshalJSONDecoder) decodeStream(s *stream, p uintptr) error {
|
||||||
s.skipWhiteSpace()
|
s.skipWhiteSpace()
|
||||||
start := s.cursor
|
start := s.cursor
|
||||||
|
|
|
@ -13,8 +13,6 @@ func newUnmarshalTextDecoder(typ *rtype) *unmarshalTextDecoder {
|
||||||
return &unmarshalTextDecoder{typ: typ}
|
return &unmarshalTextDecoder{typ: typ}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *unmarshalTextDecoder) setDisallowUnknownFields(_ bool) {}
|
|
||||||
|
|
||||||
func (d *unmarshalTextDecoder) decodeStream(s *stream, p uintptr) error {
|
func (d *unmarshalTextDecoder) decodeStream(s *stream, p uintptr) error {
|
||||||
s.skipWhiteSpace()
|
s.skipWhiteSpace()
|
||||||
start := s.cursor
|
start := s.cursor
|
||||||
|
|
Loading…
Reference in New Issue