diff options
Diffstat (limited to 'decode.go')
-rw-r--r-- | decode.go | 56 |
1 files changed, 33 insertions, 23 deletions
@@ -104,7 +104,7 @@ const maxNestingDepth = 10000 // an io.Reader. func NewDecoder(r io.RuneScanner) *Decoder { return &Decoder{ - io: &runeTypeScannerImpl{ + io: runeTypeScanner{ inner: r, parser: internal.Parser{ MaxDepth: maxNestingDepth, @@ -245,6 +245,7 @@ func (dec *Decoder) Decode(ptr any) (err error) { } dec.io.Reset() + dec.io.PushReadBarrier() defer func() { if r := recover(); r != nil { if de, ok := r.(decodeError); ok { @@ -257,6 +258,7 @@ func (dec *Decoder) Decode(ptr any) (err error) { } }() dec.decode(ptrVal.Elem(), false) + dec.io.PopReadBarrier() return nil } @@ -319,12 +321,21 @@ func (dec *Decoder) expectRuneType(ec rune, et internal.RuneType, gt reflect.Typ } } -type decRuneTypeScanner struct { +type decRuneScanner struct { dec *Decoder + eof bool } -func (sc *decRuneTypeScanner) ReadRuneType() (rune, int, internal.RuneType, error) { +func (sc *decRuneScanner) ReadRune() (rune, int, error) { + if sc.eof { + return 0, 0, io.EOF + } c, s, t, e := sc.dec.io.ReadRuneType() + if t == internal.RuneTypeEOF { + sc.eof = true + sc.dec.io.PopReadBarrier() + return 0, 0, io.EOF + } if e != nil { panic(decodeError{ Field: sc.dec.structStackStr(), @@ -333,28 +344,17 @@ func (sc *decRuneTypeScanner) ReadRuneType() (rune, int, internal.RuneType, erro Err: e, }) } - return c, s, t, nil + return c, s, nil } -func (sc *decRuneTypeScanner) ReadRune() (rune, int, error) { - r, s, t, _ := sc.ReadRuneType() - switch t { - case internal.RuneTypeEOF: - return 0, 0, io.EOF - default: - return r, s, nil - } +func (sc *decRuneScanner) UnreadRune() error { + return sc.dec.io.UnreadRune() } -func (sc *decRuneTypeScanner) UnreadRune() error { return sc.dec.io.UnreadRune() } -func (sc *decRuneTypeScanner) InputOffset() int64 { return sc.dec.InputOffset() } -func (sc *decRuneTypeScanner) Reset() { sc.dec.io.Reset() } - -func (dec *Decoder) limitingScanner() runeTypeScanner { - return &elemRuneTypeScanner{ - inner: &decRuneTypeScanner{ - dec: dec, - }, +func (dec *Decoder) limitingScanner() io.RuneScanner { + dec.io.PushReadBarrier() + return &decRuneScanner{ + dec: dec, } } @@ -867,7 +867,12 @@ func DecodeObject(r io.RuneScanner, decodeKey, decodeVal func(io.RuneScanner) er } } }() - dec := NewDecoder(r) + var dec *Decoder + if dr, ok := r.(*decRuneScanner); ok { + dec = dr.dec + } else { + dec = NewDecoder(r) + } dec.posStackPush() defer dec.posStackPop() dec.decodeObject(nil, @@ -947,7 +952,12 @@ func DecodeArray(r io.RuneScanner, decodeMember func(r io.RuneScanner) error) (e } } }() - dec := NewDecoder(r) + var dec *Decoder + if dr, ok := r.(*decRuneScanner); ok { + dec = dr.dec + } else { + dec = NewDecoder(r) + } dec.posStackPush() defer dec.posStackPop() dec.decodeArray(nil, func() { |