aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/io
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2015-10-31 00:59:47 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2015-10-31 00:59:47 +0000
commitaf146490bb04205107cb23e301ec7a8ff927b5fc (patch)
tree13beeaed3698c61903fe93fb1ce70bd9b18d4e7f /libgo/go/io
parent725e1be3406315d9bcc8195d7eef0a7082b3c7cc (diff)
downloadgcc-af146490bb04205107cb23e301ec7a8ff927b5fc.zip
gcc-af146490bb04205107cb23e301ec7a8ff927b5fc.tar.gz
gcc-af146490bb04205107cb23e301ec7a8ff927b5fc.tar.bz2
runtime: Remove now unnecessary pad field from ParFor.
It is not needed due to the removal of the ctx field. Reviewed-on: https://go-review.googlesource.com/16525 From-SVN: r229616
Diffstat (limited to 'libgo/go/io')
-rw-r--r--libgo/go/io/io.go27
-rw-r--r--libgo/go/io/io_test.go50
-rw-r--r--libgo/go/io/ioutil/tempfile.go4
-rw-r--r--libgo/go/io/pipe.go5
4 files changed, 80 insertions, 6 deletions
diff --git a/libgo/go/io/io.go b/libgo/go/io/io.go
index 7507a84..8851eaf 100644
--- a/libgo/go/io/io.go
+++ b/libgo/go/io/io.go
@@ -54,7 +54,7 @@ var ErrNoProgress = errors.New("multiple Read calls return no data or error")
// An instance of this general case is that a Reader returning
// a non-zero number of bytes at the end of the input stream may
// return either err == EOF or err == nil. The next Read should
-// return 0, EOF regardless.
+// return 0, EOF.
//
// Callers should always process the n > 0 bytes returned before
// considering the error err. Doing so correctly handles I/O errors
@@ -273,8 +273,8 @@ type stringWriter interface {
WriteString(s string) (n int, err error)
}
-// WriteString writes the contents of the string s to w, which accepts an array of bytes.
-// If w already implements a WriteString method, it is invoked directly.
+// WriteString writes the contents of the string s to w, which accepts a slice of bytes.
+// If w implements a WriteString method, it is invoked directly.
func WriteString(w Writer, s string) (n int, err error) {
if sw, ok := w.(stringWriter); ok {
return sw.WriteString(s)
@@ -348,6 +348,23 @@ func CopyN(dst Writer, src Reader, n int64) (written int64, err error) {
// Otherwise, if dst implements the ReaderFrom interface,
// the copy is implemented by calling dst.ReadFrom(src).
func Copy(dst Writer, src Reader) (written int64, err error) {
+ return copyBuffer(dst, src, nil)
+}
+
+// CopyBuffer is identical to Copy except that it stages through the
+// provided buffer (if one is required) rather than allocating a
+// temporary one. If buf is nil, one is allocated; otherwise if it has
+// zero length, CopyBuffer panics.
+func CopyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error) {
+ if buf != nil && len(buf) == 0 {
+ panic("empty buffer in io.CopyBuffer")
+ }
+ return copyBuffer(dst, src, buf)
+}
+
+// copyBuffer is the actual implementation of Copy and CopyBuffer.
+// if buf is nil, one is allocated.
+func copyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error) {
// If the reader has a WriteTo method, use it to do the copy.
// Avoids an allocation and a copy.
if wt, ok := src.(WriterTo); ok {
@@ -357,7 +374,9 @@ func Copy(dst Writer, src Reader) (written int64, err error) {
if rt, ok := dst.(ReaderFrom); ok {
return rt.ReadFrom(src)
}
- buf := make([]byte, 32*1024)
+ if buf == nil {
+ buf = make([]byte, 32*1024)
+ }
for {
nr, er := src.Read(buf)
if nr > 0 {
diff --git a/libgo/go/io/io_test.go b/libgo/go/io/io_test.go
index 57db1fb..e892574 100644
--- a/libgo/go/io/io_test.go
+++ b/libgo/go/io/io_test.go
@@ -20,7 +20,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, CopyBuffer and CopyN.
func TestCopy(t *testing.T) {
rb := new(Buffer)
@@ -32,6 +32,26 @@ func TestCopy(t *testing.T) {
}
}
+func TestCopyBuffer(t *testing.T) {
+ rb := new(Buffer)
+ wb := new(Buffer)
+ rb.WriteString("hello, world.")
+ CopyBuffer(wb, rb, make([]byte, 1)) // Tiny buffer to keep it honest.
+ if wb.String() != "hello, world." {
+ t.Errorf("CopyBuffer did not work properly")
+ }
+}
+
+func TestCopyBufferNil(t *testing.T) {
+ rb := new(Buffer)
+ wb := new(Buffer)
+ rb.WriteString("hello, world.")
+ CopyBuffer(wb, rb, nil) // Should allocate a buffer.
+ if wb.String() != "hello, world." {
+ t.Errorf("CopyBuffer did not work properly")
+ }
+}
+
func TestCopyReadFrom(t *testing.T) {
rb := new(Buffer)
wb := new(bytes.Buffer) // implements ReadFrom.
@@ -78,6 +98,34 @@ func TestCopyPriority(t *testing.T) {
}
}
+type zeroErrReader struct {
+ err error
+}
+
+func (r zeroErrReader) Read(p []byte) (int, error) {
+ return copy(p, []byte{0}), r.err
+}
+
+type errWriter struct {
+ err error
+}
+
+func (w errWriter) Write([]byte) (int, error) {
+ return 0, w.err
+}
+
+// In case a Read results in an error with non-zero bytes read, and
+// the subsequent Write also results in an error, the error from Write
+// is returned, as it is the one that prevented progressing further.
+func TestCopyReadErrWriteErr(t *testing.T) {
+ er, ew := errors.New("readError"), errors.New("writeError")
+ r, w := zeroErrReader{err: er}, errWriter{err: ew}
+ n, err := Copy(w, r)
+ if n != 0 || err != ew {
+ t.Errorf("Copy(zeroErrReader, errWriter) = %d, %v; want 0, writeError", n, err)
+ }
+}
+
func TestCopyN(t *testing.T) {
rb := new(Buffer)
wb := new(Buffer)
diff --git a/libgo/go/io/ioutil/tempfile.go b/libgo/go/io/ioutil/tempfile.go
index 4a06e97..61d4a7a 100644
--- a/libgo/go/io/ioutil/tempfile.go
+++ b/libgo/go/io/ioutil/tempfile.go
@@ -55,7 +55,9 @@ func TempFile(dir, prefix string) (f *os.File, err error) {
f, err = os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
if os.IsExist(err) {
if nconflict++; nconflict > 10 {
+ randmu.Lock()
rand = reseed()
+ randmu.Unlock()
}
continue
}
@@ -82,7 +84,9 @@ func TempDir(dir, prefix string) (name string, err error) {
err = os.Mkdir(try, 0700)
if os.IsExist(err) {
if nconflict++; nconflict > 10 {
+ randmu.Lock()
rand = reseed()
+ randmu.Unlock()
}
continue
}
diff --git a/libgo/go/io/pipe.go b/libgo/go/io/pipe.go
index f65354a..179515e 100644
--- a/libgo/go/io/pipe.go
+++ b/libgo/go/io/pipe.go
@@ -168,7 +168,10 @@ func (w *PipeWriter) Close() error {
}
// CloseWithError closes the writer; subsequent reads from the
-// read half of the pipe will return no bytes and the error err.
+// read half of the pipe will return no bytes and the error err,
+// or EOF if err is nil.
+//
+// CloseWithError always returns nil.
func (w *PipeWriter) CloseWithError(err error) error {
w.p.wclose(err)
return nil