You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

range.go 1.3 kB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. package io2
  2. import (
  3. "io"
  4. "gitlink.org.cn/cloudream/common/utils/math2"
  5. )
  6. type rng struct {
  7. offset int64
  8. length *int64
  9. inner io.ReadCloser
  10. err error
  11. }
  12. func (r *rng) Read(p []byte) (n int, err error) {
  13. if r.err != nil {
  14. return 0, r.err
  15. }
  16. if r.offset > 0 {
  17. buf := make([]byte, 1024*16)
  18. for r.offset > 0 {
  19. need := math2.Min(r.offset, int64(len(buf)))
  20. rd, err := r.inner.Read(buf[:need])
  21. if err != nil {
  22. r.err = err
  23. return 0, err
  24. }
  25. r.offset -= int64(rd)
  26. }
  27. }
  28. if r.length == nil {
  29. return r.inner.Read(p)
  30. }
  31. need := math2.Min(*r.length, int64(len(p)))
  32. rd, err := r.inner.Read(p[:need])
  33. if err != nil {
  34. r.err = err
  35. return rd, io.EOF
  36. }
  37. *r.length -= int64(rd)
  38. if *r.length == 0 {
  39. r.err = io.EOF
  40. }
  41. return rd, nil
  42. }
  43. func (r *rng) Close() error {
  44. r.err = io.ErrClosedPipe
  45. return r.inner.Close()
  46. }
  47. func NewRange(inner io.ReadCloser, offset int64, length *int64) io.ReadCloser {
  48. return &rng{
  49. offset: offset,
  50. length: length,
  51. inner: inner,
  52. }
  53. }
  54. func Ranged(inner io.ReadCloser, offset int64, length int64) io.ReadCloser {
  55. return &rng{
  56. offset: offset,
  57. length: &length,
  58. inner: inner,
  59. }
  60. }
  61. func Offset(inner io.ReadCloser, offset int64) io.ReadCloser {
  62. return &rng{
  63. offset: offset,
  64. inner: inner,
  65. }
  66. }