// 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 iotype eofReader struct{}func (eofReader) ([]byte) (int, error) {return0, EOF}type multiReader struct { readers []Reader}func ( *multiReader) ( []byte) ( int, error) {forlen(.readers) > 0 {// Optimization to flatten nested multiReaders (Issue 13558).iflen(.readers) == 1 {if , := .readers[0].(*multiReader); { .readers = .readerscontinue } } , = .readers[0].Read()if == EOF {// Use eofReader instead of nil to avoid nil panic // after performing flatten (Issue 18232). .readers[0] = eofReader{} // permit earlier GC .readers = .readers[1:] }if > 0 || != EOF {if == EOF && len(.readers) > 0 {// Don't return EOF yet. More readers remain. = nil }return } }return0, EOF}func ( *multiReader) ( Writer) ( int64, error) {return .writeToWithBuffer(, make([]byte, 1024*32))}func ( *multiReader) ( Writer, []byte) ( int64, error) {for , := range .readers {varint64if , := .(*multiReader); { // reuse buffer with nested multiReaders , = .(, ) } else { , = copyBuffer(, , ) } += if != nil { .readers = .readers[:] // permit resume / retry after errorreturn , } .readers[] = nil// permit early GC } .readers = nilreturn , nil}var _ WriterTo = (*multiReader)(nil)// 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 ( ...Reader) Reader { := make([]Reader, len())copy(, )return &multiReader{}}type multiWriter struct { writers []Writer}func ( *multiWriter) ( []byte) ( int, error) {for , := range .writers { , = .Write()if != nil {return }if != len() { = ErrShortWritereturn } }returnlen(), nil}var _ StringWriter = (*multiWriter)(nil)func ( *multiWriter) ( string) ( int, error) {var []byte// lazily initialized if/when neededfor , := range .writers {if , := .(StringWriter); { , = .WriteString() } else {if == nil { = []byte() } , = .Write() }if != nil {return }if != len() { = ErrShortWritereturn } }returnlen(), nil}// MultiWriter 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.func ( ...Writer) Writer { := make([]Writer, 0, len())for , := range {if , := .(*multiWriter); { = append(, .writers...) } else { = append(, ) } }return &multiWriter{}}
The pages are generated with Goldsv0.7.0-preview. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.