123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- package pathway
- import (
- "io"
- )
- type broadcastWriter struct {
- writers []io.Writer
- }
- func (t *broadcastWriter) Close() (err error) {
- for i := 0; i < len(t.writers); i++ {
- if w, ok := t.writers[i].(io.WriteCloser); ok {
- if e := w.Close(); e != nil {
- err = e
- }
- }
- }
- return
- }
- func (t *broadcastWriter) Write(p []byte) (n int, err error) {
- for i := 0; i < len(t.writers); i++ {
- n, err = t.writers[i].Write(p)
- if err == nil && n != len(p) {
- err = io.ErrShortWrite
- }
- if err != nil {
- // if not at the end, move last to here and redo this
- if i < len(t.writers)-1 {
- // close the writer if it implements WriteCloser
- if w, ok := t.writers[i].(io.WriteCloser); ok {
- defer w.Close()
- }
- t.writers[i] = t.writers[len(t.writers)-1]
- i = i - 1
- }
- // always shorten list by one to drop the last one
- t.writers = t.writers[:len(t.writers)-1]
- }
- }
- if len(t.writers) <= 0 {
- return 0, err
- }
- return len(p), nil
- }
- // BroadcastWriter 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
- // continues and the offending writer is dropped from the list.
- //
- // Only if all writers are dropped, the last error is returned at the end.
- func BroadcastWriter(writers ...io.Writer) io.WriteCloser {
- allWriters := make([]io.Writer, 0, len(writers))
- for _, w := range writers {
- if bw, ok := w.(*broadcastWriter); ok {
- allWriters = append(allWriters, bw.writers...)
- } else {
- allWriters = append(allWriters, w)
- }
- }
- return &broadcastWriter{allWriters}
- }
|