diff options
Diffstat (limited to 'decode_scan.go')
-rw-r--r-- | decode_scan.go | 97 |
1 files changed, 60 insertions, 37 deletions
diff --git a/decode_scan.go b/decode_scan.go index 7a52975..7911c01 100644 --- a/decode_scan.go +++ b/decode_scan.go @@ -19,8 +19,8 @@ type runeTypeScanner struct { parser jsonparse.Parser // initialized by constructor offset int64 - initialized bool - repeat bool + rTypeOK bool + repeat bool rRune rune rSize int @@ -28,28 +28,6 @@ type runeTypeScanner struct { rErr error } -func (sc *runeTypeScanner) Reset() { - sc.parser.Reset() - if sc.repeat || (sc.rType == jsonparse.RuneTypeEOF && sc.rSize > 0) { - sc.repeat = false - // re-figure the rType and rErr - var err error - sc.rType, err = sc.parser.HandleRune(sc.rRune) - if err != nil { - sc.rErr = &DecodeSyntaxError{ - Offset: sc.offset - int64(sc.rSize), - Err: err, - } - } else { - sc.rErr = nil - } - // tell it to use that rType and rErr - _ = sc.UnreadRune() // we set it up to always succeed - } else { - sc.initialized = false - } -} - // The returned error is a *ReadError, a *SyntaxError, or nil. // An EOF condition is represented as one of: // @@ -59,12 +37,13 @@ func (sc *runeTypeScanner) Reset() { // end of file at start of value: (_, 0, RuneTypeError, &DecodeSyntaxError{Offset: offset: Err: io.EOF}) func (sc *runeTypeScanner) ReadRuneType() (rune, int, jsonparse.RuneType, error) { switch { - case sc.initialized && (sc.rType == jsonparse.RuneTypeError || sc.rType == jsonparse.RuneTypeEOF): + case sc.rTypeOK && (sc.rType == jsonparse.RuneTypeError || sc.rType == jsonparse.RuneTypeEOF): // do nothing case sc.repeat: + sc.offset += int64(sc.rSize) _, _, _ = sc.inner.ReadRune() default: - sc.initialized = true + sc.rTypeOK = true again: var err error sc.rRune, sc.rSize, err = sc.inner.ReadRune() @@ -105,26 +84,23 @@ func (sc *runeTypeScanner) ReadRuneType() (rune, int, jsonparse.RuneType, error) return sc.rRune, sc.rSize, sc.rType, sc.rErr } -// UnreadRune undoes a call to .ReadRune() or .ReadRuneType(). +// UnreadRune undoes a call to .ReadRuneType(). // -// If the last call to .ReadRune() or .ReadRuneType() has already been -// unread, or if that call returned a rune with size 0, then -// ErrInvalidUnreadRune is returned. Otherwise, nil is returned. +// If the last call to .ReadRuneType() has already been unread, or if +// that call returned a rune with size 0, then ErrInvalidUnreadRune is +// returned. Otherwise, nil is returned. func (sc *runeTypeScanner) UnreadRune() error { if sc.repeat || sc.rSize == 0 { return ErrInvalidUnreadRune } sc.repeat = true + sc.offset -= int64(sc.rSize) _ = sc.inner.UnreadRune() return nil } func (sc *runeTypeScanner) InputOffset() int64 { - ret := sc.offset - if sc.repeat { - ret -= int64(sc.rSize) - } - return ret + return sc.offset } func (sc *runeTypeScanner) PushReadBarrier() { @@ -133,7 +109,20 @@ func (sc *runeTypeScanner) PushReadBarrier() { func (sc *runeTypeScanner) PopReadBarrier() { sc.parser.PopBarrier() - if sc.repeat || (sc.rType == jsonparse.RuneTypeEOF && sc.rSize > 0) { + switch { + case sc.repeat: + // re-figure the rType and rErr + var err error + sc.rType, err = sc.parser.HandleRune(sc.rRune) + if err != nil { + sc.rErr = &DecodeSyntaxError{ + Offset: sc.offset - int64(sc.rSize), + Err: err, + } + } else { + sc.rErr = nil + } + case sc.rType == jsonparse.RuneTypeEOF && sc.rSize > 0: // re-figure the rType and rErr var err error sc.rType, err = sc.parser.HandleRune(sc.rRune) @@ -147,7 +136,7 @@ func (sc *runeTypeScanner) PopReadBarrier() { } // tell it to use that rType and rErr _ = sc.UnreadRune() // we set it up to always succeed - } else if sc.rType == jsonparse.RuneTypeEOF { + case sc.rType == jsonparse.RuneTypeEOF: // re-figure the rType and rErr var err error sc.rType, err = sc.parser.HandleEOF() @@ -161,3 +150,37 @@ func (sc *runeTypeScanner) PopReadBarrier() { } } } + +func (sc *runeTypeScanner) Reset() { + sc.parser.Reset() + switch { + case sc.repeat: + // re-figure the rType and rErr + var err error + sc.rType, err = sc.parser.HandleRune(sc.rRune) + if err != nil { + sc.rErr = &DecodeSyntaxError{ + Offset: sc.offset - int64(sc.rSize), + Err: err, + } + } else { + sc.rErr = nil + } + case sc.rType == jsonparse.RuneTypeEOF && sc.rSize > 0: + // re-figure the rType and rErr + var err error + sc.rType, err = sc.parser.HandleRune(sc.rRune) + if err != nil { + sc.rErr = &DecodeSyntaxError{ + Offset: sc.offset - int64(sc.rSize), + Err: err, + } + } else { + sc.rErr = nil + } + // tell it to use that rType and rErr + _ = sc.UnreadRune() // we set it up to always succeed + default: + sc.rTypeOK = false + } +} |