]> Cypherpunks repositories - gostls13.git/commitdiff
strings, bytes: fix Reader.UnreadRune
authorRui Ueyama <ruiu@google.com>
Wed, 19 Mar 2014 16:00:58 +0000 (09:00 -0700)
committerBrad Fitzpatrick <bradfitz@golang.org>
Wed, 19 Mar 2014 16:00:58 +0000 (09:00 -0700)
UnreadRune should return an error if previous operation is not
ReadRune.

Fixes #7579.

LGTM=bradfitz
R=golang-codereviews, bradfitz
CC=golang-codereviews
https://golang.org/cl/77580046

src/pkg/bytes/reader.go
src/pkg/bytes/reader_test.go
src/pkg/strings/reader.go
src/pkg/strings/strings_test.go

index 77511b94555634d1ab934e3bd692802351eebce1..8041a3b324944f788f74974370d8aa67319aa0b2 100644 (file)
@@ -30,6 +30,7 @@ func (r *Reader) Len() int {
 }
 
 func (r *Reader) Read(b []byte) (n int, err error) {
+       r.prevRune = -1
        if len(b) == 0 {
                return 0, nil
        }
@@ -38,11 +39,11 @@ func (r *Reader) Read(b []byte) (n int, err error) {
        }
        n = copy(b, r.s[r.i:])
        r.i += n
-       r.prevRune = -1
        return
 }
 
 func (r *Reader) ReadAt(b []byte, off int64) (n int, err error) {
+       r.prevRune = -1
        if off < 0 {
                return 0, errors.New("bytes: invalid offset")
        }
@@ -57,12 +58,12 @@ func (r *Reader) ReadAt(b []byte, off int64) (n int, err error) {
 }
 
 func (r *Reader) ReadByte() (b byte, err error) {
+       r.prevRune = -1
        if r.i >= len(r.s) {
                return 0, io.EOF
        }
        b = r.s[r.i]
        r.i++
-       r.prevRune = -1
        return
 }
 
@@ -77,6 +78,7 @@ func (r *Reader) UnreadByte() error {
 
 func (r *Reader) ReadRune() (ch rune, size int, err error) {
        if r.i >= len(r.s) {
+               r.prevRune = -1
                return 0, 0, io.EOF
        }
        r.prevRune = r.i
@@ -100,6 +102,7 @@ func (r *Reader) UnreadRune() error {
 
 // Seek implements the io.Seeker interface.
 func (r *Reader) Seek(offset int64, whence int) (int64, error) {
+       r.prevRune = -1
        var abs int64
        switch whence {
        case 0:
index 19f014da030aa4162ad0b4efa1658aecbe167b71..01cfa6deb5bfb73ab767ca29c7d2617fff97a0ac 100644 (file)
@@ -133,6 +133,33 @@ func TestReaderLen(t *testing.T) {
        }
 }
 
+var UnreadRuneErrorTests = []struct {
+       name string
+       f    func(*Reader)
+}{
+       {"Read", func(r *Reader) { r.Read([]byte{}) }},
+       {"ReadAt", func(r *Reader) { r.ReadAt([]byte{}, 0) }},
+       {"ReadByte", func(r *Reader) { r.ReadByte() }},
+       {"UnreadRune", func(r *Reader) { r.UnreadRune() }},
+       {"Seek", func(r *Reader) { r.Seek(0, 1) }},
+       {"WriteTo", func(r *Reader) { r.WriteTo(&Buffer{}) }},
+}
+
+func TestUnreadRuneError(t *testing.T) {
+       for _, tt := range UnreadRuneErrorTests {
+               reader := NewReader([]byte("0123456789"))
+               if _, _, err := reader.ReadRune(); err != nil {
+                       // should not happen
+                       t.Fatal(err)
+               }
+               tt.f(reader)
+               err := reader.UnreadRune()
+               if err == nil {
+                       t.Errorf("Unreading after %s: expected error", tt.name)
+               }
+       }
+}
+
 func TestReaderDoubleUnreadRune(t *testing.T) {
        buf := NewBuffer([]byte("groucho"))
        if _, _, err := buf.ReadRune(); err != nil {
index 11240efc0780f7223d1e88a8b9161fb481b9414e..df4d807120d953bf3f434ca44e41214d8d46a1af 100644 (file)
@@ -29,6 +29,7 @@ func (r *Reader) Len() int {
 }
 
 func (r *Reader) Read(b []byte) (n int, err error) {
+       r.prevRune = -1
        if len(b) == 0 {
                return 0, nil
        }
@@ -37,11 +38,11 @@ func (r *Reader) Read(b []byte) (n int, err error) {
        }
        n = copy(b, r.s[r.i:])
        r.i += n
-       r.prevRune = -1
        return
 }
 
 func (r *Reader) ReadAt(b []byte, off int64) (n int, err error) {
+       r.prevRune = -1
        if off < 0 {
                return 0, errors.New("strings: invalid offset")
        }
@@ -56,12 +57,12 @@ func (r *Reader) ReadAt(b []byte, off int64) (n int, err error) {
 }
 
 func (r *Reader) ReadByte() (b byte, err error) {
+       r.prevRune = -1
        if r.i >= len(r.s) {
                return 0, io.EOF
        }
        b = r.s[r.i]
        r.i++
-       r.prevRune = -1
        return
 }
 
@@ -76,6 +77,7 @@ func (r *Reader) UnreadByte() error {
 
 func (r *Reader) ReadRune() (ch rune, size int, err error) {
        if r.i >= len(r.s) {
+               r.prevRune = -1
                return 0, 0, io.EOF
        }
        r.prevRune = r.i
@@ -99,6 +101,7 @@ func (r *Reader) UnreadRune() error {
 
 // Seek implements the io.Seeker interface.
 func (r *Reader) Seek(offset int64, whence int) (int64, error) {
+       r.prevRune = -1
        var abs int64
        switch whence {
        case 0:
index a5be2f9bed5e0e56f43d5a7b5e5db0dcfcf6788e..5c389657755b92d66d49d21965cc08f39cdb5c2c 100644 (file)
@@ -858,6 +858,33 @@ func TestReadRune(t *testing.T) {
        }
 }
 
+var UnreadRuneErrorTests = []struct {
+       name string
+       f    func(*Reader)
+}{
+       {"Read", func(r *Reader) { r.Read([]byte{}) }},
+       {"ReadAt", func(r *Reader) { r.ReadAt([]byte{}, 0) }},
+       {"ReadByte", func(r *Reader) { r.ReadByte() }},
+       {"UnreadRune", func(r *Reader) { r.UnreadRune() }},
+       {"Seek", func(r *Reader) { r.Seek(0, 1) }},
+       {"WriteTo", func(r *Reader) { r.WriteTo(&bytes.Buffer{}) }},
+}
+
+func TestUnreadRuneError(t *testing.T) {
+       for _, tt := range UnreadRuneErrorTests {
+               reader := NewReader("0123456789")
+               if _, _, err := reader.ReadRune(); err != nil {
+                       // should not happen
+                       t.Fatal(err)
+               }
+               tt.f(reader)
+               err := reader.UnreadRune()
+               if err == nil {
+                       t.Errorf("Unreading after %s: expected error", tt.name)
+               }
+       }
+}
+
 var ReplaceTests = []struct {
        in       string
        old, new string