var (
ErrInvalidUnreadByte os.Error = &Error{"bufio: invalid use of UnreadByte"}
ErrBufferFull os.Error = &Error{"bufio: buffer full"}
+ ErrNegativeCount os.Error = &Error{"bufio: negative count"}
errInternal os.Error = &Error{"bufio: internal error"}
)
// fill reads a new chunk into the buffer.
func (b *Reader) fill() {
// Slide existing data to beginning.
- if b.w > b.r {
- copy(b.buf[0:b.w-b.r], b.buf[b.r:b.w])
+ if b.r > 0 {
+ copy(b.buf, b.buf[b.r:b.w])
b.w -= b.r
- } else {
- b.w = 0
+ b.r = 0
}
- b.r = 0
// Read new data.
n, e := b.rd.Read(b.buf[b.w:])
}
}
+// Peek returns the next n bytes without advancing the reader. The bytes stop
+// being valid at the next read call. If Peek returns fewer than n bytes, it
+// also returns an error explaining why the read is short. The error is
+// ErrBufferFull if n is larger than b's buffer size.
+func (b *Reader) Peek(n int) ([]byte, os.Error) {
+ if n < 0 {
+ return nil, ErrNegativeCount
+ }
+ if n > len(b.buf) {
+ return nil, ErrBufferFull
+ }
+ for b.w-b.r < n && b.err == nil {
+ b.fill()
+ }
+ m := b.w - b.r
+ if m > n {
+ m = n
+ }
+ err := b.err
+ if m < n && err == nil {
+ err = ErrBufferFull
+ }
+ return b.buf[b.r : b.r+m], err
+}
+
// Read reads data into p.
// It returns the number of bytes read into p.
// If nn < len(p), also returns an error explaining
if n > b.w-b.r {
n = b.w - b.r
}
- copy(p[0:n], b.buf[b.r:b.r+n])
+ copy(p[0:n], b.buf[b.r:])
p = p[n:]
b.r += n
b.lastbyte = int(b.buf[b.r-1])
buf := make([]byte, n)
n = 0
for i := 0; i < nfull; i++ {
- copy(buf[n:n+len(full[i])], full[i])
+ copy(buf[n:], full[i])
n += len(full[i])
}
- copy(buf[n:n+len(frag)], frag)
+ copy(buf[n:], frag)
return buf, err
}
t.Errorf("second ReadSlice(,) = %q, %v", line, err)
}
}
+
+func TestPeek(t *testing.T) {
+ p := make([]byte, 10)
+ buf, _ := NewReaderSize(strings.NewReader("abcdefghij"), 4)
+ if s, err := buf.Peek(1); string(s) != "a" || err != nil {
+ t.Fatalf("want %q got %q, err=%v", "a", string(s), err)
+ }
+ if s, err := buf.Peek(4); string(s) != "abcd" || err != nil {
+ t.Fatalf("want %q got %q, err=%v", "abcd", string(s), err)
+ }
+ if _, err := buf.Peek(5); err != ErrBufferFull {
+ t.Fatalf("want ErrBufFull got %v", err)
+ }
+ if _, err := buf.Read(p[0:3]); string(p[0:3]) != "abc" || err != nil {
+ t.Fatalf("want %q got %q, err=%v", "abc", string(p[0:3]), err)
+ }
+ if s, err := buf.Peek(1); string(s) != "d" || err != nil {
+ t.Fatalf("want %q got %q, err=%v", "d", string(s), err)
+ }
+ if s, err := buf.Peek(2); string(s) != "de" || err != nil {
+ t.Fatalf("want %q got %q, err=%v", "de", string(s), err)
+ }
+ if _, err := buf.Read(p[0:3]); string(p[0:3]) != "def" || err != nil {
+ t.Fatalf("want %q got %q, err=%v", "def", string(p[0:3]), err)
+ }
+ if s, err := buf.Peek(4); string(s) != "ghij" || err != nil {
+ t.Fatalf("want %q got %q, err=%v", "ghij", string(s), err)
+ }
+ if _, err := buf.Read(p[0:4]); string(p[0:4]) != "ghij" || err != nil {
+ t.Fatalf("want %q got %q, err=%v", "ghij", string(p[0:3]), err)
+ }
+ if s, err := buf.Peek(0); string(s) != "" || err != nil {
+ t.Fatalf("want %q got %q, err=%v", "", string(s), err)
+ }
+ if _, err := buf.Peek(1); err != os.EOF {
+ t.Fatalf("want EOF got %v", err)
+ }
+}