]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/line: make it an io.Reader too
authorBrad Fitzpatrick <bradfitz@golang.org>
Wed, 26 Jan 2011 14:59:53 +0000 (09:59 -0500)
committerAdam Langley <agl@golang.org>
Wed, 26 Jan 2011 14:59:53 +0000 (09:59 -0500)
R=agl1, bradfitzwork, rsc
CC=golang-dev
https://golang.org/cl/4066043

src/pkg/encoding/line/line.go
src/pkg/encoding/line/line_test.go

index f1c1061419c1f64d160ce201e7b7d14863699c27..779b5758adde09cad0a818197a063d73982f7fdb 100644 (file)
@@ -28,6 +28,26 @@ func NewReader(input io.Reader, maxLineLength int) *Reader {
        }
 }
 
+// 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
@@ -36,11 +56,7 @@ func NewReader(input io.Reader, maxLineLength int) *Reader {
 // 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
index 68d13b58616a5dfc38901257da790b6bff8cbc96..ff16d10c709d7cbab1cda4050f8dc4eb359e5205 100644 (file)
@@ -6,6 +6,7 @@ package line
 
 import (
        "bytes"
+       "io"
        "os"
        "testing"
 )
@@ -87,3 +88,23 @@ func TestLineTooLong(t *testing.T) {
                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)
+       }
+}