gitea源码

io.go 2.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // Copyright 2021 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package util
  4. import (
  5. "bytes"
  6. "errors"
  7. "io"
  8. )
  9. type NopCloser struct {
  10. io.Writer
  11. }
  12. func (NopCloser) Close() error { return nil }
  13. // ReadAtMost reads at most len(buf) bytes from r into buf.
  14. // It returns the number of bytes copied. n is only less than len(buf) if r provides fewer bytes.
  15. // If EOF or ErrUnexpectedEOF occurs while reading, err will be nil.
  16. func ReadAtMost(r io.Reader, buf []byte) (n int, err error) {
  17. n, err = io.ReadFull(r, buf)
  18. if err == io.EOF || err == io.ErrUnexpectedEOF {
  19. err = nil
  20. }
  21. return n, err
  22. }
  23. // ReadWithLimit reads at most "limit" bytes from r into buf.
  24. // If EOF or ErrUnexpectedEOF occurs while reading, err will be nil.
  25. func ReadWithLimit(r io.Reader, n int) (buf []byte, err error) {
  26. return readWithLimit(r, 1024, n)
  27. }
  28. func readWithLimit(r io.Reader, batch, limit int) ([]byte, error) {
  29. if limit <= batch {
  30. buf := make([]byte, limit)
  31. n, err := ReadAtMost(r, buf)
  32. if err != nil {
  33. return nil, err
  34. }
  35. return buf[:n], nil
  36. }
  37. res := bytes.NewBuffer(make([]byte, 0, batch))
  38. bufFix := make([]byte, batch)
  39. eof := false
  40. for res.Len() < limit && !eof {
  41. bufTmp := bufFix
  42. if res.Len()+batch > limit {
  43. bufTmp = bufFix[:limit-res.Len()]
  44. }
  45. n, err := io.ReadFull(r, bufTmp)
  46. if err == io.EOF || err == io.ErrUnexpectedEOF {
  47. eof = true
  48. } else if err != nil {
  49. return nil, err
  50. }
  51. if _, err = res.Write(bufTmp[:n]); err != nil {
  52. return nil, err
  53. }
  54. }
  55. return res.Bytes(), nil
  56. }
  57. // ErrNotEmpty is an error reported when there is a non-empty reader
  58. var ErrNotEmpty = errors.New("not-empty")
  59. // IsEmptyReader reads a reader and ensures it is empty
  60. func IsEmptyReader(r io.Reader) (err error) {
  61. var buf [1]byte
  62. for {
  63. n, err := r.Read(buf[:])
  64. if err != nil {
  65. if err == io.EOF {
  66. return nil
  67. }
  68. return err
  69. }
  70. if n > 0 {
  71. return ErrNotEmpty
  72. }
  73. }
  74. }
  75. type CountingReader struct {
  76. io.Reader
  77. n int
  78. }
  79. var _ io.Reader = &CountingReader{}
  80. func (w *CountingReader) Count() int {
  81. return w.n
  82. }
  83. func (w *CountingReader) Read(p []byte) (int, error) {
  84. n, err := w.Reader.Read(p)
  85. w.n += n
  86. return n, err
  87. }
  88. func NewCountingReader(rd io.Reader) *CountingReader {
  89. return &CountingReader{Reader: rd}
  90. }