Documentation ¶
Overview ¶
Package plumbing is a collection of assorted I/O helpers.
Index ¶
- func DevZero() io.ReadWriter
- func FillReader(b byte) io.Reader
- func LimitReadCloser(r io.ReadCloser, n int64) io.ReadCloser
- func MultiReadCloser(readClosers ...io.ReadCloser) io.ReadCloser
- func MultiWriteCloser(writeClosers ...io.WriteCloser) io.WriteCloser
- func NopWriteCloser(w io.Writer) io.WriteCloser
- func PaddedReader(r io.Reader, n int64, fill byte) io.Reader
- func TeeReadCloser(r io.ReadCloser, w io.Writer) io.ReadCloser
- func TeeReaderAt(r io.ReaderAt, w io.Writer) io.ReaderAt
- type LimitedReadCloser
- type WriteCounter
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DevZero ¶ added in v1.3.0
func DevZero() io.ReadWriter
DevZero returns an io.ReadWriter that behaves like /dev/zero such that Read calls return an unlimited stream of zero bytes and all Write calls succeed without doing anything.
func FillReader ¶ added in v1.3.0
FillReader returns an io.Reader such that Read calls return an unlimited stream of b bytes.
func LimitReadCloser ¶ added in v1.1.0
func LimitReadCloser(r io.ReadCloser, n int64) io.ReadCloser
LimitReadCloser returns an io.ReadCloser that reads from r but stops with EOF after n bytes. The underlying implementation is a *LimitedReadCloser.
Example ¶
package main import ( "bytes" "fmt" "io" "github.com/bodgit/plumbing" ) func main() { in := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} reader := plumbing.LimitReadCloser(io.NopCloser(bytes.NewReader(in)), 5) writer := new(bytes.Buffer) if _, err := io.Copy(writer, reader); err != nil { panic(err) } if err := reader.Close(); err != nil { panic(err) } fmt.Println(writer.Bytes()) }
Output: [0 1 2 3 4]
func MultiReadCloser ¶ added in v1.2.0
func MultiReadCloser(readClosers ...io.ReadCloser) io.ReadCloser
MultiReadCloser returns an io.ReadCloser that's the logical concatenation of the provider input readers. They're read sequentially. Once all inputs have returned io.EOF, Read will return EOF. If any of the readers return a non-nil, non-EOF error, Read will return that error.
Example ¶
package main import ( "bytes" "fmt" "io" "github.com/bodgit/plumbing" ) func main() { b1, b2 := bytes.NewReader([]byte{0, 1, 2, 3}), bytes.NewReader([]byte{4, 5, 6, 7}) r := plumbing.MultiReadCloser(io.NopCloser(b1), io.NopCloser(b2)) w := new(bytes.Buffer) if _, err := io.Copy(w, r); err != nil { panic(err) } if err := r.Close(); err != nil { panic(err) } fmt.Println(w.Bytes()) }
Output: [0 1 2 3 4 5 6 7]
func MultiWriteCloser ¶
func MultiWriteCloser(writeClosers ...io.WriteCloser) io.WriteCloser
MultiWriteCloser creates a writer that duplicates its writes to all the provided writers, similar to the Unix tee(1) command.
Each write is written to each listed writer, one at a time. If a listed writer returns an error, that overall write operation stops and returns the error; it does not continue down the list.
Example ¶
package main import ( "bytes" "fmt" "github.com/bodgit/plumbing" ) func main() { in := []byte{0, 1, 2, 3} b1, b2 := new(bytes.Buffer), new(bytes.Buffer) writer := plumbing.MultiWriteCloser(plumbing.NopWriteCloser(b1), plumbing.NopWriteCloser(b2)) if _, err := writer.Write(in); err != nil { panic(err) } if err := writer.Close(); err != nil { panic(err) } fmt.Println(b1.Bytes(), b2.Bytes()) }
Output: [0 1 2 3] [0 1 2 3]
func NopWriteCloser ¶
func NopWriteCloser(w io.Writer) io.WriteCloser
NopWriteCloser returns an io.WriteCloser with a no-op Close method wrapping the provided io.Writer w.
Example ¶
package main import ( "bytes" "fmt" "github.com/bodgit/plumbing" ) func main() { writer := plumbing.NopWriteCloser(new(bytes.Buffer)) fmt.Println(writer.Close()) }
Output: <nil>
func PaddedReader ¶
PaddedReader returns an io.Reader that reads at most n bytes from r. If fewer than n bytes are available from r then any remaining bytes return fill instead.
Example ¶
package main import ( "bytes" "fmt" "io" "github.com/bodgit/plumbing" ) func main() { in := []byte{1, 2, 3, 4} reader := plumbing.PaddedReader(bytes.NewReader(in), 8, 0) writer := new(bytes.Buffer) if _, err := io.Copy(writer, reader); err != nil { panic(err) } fmt.Println(writer.Bytes()) }
Output: [1 2 3 4 0 0 0 0]
func TeeReadCloser ¶
func TeeReadCloser(r io.ReadCloser, w io.Writer) io.ReadCloser
TeeReadCloser returns an io.ReadCloser 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.
Example ¶
package main import ( "bytes" "fmt" "io" "github.com/bodgit/plumbing" ) func main() { in := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} writer := plumbing.WriteCounter{} reader := plumbing.TeeReadCloser(io.NopCloser(bytes.NewReader(in)), &writer) defer reader.Close() if _, err := io.Copy(io.Discard, reader); err != nil { panic(err) } fmt.Println(writer.Count()) }
Output: 10
func TeeReaderAt ¶
TeeReaderAt returns an io.ReaderAt 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.
Example ¶
package main import ( "archive/zip" "bytes" "fmt" "github.com/bodgit/plumbing" ) func main() { // Smallest valid zip archive in := []byte{80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} writer := plumbing.WriteCounter{} if _, err := zip.NewReader(plumbing.TeeReaderAt(bytes.NewReader(in), &writer), int64(len(in))); err != nil { panic(err) } fmt.Println(writer.Count()) }
Output: 44
Types ¶
type LimitedReadCloser ¶ added in v1.1.0
type LimitedReadCloser struct { R io.ReadCloser N int64 }
A LimitedReadCloser 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. Read returns EOF when N <= 0 or when the underlying R returns EOF.
func (*LimitedReadCloser) Close ¶ added in v1.1.0
func (l *LimitedReadCloser) Close() error
Close closes the LimitedReadCloser, rendering it unusable for I/O.
type WriteCounter ¶
type WriteCounter struct {
// contains filtered or unexported fields
}
WriteCounter is an io.Writer that simply counts the number of bytes written to it.
Example ¶
package main import ( "bytes" "fmt" "io" "github.com/bodgit/plumbing" ) func main() { in := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} writer := plumbing.WriteCounter{} reader := io.TeeReader(bytes.NewReader(in), &writer) if _, err := io.CopyN(io.Discard, reader, 4); err != nil { panic(err) } if _, err := io.Copy(io.Discard, reader); err != nil { panic(err) } fmt.Println(writer.Count()) }
Output: 10
func (*WriteCounter) Count ¶
func (wc *WriteCounter) Count() uint64
Count returns the number of bytes written.