offset_reader.go 1.2 KB

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