lin
2025-06-05 ed3dd9d3e7519a82bb871d5eedb24a2fa0c91f47
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// 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 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 {
       // Optimization to flatten nested multiReaders (Issue 13558).
       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 {
           // Use eofReader instead of nil to avoid nil panic
           // after performing flatten (Issue 18232).
           mr.readers[0] = eofReader{} // permit earlier GC
           mr.readers = mr.readers[1:]
       }
       if n > 0 || err != EOF {
           if err == EOF && len(mr.readers) > 0 {
               // Don't return EOF yet. More readers remain.
               err = nil
           }
           return
       }
   }
   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
}
 
var _ StringWriter = (*multiWriter)(nil)
 
func (t *multiWriter) WriteString(s string) (n int, err error) {
   var p []byte // lazily initialized if/when needed
   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
}
 
// 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 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}
}