}
}
+// Read reads from any buffered data past the last line read, or from the underlying
+// io.Reader if the buffer is empty.
+func (l *Reader) Read(p []byte) (n int, err os.Error) {
+ l.removeConsumedFromBuffer()
+ if len(l.buf) > 0 {
+ n = copy(p, l.buf)
+ l.consumed += n
+ return
+ }
+ return l.in.Read(p)
+}
+
+func (l *Reader) removeConsumedFromBuffer() {
+ if l.consumed > 0 {
+ n := copy(l.buf, l.buf[l.consumed:])
+ l.buf = l.buf[:n]
+ l.consumed = 0
+ }
+}
+
// ReadLine tries to return a single line, not including the end-of-line bytes.
// If the line was found to be longer than the maximum length then isPrefix is
// set and the beginning of the line is returned. The rest of the line will be
// the Reader and is only valid until the next call to ReadLine. ReadLine
// either returns a non-nil line or it returns an error, never both.
func (l *Reader) ReadLine() (line []byte, isPrefix bool, err os.Error) {
- if l.consumed > 0 {
- n := copy(l.buf, l.buf[l.consumed:])
- l.buf = l.buf[:n]
- l.consumed = 0
- }
+ l.removeConsumedFromBuffer()
if len(l.buf) == 0 && l.err != nil {
err = l.err
import (
"bytes"
+ "io"
"os"
"testing"
)
t.Errorf("bad result for third line: %x", line)
}
}
+
+func TestReadAfterLines(t *testing.T) {
+ line1 := "line1"
+ restData := "line2\nline 3\n"
+ inbuf := bytes.NewBuffer([]byte(line1 + "\n" + restData))
+ outbuf := new(bytes.Buffer)
+ maxLineLength := len(line1) + len(restData)/2
+ l := NewReader(inbuf, maxLineLength)
+ line, isPrefix, err := l.ReadLine()
+ if isPrefix || err != nil || string(line) != line1 {
+ t.Errorf("bad result for first line: isPrefix=%v err=%v line=%q", isPrefix, err, string(line))
+ }
+ n, err := io.Copy(outbuf, l)
+ if int(n) != len(restData) || err != nil {
+ t.Errorf("bad result for Read: n=%d err=%v", n, err)
+ }
+ if outbuf.String() != restData {
+ t.Errorf("bad result for Read: got %q; expected %q", outbuf.String(), restData)
+ }
+}