utils_io.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. // Copyright 2020 gf Author(https://github.com/gogf/gf). All Rights Reserved.
  2. //
  3. // This Source Code Form is subject to the terms of the MIT License.
  4. // If a copy of the MIT was not distributed with this file,
  5. // You can obtain one at https://github.com/gogf/gf.
  6. package utils
  7. import (
  8. "io"
  9. "io/ioutil"
  10. )
  11. // ReadCloser implements the io.ReadCloser interface
  12. // which is used for reading request body content multiple times.
  13. //
  14. // Note that it cannot be closed.
  15. type ReadCloser struct {
  16. index int // Current read position.
  17. content []byte // Content.
  18. repeatable bool
  19. }
  20. // NewRepeatReadCloser creates and returns a RepeatReadCloser object.
  21. func NewReadCloser(content []byte, repeatable bool) io.ReadCloser {
  22. return &ReadCloser{
  23. content: content,
  24. repeatable: repeatable,
  25. }
  26. }
  27. // NewRepeatReadCloserWithReadCloser creates and returns a RepeatReadCloser object
  28. // with given io.ReadCloser.
  29. func NewReadCloserWithReadCloser(r io.ReadCloser, repeatable bool) (io.ReadCloser, error) {
  30. content, err := ioutil.ReadAll(r)
  31. if err != nil {
  32. return nil, err
  33. }
  34. defer r.Close()
  35. return &ReadCloser{
  36. content: content,
  37. repeatable: repeatable,
  38. }, nil
  39. }
  40. // Read implements the io.ReadCloser interface.
  41. func (b *ReadCloser) Read(p []byte) (n int, err error) {
  42. n = copy(p, b.content[b.index:])
  43. b.index += n
  44. if b.index >= len(b.content) {
  45. // Make it repeatable reading.
  46. if b.repeatable {
  47. b.index = 0
  48. }
  49. return n, io.EOF
  50. }
  51. return n, nil
  52. }
  53. // Close implements the io.ReadCloser interface.
  54. func (b *ReadCloser) Close() error {
  55. return nil
  56. }