/
reuseable_reader.go
45 lines (39 loc) · 1.28 KB
/
reuseable_reader.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package mockhttp
import (
"bytes"
"io"
)
// reusableReader is a custom type implementing the io.Reader interface, enhancing it with
// the ability to reset and re-read the underlying data efficiently.
type reusableReader struct {
io.Reader
readBuf *bytes.Buffer
backBuf *bytes.Buffer
}
// ReusableReader creates and returns a new reusableReader based on the provided io.Reader.
// The reusableReader allows for multiple reads of the same data efficiently.
func ReusableReader(r io.Reader) io.Reader {
readBuf := bytes.Buffer{}
readBuf.ReadFrom(r) // error handling ignored for brevity
backBuf := bytes.Buffer{}
return reusableReader{
io.TeeReader(&readBuf, &backBuf),
&readBuf,
&backBuf,
}
}
// Read reads data into the provided byte slice and returns the number of bytes read.
// If the end of the underlying data is reached (io.EOF), it automatically resets the reader for
// subsequent reads.
func (r reusableReader) Read(p []byte) (int, error) {
n, err := r.Reader.Read(p)
if err == io.EOF {
r.reset()
}
return n, err
}
// reset rewinds the reusableReader by copying the captured data from the backup buffer
// back to the main read buffer, allowing for the underlying data to be read again.
func (r reusableReader) reset() {
io.Copy(r.readBuf, r.backBuf) // nolint: errcheck
}