reader.go 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. package io
  2. import (
  3. "io"
  4. "v2ray.com/core/common"
  5. "v2ray.com/core/common/alloc"
  6. )
  7. // Reader extends io.Reader with alloc.Buffer.
  8. type Reader interface {
  9. common.Releasable
  10. // Read reads content from underlying reader, and put it into an alloc.Buffer.
  11. Read() (*alloc.Buffer, error)
  12. }
  13. // AdaptiveReader is a Reader that adjusts its reading speed automatically.
  14. type AdaptiveReader struct {
  15. reader io.Reader
  16. largeBuffer *alloc.Buffer
  17. highVolumn bool
  18. }
  19. // NewAdaptiveReader creates a new AdaptiveReader.
  20. // The AdaptiveReader instance doesn't take the ownership of reader.
  21. func NewAdaptiveReader(reader io.Reader) *AdaptiveReader {
  22. return &AdaptiveReader{
  23. reader: reader,
  24. }
  25. }
  26. // Read implements Reader.Read().
  27. func (v *AdaptiveReader) Read() (*alloc.Buffer, error) {
  28. if v.highVolumn && v.largeBuffer.IsEmpty() {
  29. if v.largeBuffer == nil {
  30. v.largeBuffer = alloc.NewLocalBuffer(256 * 1024).Clear()
  31. }
  32. nBytes, err := v.largeBuffer.FillFrom(v.reader)
  33. if err != nil {
  34. return nil, err
  35. }
  36. if nBytes < alloc.BufferSize {
  37. v.highVolumn = false
  38. }
  39. }
  40. buffer := alloc.NewBuffer().Clear()
  41. if !v.largeBuffer.IsEmpty() {
  42. buffer.FillFrom(v.largeBuffer)
  43. return buffer, nil
  44. }
  45. _, err := buffer.FillFrom(v.reader)
  46. if err != nil {
  47. buffer.Release()
  48. return nil, err
  49. }
  50. if buffer.IsFull() {
  51. v.highVolumn = true
  52. }
  53. return buffer, nil
  54. }
  55. func (v *AdaptiveReader) Release() {
  56. v.reader = nil
  57. }