aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/io
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2011-10-26 23:57:58 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2011-10-26 23:57:58 +0000
commitd8f412571f8768df2d3239e72392dfeabbad1559 (patch)
tree19d182df05ead7ff8ba7ee00a7d57555e1383fdf /libgo/go/io
parente0c39d66d4f0607177b1cf8995dda56a667e07b3 (diff)
downloadgcc-d8f412571f8768df2d3239e72392dfeabbad1559.zip
gcc-d8f412571f8768df2d3239e72392dfeabbad1559.tar.gz
gcc-d8f412571f8768df2d3239e72392dfeabbad1559.tar.bz2
Update Go library to last weekly.
From-SVN: r180552
Diffstat (limited to 'libgo/go/io')
-rw-r--r--libgo/go/io/io.go30
-rw-r--r--libgo/go/io/io_test.go67
-rw-r--r--libgo/go/io/ioutil/ioutil.go4
3 files changed, 78 insertions, 23 deletions
diff --git a/libgo/go/io/io.go b/libgo/go/io/io.go
index b879fe5..5520634 100644
--- a/libgo/go/io/io.go
+++ b/libgo/go/io/io.go
@@ -256,15 +256,15 @@ func ReadFull(r Reader, buf []byte) (n int, err os.Error) {
return ReadAtLeast(r, buf, len(buf))
}
-// Copyn copies n bytes (or until an error) from src to dst.
+// CopyN copies n bytes (or until an error) from src to dst.
// It returns the number of bytes copied and the earliest
// error encountered while copying. Because Read can
// return the full amount requested as well as an error
-// (including os.EOF), so can Copyn.
+// (including os.EOF), so can CopyN.
//
// If dst implements the ReaderFrom interface,
// the copy is implemented by calling dst.ReadFrom(src).
-func Copyn(dst Writer, src Reader, n int64) (written int64, err os.Error) {
+func CopyN(dst Writer, src Reader, n int64) (written int64, err os.Error) {
// If the writer has a ReadFrom method, use it to do the copy.
// Avoids a buffer allocation and a copy.
if rt, ok := dst.(ReaderFrom); ok {
@@ -437,3 +437,27 @@ func (s *SectionReader) ReadAt(p []byte, off int64) (n int, err os.Error) {
// Size returns the size of the section in bytes.
func (s *SectionReader) Size() int64 { return s.limit - s.base }
+
+// TeeReader returns a Reader that writes to w what it reads from r.
+// All reads from r performed through it are matched with
+// corresponding writes to w. There is no internal buffering -
+// the write must complete before the read completes.
+// Any error encountered while writing is reported as a read error.
+func TeeReader(r Reader, w Writer) Reader {
+ return &teeReader{r, w}
+}
+
+type teeReader struct {
+ r Reader
+ w Writer
+}
+
+func (t *teeReader) Read(p []byte) (n int, err os.Error) {
+ n, err = t.r.Read(p)
+ if n > 0 {
+ if n, err := t.w.Write(p[:n]); err != nil {
+ return n, err
+ }
+ }
+ return
+}
diff --git a/libgo/go/io/io_test.go b/libgo/go/io/io_test.go
index bc4f354..f1b23e9 100644
--- a/libgo/go/io/io_test.go
+++ b/libgo/go/io/io_test.go
@@ -19,7 +19,7 @@ type Buffer struct {
WriterTo // conflicts with and hides bytes.Buffer's WriterTo.
}
-// Simple tests, primarily to verify the ReadFrom and WriteTo callouts inside Copy and Copyn.
+// Simple tests, primarily to verify the ReadFrom and WriteTo callouts inside Copy and CopyN.
func TestCopy(t *testing.T) {
rb := new(Buffer)
@@ -51,33 +51,33 @@ func TestCopyWriteTo(t *testing.T) {
}
}
-func TestCopyn(t *testing.T) {
+func TestCopyN(t *testing.T) {
rb := new(Buffer)
wb := new(Buffer)
rb.WriteString("hello, world.")
- Copyn(wb, rb, 5)
+ CopyN(wb, rb, 5)
if wb.String() != "hello" {
- t.Errorf("Copyn did not work properly")
+ t.Errorf("CopyN did not work properly")
}
}
-func TestCopynReadFrom(t *testing.T) {
+func TestCopyNReadFrom(t *testing.T) {
rb := new(Buffer)
wb := new(bytes.Buffer) // implements ReadFrom.
rb.WriteString("hello")
- Copyn(wb, rb, 5)
+ CopyN(wb, rb, 5)
if wb.String() != "hello" {
- t.Errorf("Copyn did not work properly")
+ t.Errorf("CopyN did not work properly")
}
}
-func TestCopynWriteTo(t *testing.T) {
+func TestCopyNWriteTo(t *testing.T) {
rb := new(bytes.Buffer) // implements WriteTo.
wb := new(Buffer)
rb.WriteString("hello, world.")
- Copyn(wb, rb, 5)
+ CopyN(wb, rb, 5)
if wb.String() != "hello" {
- t.Errorf("Copyn did not work properly")
+ t.Errorf("CopyN did not work properly")
}
}
@@ -89,30 +89,30 @@ func (w *noReadFrom) Write(p []byte) (n int, err os.Error) {
return w.w.Write(p)
}
-func TestCopynEOF(t *testing.T) {
+func TestCopyNEOF(t *testing.T) {
// Test that EOF behavior is the same regardless of whether
- // argument to Copyn has ReadFrom.
+ // argument to CopyN has ReadFrom.
b := new(bytes.Buffer)
- n, err := Copyn(&noReadFrom{b}, strings.NewReader("foo"), 3)
+ n, err := CopyN(&noReadFrom{b}, strings.NewReader("foo"), 3)
if n != 3 || err != nil {
- t.Errorf("Copyn(noReadFrom, foo, 3) = %d, %v; want 3, nil", n, err)
+ t.Errorf("CopyN(noReadFrom, foo, 3) = %d, %v; want 3, nil", n, err)
}
- n, err = Copyn(&noReadFrom{b}, strings.NewReader("foo"), 4)
+ n, err = CopyN(&noReadFrom{b}, strings.NewReader("foo"), 4)
if n != 3 || err != os.EOF {
- t.Errorf("Copyn(noReadFrom, foo, 4) = %d, %v; want 3, EOF", n, err)
+ t.Errorf("CopyN(noReadFrom, foo, 4) = %d, %v; want 3, EOF", n, err)
}
- n, err = Copyn(b, strings.NewReader("foo"), 3) // b has read from
+ n, err = CopyN(b, strings.NewReader("foo"), 3) // b has read from
if n != 3 || err != nil {
- t.Errorf("Copyn(bytes.Buffer, foo, 3) = %d, %v; want 3, nil", n, err)
+ t.Errorf("CopyN(bytes.Buffer, foo, 3) = %d, %v; want 3, nil", n, err)
}
- n, err = Copyn(b, strings.NewReader("foo"), 4) // b has read from
+ n, err = CopyN(b, strings.NewReader("foo"), 4) // b has read from
if n != 3 || err != os.EOF {
- t.Errorf("Copyn(bytes.Buffer, foo, 4) = %d, %v; want 3, EOF", n, err)
+ t.Errorf("CopyN(bytes.Buffer, foo, 4) = %d, %v; want 3, EOF", n, err)
}
}
@@ -177,3 +177,30 @@ func testReadAtLeast(t *testing.T, rb ReadWriter) {
t.Errorf("expected to have read 1 bytes, got %v", n)
}
}
+
+func TestTeeReader(t *testing.T) {
+ src := []byte("hello, world")
+ dst := make([]byte, len(src))
+ rb := bytes.NewBuffer(src)
+ wb := new(bytes.Buffer)
+ r := TeeReader(rb, wb)
+ if n, err := ReadFull(r, dst); err != nil || n != len(src) {
+ t.Fatalf("ReadFull(r, dst) = %d, %v; want %d, nil", n, err, len(src))
+ }
+ if !bytes.Equal(dst, src) {
+ t.Errorf("bytes read = %q want %q", dst, src)
+ }
+ if !bytes.Equal(wb.Bytes(), src) {
+ t.Errorf("bytes written = %q want %q", wb.Bytes(), src)
+ }
+ if n, err := r.Read(dst); n != 0 || err != os.EOF {
+ t.Errorf("r.Read at EOF = %d, %v want 0, EOF", n, err)
+ }
+ rb = bytes.NewBuffer(src)
+ pr, pw := Pipe()
+ pr.Close()
+ r = TeeReader(rb, pw)
+ if n, err := ReadFull(r, dst); n != 0 || err != os.EPIPE {
+ t.Errorf("closed tee: ReadFull(r, dst) = %d, %v; want 0, EPIPE", n, err)
+ }
+}
diff --git a/libgo/go/io/ioutil/ioutil.go b/libgo/go/io/ioutil/ioutil.go
index fffa132..dd50d96 100644
--- a/libgo/go/io/ioutil/ioutil.go
+++ b/libgo/go/io/ioutil/ioutil.go
@@ -104,6 +104,10 @@ func NopCloser(r io.Reader) io.ReadCloser {
type devNull int
+// devNull implements ReaderFrom as an optimization so io.Copy to
+// ioutil.Discard can avoid doing unnecessary work.
+var _ io.ReaderFrom = devNull(0)
+
func (devNull) Write(p []byte) (int, os.Error) {
return len(p), nil
}