aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/io
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2016-02-03 21:58:02 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2016-02-03 21:58:02 +0000
commitf98dd1a338867a408f7c72d73fbad7fe7fc93e3a (patch)
tree2f8da9862a9c1fe0df138917f997b03439c02773 /libgo/go/io
parentb081ed4efc144da0c45a6484aebfd10e0eb9fda3 (diff)
downloadgcc-f98dd1a338867a408f7c72d73fbad7fe7fc93e3a.zip
gcc-f98dd1a338867a408f7c72d73fbad7fe7fc93e3a.tar.gz
gcc-f98dd1a338867a408f7c72d73fbad7fe7fc93e3a.tar.bz2
libgo: Update to go1.6rc1.
Reviewed-on: https://go-review.googlesource.com/19200 From-SVN: r233110
Diffstat (limited to 'libgo/go/io')
-rw-r--r--libgo/go/io/example_test.go223
-rw-r--r--libgo/go/io/io.go13
-rw-r--r--libgo/go/io/ioutil/example_test.go73
-rw-r--r--libgo/go/io/ioutil/ioutil.go2
-rw-r--r--libgo/go/io/multi.go24
-rw-r--r--libgo/go/io/multi_test.go54
6 files changed, 380 insertions, 9 deletions
diff --git a/libgo/go/io/example_test.go b/libgo/go/io/example_test.go
new file mode 100644
index 0000000..412dfb3
--- /dev/null
+++ b/libgo/go/io/example_test.go
@@ -0,0 +1,223 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package io_test
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "log"
+ "os"
+ "strings"
+)
+
+func ExampleCopy() {
+ r := strings.NewReader("some io.Reader stream to be read\n")
+
+ if _, err := io.Copy(os.Stdout, r); err != nil {
+ log.Fatal(err)
+ }
+
+ // Output:
+ // some io.Reader stream to be read
+}
+
+func ExampleCopyBuffer() {
+ r1 := strings.NewReader("first reader\n")
+ r2 := strings.NewReader("second reader\n")
+ buf := make([]byte, 8)
+
+ // buf is used here...
+ if _, err := io.CopyBuffer(os.Stdout, r1, buf); err != nil {
+ log.Fatal(err)
+ }
+
+ // ... reused here also. No need to allocate an extra buffer.
+ if _, err := io.CopyBuffer(os.Stdout, r2, buf); err != nil {
+ log.Fatal(err)
+ }
+
+ // Output:
+ // first reader
+ // second reader
+}
+
+func ExampleCopyN() {
+ r := strings.NewReader("some io.Reader stream to be read")
+
+ if _, err := io.CopyN(os.Stdout, r, 5); err != nil {
+ log.Fatal(err)
+ }
+
+ // Output:
+ // some
+}
+
+func ExampleReadAtLeast() {
+ r := strings.NewReader("some io.Reader stream to be read\n")
+
+ buf := make([]byte, 33)
+ if _, err := io.ReadAtLeast(r, buf, 4); err != nil {
+ log.Fatal(err)
+ }
+ fmt.Printf("%s\n", buf)
+
+ // buffer smaller than minimal read size.
+ shortBuf := make([]byte, 3)
+ if _, err := io.ReadAtLeast(r, shortBuf, 4); err != nil {
+ fmt.Println("error:", err)
+ }
+
+ // minimal read size bigger than io.Reader stream
+ longBuf := make([]byte, 64)
+ if _, err := io.ReadAtLeast(r, longBuf, 64); err != nil {
+ fmt.Println("error:", err)
+ }
+
+ // Output:
+ // some io.Reader stream to be read
+ //
+ // error: short buffer
+ // error: EOF
+}
+
+func ExampleReadFull() {
+ r := strings.NewReader("some io.Reader stream to be read\n")
+
+ buf := make([]byte, 4)
+ if _, err := io.ReadFull(r, buf); err != nil {
+ log.Fatal(err)
+ }
+ fmt.Printf("%s\n", buf)
+
+ // minimal read size bigger than io.Reader stream
+ longBuf := make([]byte, 64)
+ if _, err := io.ReadFull(r, longBuf); err != nil {
+ fmt.Println("error:", err)
+ }
+
+ // Output:
+ // some
+ // error: unexpected EOF
+}
+
+func ExampleWriteString() {
+ io.WriteString(os.Stdout, "Hello World")
+
+ // Output: Hello World
+}
+
+func ExampleLimitReader() {
+ r := strings.NewReader("some io.Reader stream to be read\n")
+ lr := io.LimitReader(r, 4)
+
+ if _, err := io.Copy(os.Stdout, lr); err != nil {
+ log.Fatal(err)
+ }
+
+ // Output:
+ // some
+}
+
+func ExampleMultiReader() {
+ r1 := strings.NewReader("first reader ")
+ r2 := strings.NewReader("second reader ")
+ r3 := strings.NewReader("third reader\n")
+ r := io.MultiReader(r1, r2, r3)
+
+ if _, err := io.Copy(os.Stdout, r); err != nil {
+ log.Fatal(err)
+ }
+
+ // Output:
+ // first reader second reader third reader
+}
+
+func ExampleTeeReader() {
+ r := strings.NewReader("some io.Reader stream to be read\n")
+ var buf bytes.Buffer
+ tee := io.TeeReader(r, &buf)
+
+ printall := func(r io.Reader) {
+ b, err := ioutil.ReadAll(r)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ fmt.Printf("%s", b)
+ }
+
+ printall(tee)
+ printall(&buf)
+
+ // Output:
+ // some io.Reader stream to be read
+ // some io.Reader stream to be read
+}
+
+func ExampleSectionReader() {
+ r := strings.NewReader("some io.Reader stream to be read\n")
+ s := io.NewSectionReader(r, 5, 17)
+
+ if _, err := io.Copy(os.Stdout, s); err != nil {
+ log.Fatal(err)
+ }
+
+ // Output:
+ // io.Reader stream
+}
+
+func ExampleSectionReader_ReadAt() {
+ r := strings.NewReader("some io.Reader stream to be read\n")
+ s := io.NewSectionReader(r, 5, 16)
+
+ buf := make([]byte, 6)
+ if _, err := s.ReadAt(buf, 10); err != nil {
+ log.Fatal(err)
+ }
+
+ fmt.Printf("%s\n", buf)
+
+ // Output:
+ // stream
+}
+
+func ExampleSectionReader_Seek() {
+ r := strings.NewReader("some io.Reader stream to be read\n")
+ s := io.NewSectionReader(r, 5, 16)
+
+ if _, err := s.Seek(10, 0); err != nil {
+ log.Fatal(err)
+ }
+
+ buf := make([]byte, 6)
+ if _, err := s.Read(buf); err != nil {
+ log.Fatal(err)
+ }
+
+ fmt.Printf("%s\n", buf)
+
+ // Output:
+ // stream
+}
+
+func ExampleMultiWriter() {
+ r := strings.NewReader("some io.Reader stream to be read\n")
+
+ var buf1, buf2 bytes.Buffer
+ w := io.MultiWriter(&buf1, &buf2)
+
+ if _, err := io.Copy(w, r); err != nil {
+ log.Fatal(err)
+ }
+
+ fmt.Print(buf1.String())
+ fmt.Print(buf2.String())
+
+ // Output:
+ // some io.Reader stream to be read
+ // some io.Reader stream to be read
+}
diff --git a/libgo/go/io/io.go b/libgo/go/io/io.go
index 8851eaf..8e7855c 100644
--- a/libgo/go/io/io.go
+++ b/libgo/go/io/io.go
@@ -95,14 +95,14 @@ type Closer interface {
// Seeker is the interface that wraps the basic Seek method.
//
// Seek sets the offset for the next Read or Write to offset,
-// interpreted according to whence: 0 means relative to the origin of
+// interpreted according to whence: 0 means relative to the start of
// the file, 1 means relative to the current offset, and 2 means
-// relative to the end. Seek returns the new offset and an error, if
-// any.
+// relative to the end. Seek returns the new offset relative to the
+// start of the file and an error, if any.
//
-// Seeking to a negative offset is an error. Seeking to any positive
-// offset is legal, but the behavior of subsequent I/O operations on
-// the underlying object is implementation-dependent.
+// Seeking to an offset before the start of the file is an error.
+// Seeking to any positive offset is legal, but the behavior of subsequent
+// I/O operations on the underlying object is implementation-dependent.
type Seeker interface {
Seek(offset int64, whence int) (int64, error)
}
@@ -225,7 +225,6 @@ type WriterAt interface {
// ByteReader is the interface that wraps the ReadByte method.
//
// ReadByte reads and returns the next byte from the input.
-// If no byte is available, err will be set.
type ByteReader interface {
ReadByte() (c byte, err error)
}
diff --git a/libgo/go/io/ioutil/example_test.go b/libgo/go/io/ioutil/example_test.go
new file mode 100644
index 0000000..74a7791
--- /dev/null
+++ b/libgo/go/io/ioutil/example_test.go
@@ -0,0 +1,73 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+package ioutil_test
+
+import (
+ "fmt"
+ "io/ioutil"
+ "log"
+ "os"
+ "path/filepath"
+ "strings"
+)
+
+func ExampleReadAll() {
+ r := strings.NewReader("Go is a general-purpose language designed with systems programming in mind.")
+
+ b, err := ioutil.ReadAll(r)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ fmt.Printf("%s", b)
+
+ // Output:
+ // Go is a general-purpose language designed with systems programming in mind.
+}
+
+func ExampleReadDir() {
+ files, err := ioutil.ReadDir(".")
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ for _, file := range files {
+ fmt.Println(file.Name())
+ }
+}
+
+func ExampleTempDir() {
+ content := []byte("temporary file's content")
+ dir, err := ioutil.TempDir("", "example")
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ defer os.RemoveAll(dir) // clean up
+
+ tmpfn := filepath.Join(dir, "tmpfile")
+ if err := ioutil.WriteFile(tmpfn, content, 0666); err != nil {
+ log.Fatal(err)
+ }
+}
+
+func ExampleTempFile() {
+ content := []byte("temporary file's content")
+ tmpfile, err := ioutil.TempFile("", "example")
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ defer os.Remove(tmpfile.Name()) // clean up
+
+ if _, err := tmpfile.Write(content); err != nil {
+ log.Fatal(err)
+ }
+ if err := tmpfile.Close(); err != nil {
+ log.Fatal(err)
+ }
+}
diff --git a/libgo/go/io/ioutil/ioutil.go b/libgo/go/io/ioutil/ioutil.go
index 909a815..e90a33f 100644
--- a/libgo/go/io/ioutil/ioutil.go
+++ b/libgo/go/io/ioutil/ioutil.go
@@ -96,7 +96,7 @@ func (f byName) Less(i, j int) bool { return f[i].Name() < f[j].Name() }
func (f byName) Swap(i, j int) { f[i], f[j] = f[j], f[i] }
// ReadDir reads the directory named by dirname and returns
-// a list of sorted directory entries.
+// a list of directory entries sorted by filename.
func ReadDir(dirname string) ([]os.FileInfo, error) {
f, err := os.Open(dirname)
if err != nil {
diff --git a/libgo/go/io/multi.go b/libgo/go/io/multi.go
index e26cc53..16860aa 100644
--- a/libgo/go/io/multi.go
+++ b/libgo/go/io/multi.go
@@ -52,6 +52,30 @@ func (t *multiWriter) Write(p []byte) (n int, err error) {
return len(p), nil
}
+var _ stringWriter = (*multiWriter)(nil)
+
+func (t *multiWriter) WriteString(s string) (n int, err error) {
+ var p []byte // lazily initialized if/when needed
+ for _, w := range t.writers {
+ if sw, ok := w.(stringWriter); ok {
+ n, err = sw.WriteString(s)
+ } else {
+ if p == nil {
+ p = []byte(s)
+ }
+ n, err = w.Write(p)
+ }
+ if err != nil {
+ return
+ }
+ if n != len(s) {
+ err = ErrShortWrite
+ return
+ }
+ }
+ return len(s), nil
+}
+
// MultiWriter creates a writer that duplicates its writes to all the
// provided writers, similar to the Unix tee(1) command.
func MultiWriter(writers ...Writer) Writer {
diff --git a/libgo/go/io/multi_test.go b/libgo/go/io/multi_test.go
index 56c6769..c5d1b95 100644
--- a/libgo/go/io/multi_test.go
+++ b/libgo/go/io/multi_test.go
@@ -62,8 +62,60 @@ func TestMultiReader(t *testing.T) {
}
func TestMultiWriter(t *testing.T) {
- sha1 := sha1.New()
sink := new(bytes.Buffer)
+ // Hide bytes.Buffer's WriteString method:
+ testMultiWriter(t, struct {
+ Writer
+ fmt.Stringer
+ }{sink, sink})
+}
+
+func TestMultiWriter_String(t *testing.T) {
+ testMultiWriter(t, new(bytes.Buffer))
+}
+
+// test that a multiWriter.WriteString calls results in at most 1 allocation,
+// even if multiple targets don't support WriteString.
+func TestMultiWriter_WriteStringSingleAlloc(t *testing.T) {
+ t.Skip("skipping on gccgo until we have escape analysis")
+ var sink1, sink2 bytes.Buffer
+ type simpleWriter struct { // hide bytes.Buffer's WriteString
+ Writer
+ }
+ mw := MultiWriter(simpleWriter{&sink1}, simpleWriter{&sink2})
+ allocs := int(testing.AllocsPerRun(1000, func() {
+ WriteString(mw, "foo")
+ }))
+ if allocs != 1 {
+ t.Errorf("num allocations = %d; want 1", allocs)
+ }
+}
+
+type writeStringChecker struct{ called bool }
+
+func (c *writeStringChecker) WriteString(s string) (n int, err error) {
+ c.called = true
+ return len(s), nil
+}
+
+func (c *writeStringChecker) Write(p []byte) (n int, err error) {
+ return len(p), nil
+}
+
+func TestMultiWriter_StringCheckCall(t *testing.T) {
+ var c writeStringChecker
+ mw := MultiWriter(&c)
+ WriteString(mw, "foo")
+ if !c.called {
+ t.Error("did not see WriteString call to writeStringChecker")
+ }
+}
+
+func testMultiWriter(t *testing.T, sink interface {
+ Writer
+ fmt.Stringer
+}) {
+ sha1 := sha1.New()
mw := MultiWriter(sha1, sink)
sourceString := "My input text."