bufreader.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. package bufreader
  2. import (
  3. "bufio"
  4. "bytes"
  5. "io"
  6. "github.com/imgproxy/imgproxy/v3/imath"
  7. )
  8. type Reader struct {
  9. r io.Reader
  10. buf *bytes.Buffer
  11. cur int
  12. }
  13. func New(r io.Reader, buf *bytes.Buffer) *Reader {
  14. br := Reader{
  15. r: r,
  16. buf: buf,
  17. }
  18. return &br
  19. }
  20. func (br *Reader) Read(p []byte) (int, error) {
  21. if err := br.fill(br.cur + len(p)); err != nil {
  22. return 0, err
  23. }
  24. n := copy(p, br.buf.Bytes()[br.cur:])
  25. br.cur += n
  26. return n, nil
  27. }
  28. func (br *Reader) ReadByte() (byte, error) {
  29. if err := br.fill(br.cur + 1); err != nil {
  30. return 0, err
  31. }
  32. b := br.buf.Bytes()[br.cur]
  33. br.cur++
  34. return b, nil
  35. }
  36. func (br *Reader) Discard(n int) (int, error) {
  37. if n < 0 {
  38. return 0, bufio.ErrNegativeCount
  39. }
  40. if n == 0 {
  41. return 0, nil
  42. }
  43. if err := br.fill(br.cur + n); err != nil {
  44. return 0, err
  45. }
  46. n = imath.Min(n, br.buf.Len()-br.cur)
  47. br.cur += n
  48. return n, nil
  49. }
  50. func (br *Reader) Peek(n int) ([]byte, error) {
  51. if n < 0 {
  52. return []byte{}, bufio.ErrNegativeCount
  53. }
  54. if n == 0 {
  55. return []byte{}, nil
  56. }
  57. if err := br.fill(br.cur + n); err != nil {
  58. return []byte{}, err
  59. }
  60. if n > br.buf.Len()-br.cur {
  61. return br.buf.Bytes()[br.cur:], io.EOF
  62. }
  63. return br.buf.Bytes()[br.cur : br.cur+n], nil
  64. }
  65. func (br *Reader) Flush() error {
  66. _, err := br.buf.ReadFrom(br.r)
  67. return err
  68. }
  69. func (br *Reader) fill(need int) error {
  70. n := need - br.buf.Len()
  71. if n <= 0 {
  72. return nil
  73. }
  74. n = imath.Max(4096, n)
  75. if _, err := br.buf.ReadFrom(io.LimitReader(br.r, int64(n))); err != nil {
  76. return err
  77. }
  78. // Nothing was read, it's EOF
  79. if br.cur == br.buf.Len() {
  80. return io.EOF
  81. }
  82. return nil
  83. }