forked from mirror/go-json
Fix decoding of recursive type
This commit is contained in:
parent
f38ee9ce45
commit
99a5b20e5e
|
@ -23,6 +23,7 @@ type decoder interface {
|
|||
type Decoder struct {
|
||||
s *stream
|
||||
disallowUnknownFields bool
|
||||
structTypeToDecoder map[uintptr]decoder
|
||||
}
|
||||
|
||||
type decoderMap struct {
|
||||
|
@ -61,7 +62,9 @@ const (
|
|||
func NewDecoder(r io.Reader) *Decoder {
|
||||
s := &stream{r: r}
|
||||
s.read()
|
||||
return &Decoder{s: s}
|
||||
return &Decoder{
|
||||
s: s,
|
||||
}
|
||||
}
|
||||
|
||||
// Buffered returns a reader of the data remaining in the Decoder's
|
||||
|
@ -90,7 +93,7 @@ func (d *Decoder) decode(src []byte, header *interfaceHeader) error {
|
|||
}
|
||||
dec := cachedDecoder.get(typeptr)
|
||||
if dec == nil {
|
||||
|
||||
d.structTypeToDecoder = map[uintptr]decoder{}
|
||||
compiledDec, err := d.compileHead(copiedType)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -155,6 +158,7 @@ func (d *Decoder) Decode(v interface{}) error {
|
|||
|
||||
dec := cachedDecoder.get(typeptr)
|
||||
if dec == nil {
|
||||
d.structTypeToDecoder = map[uintptr]decoder{}
|
||||
compiledDec, err := d.compileHead(typ)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -204,6 +204,12 @@ func (d *Decoder) compileInterface(typ *rtype) (decoder, error) {
|
|||
func (d *Decoder) compileStruct(typ *rtype) (decoder, error) {
|
||||
fieldNum := typ.NumField()
|
||||
fieldMap := map[string]*structFieldSet{}
|
||||
typeptr := uintptr(unsafe.Pointer(typ))
|
||||
if dec, exists := d.structTypeToDecoder[typeptr]; exists {
|
||||
return dec, nil
|
||||
}
|
||||
structDec := newStructDecoder(fieldMap)
|
||||
d.structTypeToDecoder[typeptr] = structDec
|
||||
for i := 0; i < fieldNum; i++ {
|
||||
field := typ.Field(i)
|
||||
if isIgnoredStructField(field) {
|
||||
|
@ -222,5 +228,6 @@ func (d *Decoder) compileStruct(typ *rtype) (decoder, error) {
|
|||
fieldMap[tag.key] = fieldSet
|
||||
fieldMap[strings.ToLower(tag.key)] = fieldSet
|
||||
}
|
||||
return newStructDecoder(fieldMap), nil
|
||||
delete(d.structTypeToDecoder, typeptr)
|
||||
return structDec, nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue