github.com/haraldrudell/parl@v0.4.176/pio/read-writer-tap.go (about)

     1  /*
     2  © 2023–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/)
     3  ISC License
     4  */
     5  
     6  package pio
     7  
     8  import (
     9  	"io"
    10  	"net"
    11  
    12  	"github.com/haraldrudell/parl"
    13  )
    14  
    15  type ReadWriterTap struct {
    16  	io.ReadWriter
    17  	t *Tap
    18  }
    19  
    20  // NewReadWriterTap returns a data tap for a bidirectional data stream
    21  //   - data from readWriter.Read is written to reads.Write if non-nil
    22  //   - data written to readWriter.Write is written to writes.Write if non-nil
    23  //   - a non-nil errs receives all errors from delegated Read Write reads and writes
    24  //   - if errs is nil, an error from the reads and writes taps is panic
    25  //   - ReadWriterTap impements idempotent Close
    26  //   - if any of readWriter, reads or writes implements io.Close, they are closed on socketTap.Close
    27  //   - the consumer may invoke socketTap.Close to ensure reads and writes are closed
    28  //   - errors in reads or writes do not affect the socketTap consumer
    29  func NewReadWriterTap(readWriter io.ReadWriter, reads, writes io.Writer, errs func(err error)) (socketTap io.ReadWriter) {
    30  	if readWriter == nil {
    31  		panic(parl.NilError("readWriter"))
    32  	}
    33  	socketTap = &ReadWriterTap{
    34  		ReadWriter: readWriter,
    35  		t:          NewTap(reads, writes, errs),
    36  	}
    37  	return
    38  }
    39  
    40  func (t *ReadWriterTap) Read(p []byte) (n int, err error) { return t.t.Read(t.ReadWriter, p) }
    41  
    42  func (t *ReadWriterTap) Write(p []byte) (n int, err error) { return t.t.Write(t.ReadWriter, p) }
    43  
    44  func (t *ReadWriterTap) Close() (err error) { return t.t.Close(t.ReadWriter) }
    45  
    46  var _ io.Reader
    47  var _ io.Writer
    48  
    49  // Pipe creates a synchronous, in-memory, full duplex network connection
    50  //   - writes are behind lock to unbuffered channel
    51  //   - both returned connections are identical
    52  //   - no threads
    53  //   - func net.Pipe() (net.Conn, net.Conn)
    54  var _ = net.Pipe
    55  
    56  // Pipe creates a synchronous in-memory pipe
    57  //   - Write is behind lock and waits for sufficient reads
    58  //   - writer is io.WriteCloser
    59  //   - no threads
    60  //   - func io.Pipe() (*io.PipeReader, *io.PipeWriter)
    61  var _ = io.Pipe