summaryrefslogtreecommitdiff
path: root/decode_scan.go
diff options
context:
space:
mode:
Diffstat (limited to 'decode_scan.go')
-rw-r--r--decode_scan.go97
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
+ }
+}