diff options
Diffstat (limited to 'src/io/multi.go')
-rw-r--r-- | src/io/multi.go | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/src/io/multi.go b/src/io/multi.go new file mode 100644 index 000000000..e26cc53e9 --- /dev/null +++ b/src/io/multi.go @@ -0,0 +1,61 @@ +// 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} +} |