| | |
| | |
| | |
| |
|
| | package io |
| |
|
| | type eofReader struct{} |
| |
|
| | func (eofReader) Read([]byte) (int, error) { |
| | return 0, EOF |
| | } |
| |
|
| | type multiReader struct { |
| | readers []Reader |
| | } |
| |
|
| | func (mr *multiReader) Read(p []byte) (n int, err error) { |
| | for len(mr.readers) > 0 { |
| | |
| | if len(mr.readers) == 1 { |
| | if r, ok := mr.readers[0].(*multiReader); ok { |
| | mr.readers = r.readers |
| | continue |
| | } |
| | } |
| | n, err = mr.readers[0].Read(p) |
| | if err == EOF { |
| | |
| | |
| | mr.readers[0] = eofReader{} |
| | mr.readers = mr.readers[1:] |
| | } |
| | if n > 0 || err != EOF { |
| | if err == EOF && len(mr.readers) > 0 { |
| | |
| | err = nil |
| | } |
| | return |
| | } |
| | } |
| | return 0, EOF |
| | } |
| |
|
| | func (mr *multiReader) WriteTo(w Writer) (sum int64, err error) { |
| | return mr.writeToWithBuffer(w, make([]byte, 1024*32)) |
| | } |
| |
|
| | func (mr *multiReader) writeToWithBuffer(w Writer, buf []byte) (sum int64, err error) { |
| | for i, r := range mr.readers { |
| | var n int64 |
| | if subMr, ok := r.(*multiReader); ok { |
| | n, err = subMr.writeToWithBuffer(w, buf) |
| | } else { |
| | n, err = copyBuffer(w, r, buf) |
| | } |
| | sum += n |
| | if err != nil { |
| | mr.readers = mr.readers[i:] |
| | return sum, err |
| | } |
| | mr.readers[i] = nil |
| | } |
| | mr.readers = nil |
| | return sum, nil |
| | } |
| |
|
| | var _ WriterTo = (*multiReader)(nil) |
| |
|
| | |
| | |
| | |
| | |
| | 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 |
| | } |
| |
|
| | var _ StringWriter = (*multiWriter)(nil) |
| |
|
| | func (t *multiWriter) WriteString(s string) (n int, err error) { |
| | var p []byte |
| | 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 |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | func MultiWriter(writers ...Writer) Writer { |
| | allWriters := make([]Writer, 0, len(writers)) |
| | for _, w := range writers { |
| | if mw, ok := w.(*multiWriter); ok { |
| | allWriters = append(allWriters, mw.writers...) |
| | } else { |
| | allWriters = append(allWriters, w) |
| | } |
| | } |
| | return &multiWriter{allWriters} |
| | } |
| |
|