sectionwriter.go 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. package ioutil2
  2. import (
  3. "errors"
  4. "io"
  5. )
  6. var ErrExceedLimit = errors.New("write exceed limit")
  7. func NewSectionWriter(w io.WriterAt, off int64, n int64) *SectionWriter {
  8. return &SectionWriter{w, off, off, off + n}
  9. }
  10. type SectionWriter struct {
  11. w io.WriterAt
  12. base int64
  13. off int64
  14. limit int64
  15. }
  16. func (s *SectionWriter) Write(p []byte) (n int, err error) {
  17. if s.off >= s.limit {
  18. return 0, ErrExceedLimit
  19. }
  20. if max := s.limit - s.off; int64(len(p)) > max {
  21. return 0, ErrExceedLimit
  22. }
  23. n, err = s.w.WriteAt(p, s.off)
  24. s.off += int64(n)
  25. return
  26. }
  27. var errWhence = errors.New("Seek: invalid whence")
  28. var errOffset = errors.New("Seek: invalid offset")
  29. func (s *SectionWriter) Seek(offset int64, whence int) (int64, error) {
  30. switch whence {
  31. default:
  32. return 0, errWhence
  33. case 0:
  34. offset += s.base
  35. case 1:
  36. offset += s.off
  37. case 2:
  38. offset += s.limit
  39. }
  40. if offset < s.base {
  41. return 0, errOffset
  42. }
  43. s.off = offset
  44. return offset - s.base, nil
  45. }
  46. func (s *SectionWriter) WriteAt(p []byte, off int64) (n int, err error) {
  47. if off < 0 || off >= s.limit-s.base {
  48. return 0, errOffset
  49. }
  50. off += s.base
  51. if max := s.limit - off; int64(len(p)) > max {
  52. return 0, ErrExceedLimit
  53. }
  54. return s.w.WriteAt(p, off)
  55. }
  56. // Size returns the size of the section in bytes.
  57. func (s *SectionWriter) Size() int64 { return s.limit - s.base }