summaryrefslogtreecommitdiff
path: root/src/pkg/io
diff options
context:
space:
mode:
authorTianon Gravi <admwiggin@gmail.com>2015-01-15 11:54:00 -0700
committerTianon Gravi <admwiggin@gmail.com>2015-01-15 11:54:00 -0700
commitf154da9e12608589e8d5f0508f908a0c3e88a1bb (patch)
treef8255d51e10c6f1e0ed69702200b966c9556a431 /src/pkg/io
parent8d8329ed5dfb9622c82a9fbec6fd99a580f9c9f6 (diff)
downloadgolang-upstream/1.4.tar.gz
Imported Upstream version 1.4upstream/1.4
Diffstat (limited to 'src/pkg/io')
-rw-r--r--src/pkg/io/io.go493
-rw-r--r--src/pkg/io/io_test.go341
-rw-r--r--src/pkg/io/ioutil/ioutil.go165
-rw-r--r--src/pkg/io/ioutil/ioutil_test.go95
-rw-r--r--src/pkg/io/ioutil/tempfile.go95
-rw-r--r--src/pkg/io/ioutil/tempfile_test.go53
-rw-r--r--src/pkg/io/multi.go61
-rw-r--r--src/pkg/io/multi_test.go115
-rw-r--r--src/pkg/io/pipe.go193
-rw-r--r--src/pkg/io/pipe_test.go302
10 files changed, 0 insertions, 1913 deletions
diff --git a/src/pkg/io/io.go b/src/pkg/io/io.go
deleted file mode 100644
index 022fdb676..000000000
--- a/src/pkg/io/io.go
+++ /dev/null
@@ -1,493 +0,0 @@
-// Copyright 2009 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 provides basic interfaces to I/O primitives.
-// Its primary job is to wrap existing implementations of such primitives,
-// such as those in package os, into shared public interfaces that
-// abstract the functionality, plus some other related primitives.
-//
-// Because these interfaces and primitives wrap lower-level operations with
-// various implementations, unless otherwise informed clients should not
-// assume they are safe for parallel execution.
-package io
-
-import (
- "errors"
-)
-
-// ErrShortWrite means that a write accepted fewer bytes than requested
-// but failed to return an explicit error.
-var ErrShortWrite = errors.New("short write")
-
-// ErrShortBuffer means that a read required a longer buffer than was provided.
-var ErrShortBuffer = errors.New("short buffer")
-
-// EOF is the error returned by Read when no more input is available.
-// Functions should return EOF only to signal a graceful end of input.
-// If the EOF occurs unexpectedly in a structured data stream,
-// the appropriate error is either ErrUnexpectedEOF or some other error
-// giving more detail.
-var EOF = errors.New("EOF")
-
-// ErrUnexpectedEOF means that EOF was encountered in the
-// middle of reading a fixed-size block or data structure.
-var ErrUnexpectedEOF = errors.New("unexpected EOF")
-
-// ErrNoProgress is returned by some clients of an io.Reader when
-// many calls to Read have failed to return any data or error,
-// usually the sign of a broken io.Reader implementation.
-var ErrNoProgress = errors.New("multiple Read calls return no data or error")
-
-// Reader is the interface that wraps the basic Read method.
-//
-// Read reads up to len(p) bytes into p. It returns the number of bytes
-// read (0 <= n <= len(p)) and any error encountered. Even if Read
-// returns n < len(p), it may use all of p as scratch space during the call.
-// If some data is available but not len(p) bytes, Read conventionally
-// returns what is available instead of waiting for more.
-//
-// When Read encounters an error or end-of-file condition after
-// successfully reading n > 0 bytes, it returns the number of
-// bytes read. It may return the (non-nil) error from the same call
-// or return the error (and n == 0) from a subsequent call.
-// 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.
-//
-// Callers should always process the n > 0 bytes returned before
-// considering the error err. Doing so correctly handles I/O errors
-// that happen after reading some bytes and also both of the
-// allowed EOF behaviors.
-//
-// Implementations of Read are discouraged from returning a
-// zero byte count with a nil error, and callers should treat
-// that situation as a no-op.
-type Reader interface {
- Read(p []byte) (n int, err error)
-}
-
-// Writer is the interface that wraps the basic Write method.
-//
-// Write writes len(p) bytes from p to the underlying data stream.
-// It returns the number of bytes written from p (0 <= n <= len(p))
-// and any error encountered that caused the write to stop early.
-// Write must return a non-nil error if it returns n < len(p).
-// Write must not modify the slice data, even temporarily.
-type Writer interface {
- Write(p []byte) (n int, err error)
-}
-
-// Closer is the interface that wraps the basic Close method.
-//
-// The behavior of Close after the first call is undefined.
-// Specific implementations may document their own behavior.
-type Closer interface {
- Close() error
-}
-
-// 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
-// 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.
-//
-// 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.
-type Seeker interface {
- Seek(offset int64, whence int) (int64, error)
-}
-
-// ReadWriter is the interface that groups the basic Read and Write methods.
-type ReadWriter interface {
- Reader
- Writer
-}
-
-// ReadCloser is the interface that groups the basic Read and Close methods.
-type ReadCloser interface {
- Reader
- Closer
-}
-
-// WriteCloser is the interface that groups the basic Write and Close methods.
-type WriteCloser interface {
- Writer
- Closer
-}
-
-// ReadWriteCloser is the interface that groups the basic Read, Write and Close methods.
-type ReadWriteCloser interface {
- Reader
- Writer
- Closer
-}
-
-// ReadSeeker is the interface that groups the basic Read and Seek methods.
-type ReadSeeker interface {
- Reader
- Seeker
-}
-
-// WriteSeeker is the interface that groups the basic Write and Seek methods.
-type WriteSeeker interface {
- Writer
- Seeker
-}
-
-// ReadWriteSeeker is the interface that groups the basic Read, Write and Seek methods.
-type ReadWriteSeeker interface {
- Reader
- Writer
- Seeker
-}
-
-// ReaderFrom is the interface that wraps the ReadFrom method.
-//
-// ReadFrom reads data from r until EOF or error.
-// The return value n is the number of bytes read.
-// Any error except io.EOF encountered during the read is also returned.
-//
-// The Copy function uses ReaderFrom if available.
-type ReaderFrom interface {
- ReadFrom(r Reader) (n int64, err error)
-}
-
-// WriterTo is the interface that wraps the WriteTo method.
-//
-// WriteTo writes data to w until there's no more data to write or
-// when an error occurs. The return value n is the number of bytes
-// written. Any error encountered during the write is also returned.
-//
-// The Copy function uses WriterTo if available.
-type WriterTo interface {
- WriteTo(w Writer) (n int64, err error)
-}
-
-// ReaderAt is the interface that wraps the basic ReadAt method.
-//
-// ReadAt reads len(p) bytes into p starting at offset off in the
-// underlying input source. It returns the number of bytes
-// read (0 <= n <= len(p)) and any error encountered.
-//
-// When ReadAt returns n < len(p), it returns a non-nil error
-// explaining why more bytes were not returned. In this respect,
-// ReadAt is stricter than Read.
-//
-// Even if ReadAt returns n < len(p), it may use all of p as scratch
-// space during the call. If some data is available but not len(p) bytes,
-// ReadAt blocks until either all the data is available or an error occurs.
-// In this respect ReadAt is different from Read.
-//
-// If the n = len(p) bytes returned by ReadAt are at the end of the
-// input source, ReadAt may return either err == EOF or err == nil.
-//
-// If ReadAt is reading from an input source with a seek offset,
-// ReadAt should not affect nor be affected by the underlying
-// seek offset.
-//
-// Clients of ReadAt can execute parallel ReadAt calls on the
-// same input source.
-type ReaderAt interface {
- ReadAt(p []byte, off int64) (n int, err error)
-}
-
-// WriterAt is the interface that wraps the basic WriteAt method.
-//
-// WriteAt writes len(p) bytes from p to the underlying data stream
-// at offset off. It returns the number of bytes written from p (0 <= n <= len(p))
-// and any error encountered that caused the write to stop early.
-// WriteAt must return a non-nil error if it returns n < len(p).
-//
-// If WriteAt is writing to a destination with a seek offset,
-// WriteAt should not affect nor be affected by the underlying
-// seek offset.
-//
-// Clients of WriteAt can execute parallel WriteAt calls on the same
-// destination if the ranges do not overlap.
-type WriterAt interface {
- WriteAt(p []byte, off int64) (n int, err error)
-}
-
-// 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)
-}
-
-// ByteScanner is the interface that adds the UnreadByte method to the
-// basic ReadByte method.
-//
-// UnreadByte causes the next call to ReadByte to return the same byte
-// as the previous call to ReadByte.
-// It may be an error to call UnreadByte twice without an intervening
-// call to ReadByte.
-type ByteScanner interface {
- ByteReader
- UnreadByte() error
-}
-
-// ByteWriter is the interface that wraps the WriteByte method.
-type ByteWriter interface {
- WriteByte(c byte) error
-}
-
-// RuneReader is the interface that wraps the ReadRune method.
-//
-// ReadRune reads a single UTF-8 encoded Unicode character
-// and returns the rune and its size in bytes. If no character is
-// available, err will be set.
-type RuneReader interface {
- ReadRune() (r rune, size int, err error)
-}
-
-// RuneScanner is the interface that adds the UnreadRune method to the
-// basic ReadRune method.
-//
-// UnreadRune causes the next call to ReadRune to return the same rune
-// as the previous call to ReadRune.
-// It may be an error to call UnreadRune twice without an intervening
-// call to ReadRune.
-type RuneScanner interface {
- RuneReader
- UnreadRune() error
-}
-
-// stringWriter is the interface that wraps the WriteString method.
-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.
-func WriteString(w Writer, s string) (n int, err error) {
- if sw, ok := w.(stringWriter); ok {
- return sw.WriteString(s)
- }
- return w.Write([]byte(s))
-}
-
-// ReadAtLeast reads from r into buf until it has read at least min bytes.
-// It returns the number of bytes copied and an error if fewer bytes were read.
-// The error is EOF only if no bytes were read.
-// If an EOF happens after reading fewer than min bytes,
-// ReadAtLeast returns ErrUnexpectedEOF.
-// If min is greater than the length of buf, ReadAtLeast returns ErrShortBuffer.
-// On return, n >= min if and only if err == nil.
-func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error) {
- if len(buf) < min {
- return 0, ErrShortBuffer
- }
- for n < min && err == nil {
- var nn int
- nn, err = r.Read(buf[n:])
- n += nn
- }
- if n >= min {
- err = nil
- } else if n > 0 && err == EOF {
- err = ErrUnexpectedEOF
- }
- return
-}
-
-// ReadFull reads exactly len(buf) bytes from r into buf.
-// It returns the number of bytes copied and an error if fewer bytes were read.
-// The error is EOF only if no bytes were read.
-// If an EOF happens after reading some but not all the bytes,
-// ReadFull returns ErrUnexpectedEOF.
-// On return, n == len(buf) if and only if err == nil.
-func ReadFull(r Reader, buf []byte) (n int, err error) {
- return ReadAtLeast(r, buf, len(buf))
-}
-
-// 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.
-// On return, written == n if and only if err == nil.
-//
-// If dst implements the ReaderFrom interface,
-// the copy is implemented using it.
-func CopyN(dst Writer, src Reader, n int64) (written int64, err error) {
- written, err = Copy(dst, LimitReader(src, n))
- if written == n {
- return n, nil
- }
- if written < n && err == nil {
- // src stopped early; must have been EOF.
- err = EOF
- }
- return
-}
-
-// Copy copies from src to dst until either EOF is reached
-// on src or an error occurs. It returns the number of bytes
-// copied and the first error encountered while copying, if any.
-//
-// A successful Copy returns err == nil, not err == EOF.
-// Because Copy is defined to read from src until EOF, it does
-// not treat an EOF from Read as an error to be reported.
-//
-// If src implements the WriterTo interface,
-// the copy is implemented by calling src.WriteTo(dst).
-// 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) {
- // 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 {
- return wt.WriteTo(dst)
- }
- // Similarly, if the writer has a ReadFrom method, use it to do the copy.
- if rt, ok := dst.(ReaderFrom); ok {
- return rt.ReadFrom(src)
- }
- buf := make([]byte, 32*1024)
- for {
- nr, er := src.Read(buf)
- if nr > 0 {
- nw, ew := dst.Write(buf[0:nr])
- if nw > 0 {
- written += int64(nw)
- }
- if ew != nil {
- err = ew
- break
- }
- if nr != nw {
- err = ErrShortWrite
- break
- }
- }
- if er == EOF {
- break
- }
- if er != nil {
- err = er
- break
- }
- }
- return written, err
-}
-
-// LimitReader returns a Reader that reads from r
-// but stops with EOF after n bytes.
-// The underlying implementation is a *LimitedReader.
-func LimitReader(r Reader, n int64) Reader { return &LimitedReader{r, n} }
-
-// A LimitedReader reads from R but limits the amount of
-// data returned to just N bytes. Each call to Read
-// updates N to reflect the new amount remaining.
-type LimitedReader struct {
- R Reader // underlying reader
- N int64 // max bytes remaining
-}
-
-func (l *LimitedReader) Read(p []byte) (n int, err error) {
- if l.N <= 0 {
- return 0, EOF
- }
- if int64(len(p)) > l.N {
- p = p[0:l.N]
- }
- n, err = l.R.Read(p)
- l.N -= int64(n)
- return
-}
-
-// NewSectionReader returns a SectionReader that reads from r
-// starting at offset off and stops with EOF after n bytes.
-func NewSectionReader(r ReaderAt, off int64, n int64) *SectionReader {
- return &SectionReader{r, off, off, off + n}
-}
-
-// SectionReader implements Read, Seek, and ReadAt on a section
-// of an underlying ReaderAt.
-type SectionReader struct {
- r ReaderAt
- base int64
- off int64
- limit int64
-}
-
-func (s *SectionReader) Read(p []byte) (n int, err error) {
- if s.off >= s.limit {
- return 0, EOF
- }
- if max := s.limit - s.off; int64(len(p)) > max {
- p = p[0:max]
- }
- n, err = s.r.ReadAt(p, s.off)
- s.off += int64(n)
- return
-}
-
-var errWhence = errors.New("Seek: invalid whence")
-var errOffset = errors.New("Seek: invalid offset")
-
-func (s *SectionReader) Seek(offset int64, whence int) (int64, error) {
- switch whence {
- default:
- return 0, errWhence
- case 0:
- offset += s.base
- case 1:
- offset += s.off
- case 2:
- offset += s.limit
- }
- if offset < s.base {
- return 0, errOffset
- }
- s.off = offset
- return offset - s.base, nil
-}
-
-func (s *SectionReader) ReadAt(p []byte, off int64) (n int, err error) {
- if off < 0 || off >= s.limit-s.base {
- return 0, EOF
- }
- off += s.base
- if max := s.limit - off; int64(len(p)) > max {
- p = p[0:max]
- n, err = s.r.ReadAt(p, off)
- if err == nil {
- err = EOF
- }
- return n, err
- }
- return s.r.ReadAt(p, off)
-}
-
-// 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 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/src/pkg/io/io_test.go b/src/pkg/io/io_test.go
deleted file mode 100644
index 57db1fbf0..000000000
--- a/src/pkg/io/io_test.go
+++ /dev/null
@@ -1,341 +0,0 @@
-// Copyright 2009 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"
- "errors"
- "fmt"
- . "io"
- "strings"
- "testing"
-)
-
-// An version of bytes.Buffer without ReadFrom and WriteTo
-type Buffer struct {
- bytes.Buffer
- ReaderFrom // conflicts with and hides bytes.Buffer's ReaderFrom.
- WriterTo // conflicts with and hides bytes.Buffer's WriterTo.
-}
-
-// Simple tests, primarily to verify the ReadFrom and WriteTo callouts inside Copy and CopyN.
-
-func TestCopy(t *testing.T) {
- rb := new(Buffer)
- wb := new(Buffer)
- rb.WriteString("hello, world.")
- Copy(wb, rb)
- if wb.String() != "hello, world." {
- t.Errorf("Copy did not work properly")
- }
-}
-
-func TestCopyReadFrom(t *testing.T) {
- rb := new(Buffer)
- wb := new(bytes.Buffer) // implements ReadFrom.
- rb.WriteString("hello, world.")
- Copy(wb, rb)
- if wb.String() != "hello, world." {
- t.Errorf("Copy did not work properly")
- }
-}
-
-func TestCopyWriteTo(t *testing.T) {
- rb := new(bytes.Buffer) // implements WriteTo.
- wb := new(Buffer)
- rb.WriteString("hello, world.")
- Copy(wb, rb)
- if wb.String() != "hello, world." {
- t.Errorf("Copy did not work properly")
- }
-}
-
-// Version of bytes.Buffer that checks whether WriteTo was called or not
-type writeToChecker struct {
- bytes.Buffer
- writeToCalled bool
-}
-
-func (wt *writeToChecker) WriteTo(w Writer) (int64, error) {
- wt.writeToCalled = true
- return wt.Buffer.WriteTo(w)
-}
-
-// It's preferable to choose WriterTo over ReaderFrom, since a WriterTo can issue one large write,
-// while the ReaderFrom must read until EOF, potentially allocating when running out of buffer.
-// Make sure that we choose WriterTo when both are implemented.
-func TestCopyPriority(t *testing.T) {
- rb := new(writeToChecker)
- wb := new(bytes.Buffer)
- rb.WriteString("hello, world.")
- Copy(wb, rb)
- if wb.String() != "hello, world." {
- t.Errorf("Copy did not work properly")
- } else if !rb.writeToCalled {
- t.Errorf("WriteTo was not prioritized over ReadFrom")
- }
-}
-
-func TestCopyN(t *testing.T) {
- rb := new(Buffer)
- wb := new(Buffer)
- rb.WriteString("hello, world.")
- CopyN(wb, rb, 5)
- if wb.String() != "hello" {
- t.Errorf("CopyN did not work properly")
- }
-}
-
-func TestCopyNReadFrom(t *testing.T) {
- rb := new(Buffer)
- wb := new(bytes.Buffer) // implements ReadFrom.
- rb.WriteString("hello")
- CopyN(wb, rb, 5)
- if wb.String() != "hello" {
- t.Errorf("CopyN did not work properly")
- }
-}
-
-func TestCopyNWriteTo(t *testing.T) {
- rb := new(bytes.Buffer) // implements WriteTo.
- wb := new(Buffer)
- rb.WriteString("hello, world.")
- CopyN(wb, rb, 5)
- if wb.String() != "hello" {
- t.Errorf("CopyN did not work properly")
- }
-}
-
-type noReadFrom struct {
- w Writer
-}
-
-func (w *noReadFrom) Write(p []byte) (n int, err error) {
- return w.w.Write(p)
-}
-
-type wantedAndErrReader struct{}
-
-func (wantedAndErrReader) Read(p []byte) (int, error) {
- return len(p), errors.New("wantedAndErrReader error")
-}
-
-func TestCopyNEOF(t *testing.T) {
- // Test that EOF behavior is the same regardless of whether
- // argument to CopyN has ReadFrom.
-
- b := new(bytes.Buffer)
-
- 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)
- }
-
- n, err = CopyN(&noReadFrom{b}, strings.NewReader("foo"), 4)
- if n != 3 || err != EOF {
- 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
- if n != 3 || err != nil {
- 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
- if n != 3 || err != EOF {
- t.Errorf("CopyN(bytes.Buffer, foo, 4) = %d, %v; want 3, EOF", n, err)
- }
-
- n, err = CopyN(b, wantedAndErrReader{}, 5)
- if n != 5 || err != nil {
- t.Errorf("CopyN(bytes.Buffer, wantedAndErrReader, 5) = %d, %v; want 5, nil", n, err)
- }
-
- n, err = CopyN(&noReadFrom{b}, wantedAndErrReader{}, 5)
- if n != 5 || err != nil {
- t.Errorf("CopyN(noReadFrom, wantedAndErrReader, 5) = %d, %v; want 5, nil", n, err)
- }
-}
-
-func TestReadAtLeast(t *testing.T) {
- var rb bytes.Buffer
- testReadAtLeast(t, &rb)
-}
-
-// A version of bytes.Buffer that returns n > 0, err on Read
-// when the input is exhausted.
-type dataAndErrorBuffer struct {
- err error
- bytes.Buffer
-}
-
-func (r *dataAndErrorBuffer) Read(p []byte) (n int, err error) {
- n, err = r.Buffer.Read(p)
- if n > 0 && r.Buffer.Len() == 0 && err == nil {
- err = r.err
- }
- return
-}
-
-func TestReadAtLeastWithDataAndEOF(t *testing.T) {
- var rb dataAndErrorBuffer
- rb.err = EOF
- testReadAtLeast(t, &rb)
-}
-
-func TestReadAtLeastWithDataAndError(t *testing.T) {
- var rb dataAndErrorBuffer
- rb.err = fmt.Errorf("fake error")
- testReadAtLeast(t, &rb)
-}
-
-func testReadAtLeast(t *testing.T, rb ReadWriter) {
- rb.Write([]byte("0123"))
- buf := make([]byte, 2)
- n, err := ReadAtLeast(rb, buf, 2)
- if err != nil {
- t.Error(err)
- }
- n, err = ReadAtLeast(rb, buf, 4)
- if err != ErrShortBuffer {
- t.Errorf("expected ErrShortBuffer got %v", err)
- }
- if n != 0 {
- t.Errorf("expected to have read 0 bytes, got %v", n)
- }
- n, err = ReadAtLeast(rb, buf, 1)
- if err != nil {
- t.Error(err)
- }
- if n != 2 {
- t.Errorf("expected to have read 2 bytes, got %v", n)
- }
- n, err = ReadAtLeast(rb, buf, 2)
- if err != EOF {
- t.Errorf("expected EOF, got %v", err)
- }
- if n != 0 {
- t.Errorf("expected to have read 0 bytes, got %v", n)
- }
- rb.Write([]byte("4"))
- n, err = ReadAtLeast(rb, buf, 2)
- want := ErrUnexpectedEOF
- if rb, ok := rb.(*dataAndErrorBuffer); ok && rb.err != EOF {
- want = rb.err
- }
- if err != want {
- t.Errorf("expected %v, got %v", want, err)
- }
- if n != 1 {
- 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 != 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 != ErrClosedPipe {
- t.Errorf("closed tee: ReadFull(r, dst) = %d, %v; want 0, EPIPE", n, err)
- }
-}
-
-func TestSectionReader_ReadAt(t *testing.T) {
- dat := "a long sample data, 1234567890"
- tests := []struct {
- data string
- off int
- n int
- bufLen int
- at int
- exp string
- err error
- }{
- {data: "", off: 0, n: 10, bufLen: 2, at: 0, exp: "", err: EOF},
- {data: dat, off: 0, n: len(dat), bufLen: 0, at: 0, exp: "", err: nil},
- {data: dat, off: len(dat), n: 1, bufLen: 1, at: 0, exp: "", err: EOF},
- {data: dat, off: 0, n: len(dat) + 2, bufLen: len(dat), at: 0, exp: dat, err: nil},
- {data: dat, off: 0, n: len(dat), bufLen: len(dat) / 2, at: 0, exp: dat[:len(dat)/2], err: nil},
- {data: dat, off: 0, n: len(dat), bufLen: len(dat), at: 0, exp: dat, err: nil},
- {data: dat, off: 0, n: len(dat), bufLen: len(dat) / 2, at: 2, exp: dat[2 : 2+len(dat)/2], err: nil},
- {data: dat, off: 3, n: len(dat), bufLen: len(dat) / 2, at: 2, exp: dat[5 : 5+len(dat)/2], err: nil},
- {data: dat, off: 3, n: len(dat) / 2, bufLen: len(dat)/2 - 2, at: 2, exp: dat[5 : 5+len(dat)/2-2], err: nil},
- {data: dat, off: 3, n: len(dat) / 2, bufLen: len(dat)/2 + 2, at: 2, exp: dat[5 : 5+len(dat)/2-2], err: EOF},
- {data: dat, off: 0, n: 0, bufLen: 0, at: -1, exp: "", err: EOF},
- {data: dat, off: 0, n: 0, bufLen: 0, at: 1, exp: "", err: EOF},
- }
- for i, tt := range tests {
- r := strings.NewReader(tt.data)
- s := NewSectionReader(r, int64(tt.off), int64(tt.n))
- buf := make([]byte, tt.bufLen)
- if n, err := s.ReadAt(buf, int64(tt.at)); n != len(tt.exp) || string(buf[:n]) != tt.exp || err != tt.err {
- t.Fatalf("%d: ReadAt(%d) = %q, %v; expected %q, %v", i, tt.at, buf[:n], err, tt.exp, tt.err)
- }
- }
-}
-
-func TestSectionReader_Seek(t *testing.T) {
- // Verifies that NewSectionReader's Seeker behaves like bytes.NewReader (which is like strings.NewReader)
- br := bytes.NewReader([]byte("foo"))
- sr := NewSectionReader(br, 0, int64(len("foo")))
-
- for whence := 0; whence <= 2; whence++ {
- for offset := int64(-3); offset <= 4; offset++ {
- brOff, brErr := br.Seek(offset, whence)
- srOff, srErr := sr.Seek(offset, whence)
- if (brErr != nil) != (srErr != nil) || brOff != srOff {
- t.Errorf("For whence %d, offset %d: bytes.Reader.Seek = (%v, %v) != SectionReader.Seek = (%v, %v)",
- whence, offset, brOff, brErr, srErr, srOff)
- }
- }
- }
-
- // And verify we can just seek past the end and get an EOF
- got, err := sr.Seek(100, 0)
- if err != nil || got != 100 {
- t.Errorf("Seek = %v, %v; want 100, nil", got, err)
- }
-
- n, err := sr.Read(make([]byte, 10))
- if n != 0 || err != EOF {
- t.Errorf("Read = %v, %v; want 0, EOF", n, err)
- }
-}
-
-func TestSectionReader_Size(t *testing.T) {
- tests := []struct {
- data string
- want int64
- }{
- {"a long sample data, 1234567890", 30},
- {"", 0},
- }
-
- for _, tt := range tests {
- r := strings.NewReader(tt.data)
- sr := NewSectionReader(r, 0, int64(len(tt.data)))
- if got := sr.Size(); got != tt.want {
- t.Errorf("Size = %v; want %v", got, tt.want)
- }
- }
-}
diff --git a/src/pkg/io/ioutil/ioutil.go b/src/pkg/io/ioutil/ioutil.go
deleted file mode 100644
index 909a81563..000000000
--- a/src/pkg/io/ioutil/ioutil.go
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright 2009 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 ioutil implements some I/O utility functions.
-package ioutil
-
-import (
- "bytes"
- "io"
- "os"
- "sort"
- "sync"
-)
-
-// readAll reads from r until an error or EOF and returns the data it read
-// from the internal buffer allocated with a specified capacity.
-func readAll(r io.Reader, capacity int64) (b []byte, err error) {
- buf := bytes.NewBuffer(make([]byte, 0, capacity))
- // If the buffer overflows, we will get bytes.ErrTooLarge.
- // Return that as an error. Any other panic remains.
- defer func() {
- e := recover()
- if e == nil {
- return
- }
- if panicErr, ok := e.(error); ok && panicErr == bytes.ErrTooLarge {
- err = panicErr
- } else {
- panic(e)
- }
- }()
- _, err = buf.ReadFrom(r)
- return buf.Bytes(), err
-}
-
-// ReadAll reads from r until an error or EOF and returns the data it read.
-// A successful call returns err == nil, not err == EOF. Because ReadAll is
-// defined to read from src until EOF, it does not treat an EOF from Read
-// as an error to be reported.
-func ReadAll(r io.Reader) ([]byte, error) {
- return readAll(r, bytes.MinRead)
-}
-
-// ReadFile reads the file named by filename and returns the contents.
-// A successful call returns err == nil, not err == EOF. Because ReadFile
-// reads the whole file, it does not treat an EOF from Read as an error
-// to be reported.
-func ReadFile(filename string) ([]byte, error) {
- f, err := os.Open(filename)
- if err != nil {
- return nil, err
- }
- defer f.Close()
- // It's a good but not certain bet that FileInfo will tell us exactly how much to
- // read, so let's try it but be prepared for the answer to be wrong.
- var n int64
-
- if fi, err := f.Stat(); err == nil {
- // Don't preallocate a huge buffer, just in case.
- if size := fi.Size(); size < 1e9 {
- n = size
- }
- }
- // As initial capacity for readAll, use n + a little extra in case Size is zero,
- // and to avoid another allocation after Read has filled the buffer. The readAll
- // call will read into its allocated internal buffer cheaply. If the size was
- // wrong, we'll either waste some space off the end or reallocate as needed, but
- // in the overwhelmingly common case we'll get it just right.
- return readAll(f, n+bytes.MinRead)
-}
-
-// WriteFile writes data to a file named by filename.
-// If the file does not exist, WriteFile creates it with permissions perm;
-// otherwise WriteFile truncates it before writing.
-func WriteFile(filename string, data []byte, perm os.FileMode) error {
- f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
- if err != nil {
- return err
- }
- n, err := f.Write(data)
- if err == nil && n < len(data) {
- err = io.ErrShortWrite
- }
- if err1 := f.Close(); err == nil {
- err = err1
- }
- return err
-}
-
-// byName implements sort.Interface.
-type byName []os.FileInfo
-
-func (f byName) Len() int { return len(f) }
-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.
-func ReadDir(dirname string) ([]os.FileInfo, error) {
- f, err := os.Open(dirname)
- if err != nil {
- return nil, err
- }
- list, err := f.Readdir(-1)
- f.Close()
- if err != nil {
- return nil, err
- }
- sort.Sort(byName(list))
- return list, nil
-}
-
-type nopCloser struct {
- io.Reader
-}
-
-func (nopCloser) Close() error { return nil }
-
-// NopCloser returns a ReadCloser with a no-op Close method wrapping
-// the provided Reader r.
-func NopCloser(r io.Reader) io.ReadCloser {
- return nopCloser{r}
-}
-
-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, error) {
- return len(p), nil
-}
-
-func (devNull) WriteString(s string) (int, error) {
- return len(s), nil
-}
-
-var blackHolePool = sync.Pool{
- New: func() interface{} {
- b := make([]byte, 8192)
- return &b
- },
-}
-
-func (devNull) ReadFrom(r io.Reader) (n int64, err error) {
- bufp := blackHolePool.Get().(*[]byte)
- readSize := 0
- for {
- readSize, err = r.Read(*bufp)
- n += int64(readSize)
- if err != nil {
- blackHolePool.Put(bufp)
- if err == io.EOF {
- return n, nil
- }
- return
- }
- }
-}
-
-// Discard is an io.Writer on which all Write calls succeed
-// without doing anything.
-var Discard io.Writer = devNull(0)
diff --git a/src/pkg/io/ioutil/ioutil_test.go b/src/pkg/io/ioutil/ioutil_test.go
deleted file mode 100644
index c297847b4..000000000
--- a/src/pkg/io/ioutil/ioutil_test.go
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2009 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 ioutil
-
-import (
- "os"
- "testing"
-)
-
-func checkSize(t *testing.T, path string, size int64) {
- dir, err := os.Stat(path)
- if err != nil {
- t.Fatalf("Stat %q (looking for size %d): %s", path, size, err)
- }
- if dir.Size() != size {
- t.Errorf("Stat %q: size %d want %d", path, dir.Size(), size)
- }
-}
-
-func TestReadFile(t *testing.T) {
- filename := "rumpelstilzchen"
- contents, err := ReadFile(filename)
- if err == nil {
- t.Fatalf("ReadFile %s: error expected, none found", filename)
- }
-
- filename = "ioutil_test.go"
- contents, err = ReadFile(filename)
- if err != nil {
- t.Fatalf("ReadFile %s: %v", filename, err)
- }
-
- checkSize(t, filename, int64(len(contents)))
-}
-
-func TestWriteFile(t *testing.T) {
- f, err := TempFile("", "ioutil-test")
- if err != nil {
- t.Fatal(err)
- }
- filename := f.Name()
- data := "Programming today is a race between software engineers striving to " +
- "build bigger and better idiot-proof programs, and the Universe trying " +
- "to produce bigger and better idiots. So far, the Universe is winning."
-
- if err := WriteFile(filename, []byte(data), 0644); err != nil {
- t.Fatalf("WriteFile %s: %v", filename, err)
- }
-
- contents, err := ReadFile(filename)
- if err != nil {
- t.Fatalf("ReadFile %s: %v", filename, err)
- }
-
- if string(contents) != data {
- t.Fatalf("contents = %q\nexpected = %q", string(contents), data)
- }
-
- // cleanup
- f.Close()
- os.Remove(filename) // ignore error
-}
-
-func TestReadDir(t *testing.T) {
- dirname := "rumpelstilzchen"
- _, err := ReadDir(dirname)
- if err == nil {
- t.Fatalf("ReadDir %s: error expected, none found", dirname)
- }
-
- dirname = ".."
- list, err := ReadDir(dirname)
- if err != nil {
- t.Fatalf("ReadDir %s: %v", dirname, err)
- }
-
- foundFile := false
- foundSubDir := false
- for _, dir := range list {
- switch {
- case !dir.IsDir() && dir.Name() == "io_test.go":
- foundFile = true
- case dir.IsDir() && dir.Name() == "ioutil":
- foundSubDir = true
- }
- }
- if !foundFile {
- t.Fatalf("ReadDir %s: io_test.go file not found", dirname)
- }
- if !foundSubDir {
- t.Fatalf("ReadDir %s: ioutil directory not found", dirname)
- }
-}
diff --git a/src/pkg/io/ioutil/tempfile.go b/src/pkg/io/ioutil/tempfile.go
deleted file mode 100644
index 4a06e9756..000000000
--- a/src/pkg/io/ioutil/tempfile.go
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2010 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 ioutil
-
-import (
- "os"
- "path/filepath"
- "strconv"
- "sync"
- "time"
-)
-
-// Random number state.
-// We generate random temporary file names so that there's a good
-// chance the file doesn't exist yet - keeps the number of tries in
-// TempFile to a minimum.
-var rand uint32
-var randmu sync.Mutex
-
-func reseed() uint32 {
- return uint32(time.Now().UnixNano() + int64(os.Getpid()))
-}
-
-func nextSuffix() string {
- randmu.Lock()
- r := rand
- if r == 0 {
- r = reseed()
- }
- r = r*1664525 + 1013904223 // constants from Numerical Recipes
- rand = r
- randmu.Unlock()
- return strconv.Itoa(int(1e9 + r%1e9))[1:]
-}
-
-// TempFile creates a new temporary file in the directory dir
-// with a name beginning with prefix, opens the file for reading
-// and writing, and returns the resulting *os.File.
-// If dir is the empty string, TempFile uses the default directory
-// for temporary files (see os.TempDir).
-// Multiple programs calling TempFile simultaneously
-// will not choose the same file. The caller can use f.Name()
-// to find the pathname of the file. It is the caller's responsibility
-// to remove the file when no longer needed.
-func TempFile(dir, prefix string) (f *os.File, err error) {
- if dir == "" {
- dir = os.TempDir()
- }
-
- nconflict := 0
- for i := 0; i < 10000; i++ {
- name := filepath.Join(dir, prefix+nextSuffix())
- f, err = os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
- if os.IsExist(err) {
- if nconflict++; nconflict > 10 {
- rand = reseed()
- }
- continue
- }
- break
- }
- return
-}
-
-// TempDir creates a new temporary directory in the directory dir
-// with a name beginning with prefix and returns the path of the
-// new directory. If dir is the empty string, TempDir uses the
-// default directory for temporary files (see os.TempDir).
-// Multiple programs calling TempDir simultaneously
-// will not choose the same directory. It is the caller's responsibility
-// to remove the directory when no longer needed.
-func TempDir(dir, prefix string) (name string, err error) {
- if dir == "" {
- dir = os.TempDir()
- }
-
- nconflict := 0
- for i := 0; i < 10000; i++ {
- try := filepath.Join(dir, prefix+nextSuffix())
- err = os.Mkdir(try, 0700)
- if os.IsExist(err) {
- if nconflict++; nconflict > 10 {
- rand = reseed()
- }
- continue
- }
- if err == nil {
- name = try
- }
- break
- }
- return
-}
diff --git a/src/pkg/io/ioutil/tempfile_test.go b/src/pkg/io/ioutil/tempfile_test.go
deleted file mode 100644
index d2a132a11..000000000
--- a/src/pkg/io/ioutil/tempfile_test.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2010 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 ioutil
-
-import (
- "os"
- "path/filepath"
- "regexp"
- "testing"
-)
-
-func TestTempFile(t *testing.T) {
- f, err := TempFile("/_not_exists_", "foo")
- if f != nil || err == nil {
- t.Errorf("TempFile(`/_not_exists_`, `foo`) = %v, %v", f, err)
- }
-
- dir := os.TempDir()
- f, err = TempFile(dir, "ioutil_test")
- if f == nil || err != nil {
- t.Errorf("TempFile(dir, `ioutil_test`) = %v, %v", f, err)
- }
- if f != nil {
- f.Close()
- os.Remove(f.Name())
- re := regexp.MustCompile("^" + regexp.QuoteMeta(filepath.Join(dir, "ioutil_test")) + "[0-9]+$")
- if !re.MatchString(f.Name()) {
- t.Errorf("TempFile(`"+dir+"`, `ioutil_test`) created bad name %s", f.Name())
- }
- }
-}
-
-func TestTempDir(t *testing.T) {
- name, err := TempDir("/_not_exists_", "foo")
- if name != "" || err == nil {
- t.Errorf("TempDir(`/_not_exists_`, `foo`) = %v, %v", name, err)
- }
-
- dir := os.TempDir()
- name, err = TempDir(dir, "ioutil_test")
- if name == "" || err != nil {
- t.Errorf("TempDir(dir, `ioutil_test`) = %v, %v", name, err)
- }
- if name != "" {
- os.Remove(name)
- re := regexp.MustCompile("^" + regexp.QuoteMeta(filepath.Join(dir, "ioutil_test")) + "[0-9]+$")
- if !re.MatchString(name) {
- t.Errorf("TempDir(`"+dir+"`, `ioutil_test`) created bad name %s", name)
- }
- }
-}
diff --git a/src/pkg/io/multi.go b/src/pkg/io/multi.go
deleted file mode 100644
index e26cc53e9..000000000
--- a/src/pkg/io/multi.go
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2010 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
-
-type multiReader struct {
- readers []Reader
-}
-
-func (mr *multiReader) Read(p []byte) (n int, err error) {
- for len(mr.readers) > 0 {
- n, err = mr.readers[0].Read(p)
- if n > 0 || err != EOF {
- if err == EOF {
- // Don't return EOF yet. There may be more bytes
- // in the remaining readers.
- err = nil
- }
- return
- }
- mr.readers = mr.readers[1:]
- }
- return 0, EOF
-}
-
-// MultiReader returns a Reader that's the logical concatenation of
-// the provided input readers. They're read sequentially. Once all
-// inputs have returned EOF, Read will return EOF. If any of the readers
-// return a non-nil, non-EOF error, Read will return that error.
-func MultiReader(readers ...Reader) Reader {
- r := make([]Reader, len(readers))
- copy(r, readers)
- return &multiReader{r}
-}
-
-type multiWriter struct {
- writers []Writer
-}
-
-func (t *multiWriter) Write(p []byte) (n int, err error) {
- for _, w := range t.writers {
- n, err = w.Write(p)
- if err != nil {
- return
- }
- if n != len(p) {
- err = ErrShortWrite
- return
- }
- }
- return len(p), 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 {
- w := make([]Writer, len(writers))
- copy(w, writers)
- return &multiWriter{w}
-}
diff --git a/src/pkg/io/multi_test.go b/src/pkg/io/multi_test.go
deleted file mode 100644
index 56c6769a9..000000000
--- a/src/pkg/io/multi_test.go
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2010 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"
- "crypto/sha1"
- "fmt"
- . "io"
- "io/ioutil"
- "strings"
- "testing"
-)
-
-func TestMultiReader(t *testing.T) {
- var mr Reader
- var buf []byte
- nread := 0
- withFooBar := func(tests func()) {
- r1 := strings.NewReader("foo ")
- r2 := strings.NewReader("")
- r3 := strings.NewReader("bar")
- mr = MultiReader(r1, r2, r3)
- buf = make([]byte, 20)
- tests()
- }
- expectRead := func(size int, expected string, eerr error) {
- nread++
- n, gerr := mr.Read(buf[0:size])
- if n != len(expected) {
- t.Errorf("#%d, expected %d bytes; got %d",
- nread, len(expected), n)
- }
- got := string(buf[0:n])
- if got != expected {
- t.Errorf("#%d, expected %q; got %q",
- nread, expected, got)
- }
- if gerr != eerr {
- t.Errorf("#%d, expected error %v; got %v",
- nread, eerr, gerr)
- }
- buf = buf[n:]
- }
- withFooBar(func() {
- expectRead(2, "fo", nil)
- expectRead(5, "o ", nil)
- expectRead(5, "bar", nil)
- expectRead(5, "", EOF)
- })
- withFooBar(func() {
- expectRead(4, "foo ", nil)
- expectRead(1, "b", nil)
- expectRead(3, "ar", nil)
- expectRead(1, "", EOF)
- })
- withFooBar(func() {
- expectRead(5, "foo ", nil)
- })
-}
-
-func TestMultiWriter(t *testing.T) {
- sha1 := sha1.New()
- sink := new(bytes.Buffer)
- mw := MultiWriter(sha1, sink)
-
- sourceString := "My input text."
- source := strings.NewReader(sourceString)
- written, err := Copy(mw, source)
-
- if written != int64(len(sourceString)) {
- t.Errorf("short write of %d, not %d", written, len(sourceString))
- }
-
- if err != nil {
- t.Errorf("unexpected error: %v", err)
- }
-
- sha1hex := fmt.Sprintf("%x", sha1.Sum(nil))
- if sha1hex != "01cb303fa8c30a64123067c5aa6284ba7ec2d31b" {
- t.Error("incorrect sha1 value")
- }
-
- if sink.String() != sourceString {
- t.Errorf("expected %q; got %q", sourceString, sink.String())
- }
-}
-
-// Test that MultiReader copies the input slice and is insulated from future modification.
-func TestMultiReaderCopy(t *testing.T) {
- slice := []Reader{strings.NewReader("hello world")}
- r := MultiReader(slice...)
- slice[0] = nil
- data, err := ioutil.ReadAll(r)
- if err != nil || string(data) != "hello world" {
- t.Errorf("ReadAll() = %q, %v, want %q, nil", data, err, "hello world")
- }
-}
-
-// Test that MultiWriter copies the input slice and is insulated from future modification.
-func TestMultiWriterCopy(t *testing.T) {
- var buf bytes.Buffer
- slice := []Writer{&buf}
- w := MultiWriter(slice...)
- slice[0] = nil
- n, err := w.Write([]byte("hello world"))
- if err != nil || n != 11 {
- t.Errorf("Write(`hello world`) = %d, %v, want 11, nil", n, err)
- }
- if buf.String() != "hello world" {
- t.Errorf("buf.String() = %q, want %q", buf.String(), "hello world")
- }
-}
diff --git a/src/pkg/io/pipe.go b/src/pkg/io/pipe.go
deleted file mode 100644
index f65354a7f..000000000
--- a/src/pkg/io/pipe.go
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright 2009 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.
-
-// Pipe adapter to connect code expecting an io.Reader
-// with code expecting an io.Writer.
-
-package io
-
-import (
- "errors"
- "sync"
-)
-
-// ErrClosedPipe is the error used for read or write operations on a closed pipe.
-var ErrClosedPipe = errors.New("io: read/write on closed pipe")
-
-type pipeResult struct {
- n int
- err error
-}
-
-// A pipe is the shared pipe structure underlying PipeReader and PipeWriter.
-type pipe struct {
- rl sync.Mutex // gates readers one at a time
- wl sync.Mutex // gates writers one at a time
- l sync.Mutex // protects remaining fields
- data []byte // data remaining in pending write
- rwait sync.Cond // waiting reader
- wwait sync.Cond // waiting writer
- rerr error // if reader closed, error to give writes
- werr error // if writer closed, error to give reads
-}
-
-func (p *pipe) read(b []byte) (n int, err error) {
- // One reader at a time.
- p.rl.Lock()
- defer p.rl.Unlock()
-
- p.l.Lock()
- defer p.l.Unlock()
- for {
- if p.rerr != nil {
- return 0, ErrClosedPipe
- }
- if p.data != nil {
- break
- }
- if p.werr != nil {
- return 0, p.werr
- }
- p.rwait.Wait()
- }
- n = copy(b, p.data)
- p.data = p.data[n:]
- if len(p.data) == 0 {
- p.data = nil
- p.wwait.Signal()
- }
- return
-}
-
-var zero [0]byte
-
-func (p *pipe) write(b []byte) (n int, err error) {
- // pipe uses nil to mean not available
- if b == nil {
- b = zero[:]
- }
-
- // One writer at a time.
- p.wl.Lock()
- defer p.wl.Unlock()
-
- p.l.Lock()
- defer p.l.Unlock()
- if p.werr != nil {
- err = ErrClosedPipe
- return
- }
- p.data = b
- p.rwait.Signal()
- for {
- if p.data == nil {
- break
- }
- if p.rerr != nil {
- err = p.rerr
- break
- }
- if p.werr != nil {
- err = ErrClosedPipe
- }
- p.wwait.Wait()
- }
- n = len(b) - len(p.data)
- p.data = nil // in case of rerr or werr
- return
-}
-
-func (p *pipe) rclose(err error) {
- if err == nil {
- err = ErrClosedPipe
- }
- p.l.Lock()
- defer p.l.Unlock()
- p.rerr = err
- p.rwait.Signal()
- p.wwait.Signal()
-}
-
-func (p *pipe) wclose(err error) {
- if err == nil {
- err = EOF
- }
- p.l.Lock()
- defer p.l.Unlock()
- p.werr = err
- p.rwait.Signal()
- p.wwait.Signal()
-}
-
-// A PipeReader is the read half of a pipe.
-type PipeReader struct {
- p *pipe
-}
-
-// Read implements the standard Read interface:
-// it reads data from the pipe, blocking until a writer
-// arrives or the write end is closed.
-// If the write end is closed with an error, that error is
-// returned as err; otherwise err is EOF.
-func (r *PipeReader) Read(data []byte) (n int, err error) {
- return r.p.read(data)
-}
-
-// Close closes the reader; subsequent writes to the
-// write half of the pipe will return the error ErrClosedPipe.
-func (r *PipeReader) Close() error {
- return r.CloseWithError(nil)
-}
-
-// CloseWithError closes the reader; subsequent writes
-// to the write half of the pipe will return the error err.
-func (r *PipeReader) CloseWithError(err error) error {
- r.p.rclose(err)
- return nil
-}
-
-// A PipeWriter is the write half of a pipe.
-type PipeWriter struct {
- p *pipe
-}
-
-// Write implements the standard Write interface:
-// it writes data to the pipe, blocking until readers
-// have consumed all the data or the read end is closed.
-// If the read end is closed with an error, that err is
-// returned as err; otherwise err is ErrClosedPipe.
-func (w *PipeWriter) Write(data []byte) (n int, err error) {
- return w.p.write(data)
-}
-
-// Close closes the writer; subsequent reads from the
-// read half of the pipe will return no bytes and EOF.
-func (w *PipeWriter) Close() error {
- return w.CloseWithError(nil)
-}
-
-// CloseWithError closes the writer; subsequent reads from the
-// read half of the pipe will return no bytes and the error err.
-func (w *PipeWriter) CloseWithError(err error) error {
- w.p.wclose(err)
- return nil
-}
-
-// Pipe creates a synchronous in-memory pipe.
-// It can be used to connect code expecting an io.Reader
-// with code expecting an io.Writer.
-// Reads on one end are matched with writes on the other,
-// copying data directly between the two; there is no internal buffering.
-// It is safe to call Read and Write in parallel with each other or with
-// Close. Close will complete once pending I/O is done. Parallel calls to
-// Read, and parallel calls to Write, are also safe:
-// the individual calls will be gated sequentially.
-func Pipe() (*PipeReader, *PipeWriter) {
- p := new(pipe)
- p.rwait.L = &p.l
- p.wwait.L = &p.l
- r := &PipeReader{p}
- w := &PipeWriter{p}
- return r, w
-}
diff --git a/src/pkg/io/pipe_test.go b/src/pkg/io/pipe_test.go
deleted file mode 100644
index b16e65306..000000000
--- a/src/pkg/io/pipe_test.go
+++ /dev/null
@@ -1,302 +0,0 @@
-// Copyright 2009 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 (
- "fmt"
- . "io"
- "testing"
- "time"
-)
-
-func checkWrite(t *testing.T, w Writer, data []byte, c chan int) {
- n, err := w.Write(data)
- if err != nil {
- t.Errorf("write: %v", err)
- }
- if n != len(data) {
- t.Errorf("short write: %d != %d", n, len(data))
- }
- c <- 0
-}
-
-// Test a single read/write pair.
-func TestPipe1(t *testing.T) {
- c := make(chan int)
- r, w := Pipe()
- var buf = make([]byte, 64)
- go checkWrite(t, w, []byte("hello, world"), c)
- n, err := r.Read(buf)
- if err != nil {
- t.Errorf("read: %v", err)
- } else if n != 12 || string(buf[0:12]) != "hello, world" {
- t.Errorf("bad read: got %q", buf[0:n])
- }
- <-c
- r.Close()
- w.Close()
-}
-
-func reader(t *testing.T, r Reader, c chan int) {
- var buf = make([]byte, 64)
- for {
- n, err := r.Read(buf)
- if err == EOF {
- c <- 0
- break
- }
- if err != nil {
- t.Errorf("read: %v", err)
- }
- c <- n
- }
-}
-
-// Test a sequence of read/write pairs.
-func TestPipe2(t *testing.T) {
- c := make(chan int)
- r, w := Pipe()
- go reader(t, r, c)
- var buf = make([]byte, 64)
- for i := 0; i < 5; i++ {
- p := buf[0 : 5+i*10]
- n, err := w.Write(p)
- if n != len(p) {
- t.Errorf("wrote %d, got %d", len(p), n)
- }
- if err != nil {
- t.Errorf("write: %v", err)
- }
- nn := <-c
- if nn != n {
- t.Errorf("wrote %d, read got %d", n, nn)
- }
- }
- w.Close()
- nn := <-c
- if nn != 0 {
- t.Errorf("final read got %d", nn)
- }
-}
-
-type pipeReturn struct {
- n int
- err error
-}
-
-// Test a large write that requires multiple reads to satisfy.
-func writer(w WriteCloser, buf []byte, c chan pipeReturn) {
- n, err := w.Write(buf)
- w.Close()
- c <- pipeReturn{n, err}
-}
-
-func TestPipe3(t *testing.T) {
- c := make(chan pipeReturn)
- r, w := Pipe()
- var wdat = make([]byte, 128)
- for i := 0; i < len(wdat); i++ {
- wdat[i] = byte(i)
- }
- go writer(w, wdat, c)
- var rdat = make([]byte, 1024)
- tot := 0
- for n := 1; n <= 256; n *= 2 {
- nn, err := r.Read(rdat[tot : tot+n])
- if err != nil && err != EOF {
- t.Fatalf("read: %v", err)
- }
-
- // only final two reads should be short - 1 byte, then 0
- expect := n
- if n == 128 {
- expect = 1
- } else if n == 256 {
- expect = 0
- if err != EOF {
- t.Fatalf("read at end: %v", err)
- }
- }
- if nn != expect {
- t.Fatalf("read %d, expected %d, got %d", n, expect, nn)
- }
- tot += nn
- }
- pr := <-c
- if pr.n != 128 || pr.err != nil {
- t.Fatalf("write 128: %d, %v", pr.n, pr.err)
- }
- if tot != 128 {
- t.Fatalf("total read %d != 128", tot)
- }
- for i := 0; i < 128; i++ {
- if rdat[i] != byte(i) {
- t.Fatalf("rdat[%d] = %d", i, rdat[i])
- }
- }
-}
-
-// Test read after/before writer close.
-
-type closer interface {
- CloseWithError(error) error
- Close() error
-}
-
-type pipeTest struct {
- async bool
- err error
- closeWithError bool
-}
-
-func (p pipeTest) String() string {
- return fmt.Sprintf("async=%v err=%v closeWithError=%v", p.async, p.err, p.closeWithError)
-}
-
-var pipeTests = []pipeTest{
- {true, nil, false},
- {true, nil, true},
- {true, ErrShortWrite, true},
- {false, nil, false},
- {false, nil, true},
- {false, ErrShortWrite, true},
-}
-
-func delayClose(t *testing.T, cl closer, ch chan int, tt pipeTest) {
- time.Sleep(1 * time.Millisecond)
- var err error
- if tt.closeWithError {
- err = cl.CloseWithError(tt.err)
- } else {
- err = cl.Close()
- }
- if err != nil {
- t.Errorf("delayClose: %v", err)
- }
- ch <- 0
-}
-
-func TestPipeReadClose(t *testing.T) {
- for _, tt := range pipeTests {
- c := make(chan int, 1)
- r, w := Pipe()
- if tt.async {
- go delayClose(t, w, c, tt)
- } else {
- delayClose(t, w, c, tt)
- }
- var buf = make([]byte, 64)
- n, err := r.Read(buf)
- <-c
- want := tt.err
- if want == nil {
- want = EOF
- }
- if err != want {
- t.Errorf("read from closed pipe: %v want %v", err, want)
- }
- if n != 0 {
- t.Errorf("read on closed pipe returned %d", n)
- }
- if err = r.Close(); err != nil {
- t.Errorf("r.Close: %v", err)
- }
- }
-}
-
-// Test close on Read side during Read.
-func TestPipeReadClose2(t *testing.T) {
- c := make(chan int, 1)
- r, _ := Pipe()
- go delayClose(t, r, c, pipeTest{})
- n, err := r.Read(make([]byte, 64))
- <-c
- if n != 0 || err != ErrClosedPipe {
- t.Errorf("read from closed pipe: %v, %v want %v, %v", n, err, 0, ErrClosedPipe)
- }
-}
-
-// Test write after/before reader close.
-
-func TestPipeWriteClose(t *testing.T) {
- for _, tt := range pipeTests {
- c := make(chan int, 1)
- r, w := Pipe()
- if tt.async {
- go delayClose(t, r, c, tt)
- } else {
- delayClose(t, r, c, tt)
- }
- n, err := WriteString(w, "hello, world")
- <-c
- expect := tt.err
- if expect == nil {
- expect = ErrClosedPipe
- }
- if err != expect {
- t.Errorf("write on closed pipe: %v want %v", err, expect)
- }
- if n != 0 {
- t.Errorf("write on closed pipe returned %d", n)
- }
- if err = w.Close(); err != nil {
- t.Errorf("w.Close: %v", err)
- }
- }
-}
-
-func TestWriteEmpty(t *testing.T) {
- r, w := Pipe()
- go func() {
- w.Write([]byte{})
- w.Close()
- }()
- var b [2]byte
- ReadFull(r, b[0:2])
- r.Close()
-}
-
-func TestWriteNil(t *testing.T) {
- r, w := Pipe()
- go func() {
- w.Write(nil)
- w.Close()
- }()
- var b [2]byte
- ReadFull(r, b[0:2])
- r.Close()
-}
-
-func TestWriteAfterWriterClose(t *testing.T) {
- r, w := Pipe()
-
- done := make(chan bool)
- var writeErr error
- go func() {
- _, err := w.Write([]byte("hello"))
- if err != nil {
- t.Errorf("got error: %q; expected none", err)
- }
- w.Close()
- _, writeErr = w.Write([]byte("world"))
- done <- true
- }()
-
- buf := make([]byte, 100)
- var result string
- n, err := ReadFull(r, buf)
- if err != nil && err != ErrUnexpectedEOF {
- t.Fatalf("got: %q; want: %q", err, ErrUnexpectedEOF)
- }
- result = string(buf[0:n])
- <-done
-
- if result != "hello" {
- t.Errorf("got: %q; want: %q", result, "hello")
- }
- if writeErr != ErrClosedPipe {
- t.Errorf("got: %q; want: %q", writeErr, ErrClosedPipe)
- }
-}