// UnreadRune unreads the last rune returned by ReadRune.
// If the most recent read or write operation on the buffer was
-// not a ReadRune, UnreadRune returns an error. (In this regard
+// not a successful ReadRune, UnreadRune returns an error. (In this regard
// it is stricter than UnreadByte, which will unread the last byte
// from any read operation.)
func (b *Buffer) UnreadRune() error {
if b.lastRead <= opInvalid {
- return errors.New("bytes.Buffer: UnreadRune: previous operation was not ReadRune")
+ return errors.New("bytes.Buffer: UnreadRune: previous operation was not a successful ReadRune")
}
if b.off >= int(b.lastRead) {
b.off -= int(b.lastRead)
return nil
}
-// UnreadByte unreads the last byte returned by the most recent
-// read operation. If write has happened since the last read, UnreadByte
-// returns an error.
+// UnreadByte unreads the last byte returned by the most recent successful
+// read operation that read at least one byte. If a write has happened since
+// the last read, if the last read returned an error, or if the read read zero
+// bytes, UnreadByte returns an error.
func (b *Buffer) UnreadByte() error {
if b.lastRead == opInvalid {
- return errors.New("bytes.Buffer: UnreadByte: previous operation was not a read")
+ return errors.New("bytes.Buffer: UnreadByte: previous operation was not a successful read")
}
b.lastRead = opInvalid
if b.off > 0 {
// Check that UnreadRune works
buf.Reset()
+
+ // check at EOF
+ if err := buf.UnreadRune(); err == nil {
+ t.Fatal("UnreadRune at EOF: got no error")
+ }
+ if _, _, err := buf.ReadRune(); err == nil {
+ t.Fatal("ReadRune at EOF: got no error")
+ }
+ if err := buf.UnreadRune(); err == nil {
+ t.Fatal("UnreadRune after ReadRune at EOF: got no error")
+ }
+
+ // check not at EOF
buf.Write(b)
for r := rune(0); r < NRune; r++ {
r1, size, _ := buf.ReadRune()
func TestUnreadByte(t *testing.T) {
b := new(Buffer)
+
+ // check at EOF
+ if err := b.UnreadByte(); err == nil {
+ t.Fatal("UnreadByte at EOF: got no error")
+ }
+ if _, err := b.ReadByte(); err == nil {
+ t.Fatal("ReadByte at EOF: got no error")
+ }
+ if err := b.UnreadByte(); err == nil {
+ t.Fatal("UnreadByte after ReadByte at EOF: got no error")
+ }
+
+ // check not at EOF
b.WriteString("abcdefghijklmnopqrstuvwxyz")
- _, err := b.ReadBytes('m')
- if err != nil {
- t.Fatalf("ReadBytes: %v", err)
+ // after unsuccessful read
+ if n, err := b.Read(nil); n != 0 || err != nil {
+ t.Fatalf("Read(nil) = %d,%v; want 0,nil", n, err)
+ }
+ if err := b.UnreadByte(); err == nil {
+ t.Fatal("UnreadByte after Read(nil): got no error")
}
- err = b.UnreadByte()
- if err != nil {
+ // after successful read
+ if _, err := b.ReadBytes('m'); err != nil {
+ t.Fatalf("ReadBytes: %v", err)
+ }
+ if err := b.UnreadByte(); err != nil {
t.Fatalf("UnreadByte: %v", err)
}
c, err := b.ReadByte()