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

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  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. *r.length -= int64(rd)
  34. if *r.length == 0 {
  35. r.err = io.EOF
  36. }
  37. if err == nil {
  38. return rd, nil
  39. }
  40. if err != io.EOF {
  41. r.err = err
  42. return rd, err
  43. }
  44. r.err = io.EOF
  45. return rd, nil
  46. }
  47. func (r *rng) Close() error {
  48. r.err = io.ErrClosedPipe
  49. return r.inner.Close()
  50. }
  51. func NewRange(inner io.ReadCloser, offset int64, length *int64) io.ReadCloser {
  52. return &rng{
  53. offset: offset,
  54. length: length,
  55. inner: inner,
  56. }
  57. }
  58. func Ranged(inner io.ReadCloser, offset int64, length int64) io.ReadCloser {
  59. return &rng{
  60. offset: offset,
  61. length: &length,
  62. inner: inner,
  63. }
  64. }
  65. func Offset(inner io.ReadCloser, offset int64) io.ReadCloser {
  66. return &rng{
  67. offset: offset,
  68. inner: inner,
  69. }
  70. }