lazy_reader.go 949 B

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. package splithttp
  2. import (
  3. "io"
  4. "sync"
  5. )
  6. // Close is intentionally not supported by LazyReader because it's not clear
  7. // how CreateReader should be aborted in case of Close. It's best to wrap
  8. // LazyReader in another struct that handles Close correctly, or better, stop
  9. // using LazyReader entirely.
  10. type LazyReader struct {
  11. readerSync sync.Mutex
  12. CreateReader func() (io.Reader, error)
  13. reader io.Reader
  14. readerError error
  15. }
  16. func (r *LazyReader) getReader() (io.Reader, error) {
  17. r.readerSync.Lock()
  18. defer r.readerSync.Unlock()
  19. if r.reader != nil {
  20. return r.reader, nil
  21. }
  22. if r.readerError != nil {
  23. return nil, r.readerError
  24. }
  25. reader, err := r.CreateReader()
  26. if err != nil {
  27. r.readerError = err
  28. return nil, err
  29. }
  30. r.reader = reader
  31. return reader, nil
  32. }
  33. func (r *LazyReader) Read(b []byte) (int, error) {
  34. reader, err := r.getReader()
  35. if err != nil {
  36. return 0, err
  37. }
  38. n, err := reader.Read(b)
  39. return n, err
  40. }