github.com/daaku/docker@v1.5.0/pkg/ioutils/readers.go (about)

     1  package ioutils
     2  
     3  import (
     4  	"bytes"
     5  	"io"
     6  	"sync"
     7  )
     8  
     9  type readCloserWrapper struct {
    10  	io.Reader
    11  	closer func() error
    12  }
    13  
    14  func (r *readCloserWrapper) Close() error {
    15  	return r.closer()
    16  }
    17  
    18  func NewReadCloserWrapper(r io.Reader, closer func() error) io.ReadCloser {
    19  	return &readCloserWrapper{
    20  		Reader: r,
    21  		closer: closer,
    22  	}
    23  }
    24  
    25  type readerErrWrapper struct {
    26  	reader io.Reader
    27  	closer func()
    28  }
    29  
    30  func (r *readerErrWrapper) Read(p []byte) (int, error) {
    31  	n, err := r.reader.Read(p)
    32  	if err != nil {
    33  		r.closer()
    34  	}
    35  	return n, err
    36  }
    37  
    38  func NewReaderErrWrapper(r io.Reader, closer func()) io.Reader {
    39  	return &readerErrWrapper{
    40  		reader: r,
    41  		closer: closer,
    42  	}
    43  }
    44  
    45  type bufReader struct {
    46  	sync.Mutex
    47  	buf      *bytes.Buffer
    48  	reader   io.Reader
    49  	err      error
    50  	wait     sync.Cond
    51  	drainBuf []byte
    52  }
    53  
    54  func NewBufReader(r io.Reader) *bufReader {
    55  	reader := &bufReader{
    56  		buf:      &bytes.Buffer{},
    57  		drainBuf: make([]byte, 1024),
    58  		reader:   r,
    59  	}
    60  	reader.wait.L = &reader.Mutex
    61  	go reader.drain()
    62  	return reader
    63  }
    64  
    65  func NewBufReaderWithDrainbufAndBuffer(r io.Reader, drainBuffer []byte, buffer *bytes.Buffer) *bufReader {
    66  	reader := &bufReader{
    67  		buf:      buffer,
    68  		drainBuf: drainBuffer,
    69  		reader:   r,
    70  	}
    71  	reader.wait.L = &reader.Mutex
    72  	go reader.drain()
    73  	return reader
    74  }
    75  
    76  func (r *bufReader) drain() {
    77  	for {
    78  		n, err := r.reader.Read(r.drainBuf)
    79  		r.Lock()
    80  		if err != nil {
    81  			r.err = err
    82  		} else {
    83  			r.buf.Write(r.drainBuf[0:n])
    84  		}
    85  		r.wait.Signal()
    86  		r.Unlock()
    87  		if err != nil {
    88  			break
    89  		}
    90  	}
    91  }
    92  
    93  func (r *bufReader) Read(p []byte) (n int, err error) {
    94  	r.Lock()
    95  	defer r.Unlock()
    96  	for {
    97  		n, err = r.buf.Read(p)
    98  		if n > 0 {
    99  			return n, err
   100  		}
   101  		if r.err != nil {
   102  			return 0, r.err
   103  		}
   104  		r.wait.Wait()
   105  	}
   106  }
   107  
   108  func (r *bufReader) Close() error {
   109  	closer, ok := r.reader.(io.ReadCloser)
   110  	if !ok {
   111  		return nil
   112  	}
   113  	return closer.Close()
   114  }