github.com/aavshr/aws-sdk-go@v1.41.3/aws/request/offset_reader.go (about)

     1  package request
     2  
     3  import (
     4  	"io"
     5  	"sync"
     6  
     7  	"github.com/aavshr/aws-sdk-go/internal/sdkio"
     8  )
     9  
    10  // offsetReader is a thread-safe io.ReadCloser to prevent racing
    11  // with retrying requests
    12  type offsetReader struct {
    13  	buf    io.ReadSeeker
    14  	lock   sync.Mutex
    15  	closed bool
    16  }
    17  
    18  func newOffsetReader(buf io.ReadSeeker, offset int64) (*offsetReader, error) {
    19  	reader := &offsetReader{}
    20  	_, err := buf.Seek(offset, sdkio.SeekStart)
    21  	if err != nil {
    22  		return nil, err
    23  	}
    24  
    25  	reader.buf = buf
    26  	return reader, nil
    27  }
    28  
    29  // Close will close the instance of the offset reader's access to
    30  // the underlying io.ReadSeeker.
    31  func (o *offsetReader) Close() error {
    32  	o.lock.Lock()
    33  	defer o.lock.Unlock()
    34  	o.closed = true
    35  	return nil
    36  }
    37  
    38  // Read is a thread-safe read of the underlying io.ReadSeeker
    39  func (o *offsetReader) Read(p []byte) (int, error) {
    40  	o.lock.Lock()
    41  	defer o.lock.Unlock()
    42  
    43  	if o.closed {
    44  		return 0, io.EOF
    45  	}
    46  
    47  	return o.buf.Read(p)
    48  }
    49  
    50  // Seek is a thread-safe seeking operation.
    51  func (o *offsetReader) Seek(offset int64, whence int) (int64, error) {
    52  	o.lock.Lock()
    53  	defer o.lock.Unlock()
    54  
    55  	return o.buf.Seek(offset, whence)
    56  }
    57  
    58  // CloseAndCopy will return a new offsetReader with a copy of the old buffer
    59  // and close the old buffer.
    60  func (o *offsetReader) CloseAndCopy(offset int64) (*offsetReader, error) {
    61  	if err := o.Close(); err != nil {
    62  		return nil, err
    63  	}
    64  	return newOffsetReader(o.buf, offset)
    65  }