// OneByteReader returns a Reader that implements // each non-empty Read by reading one byte from r. func OneByteReader(r io.Reader) io.Reader { … } type oneByteReader … func (r *oneByteReader) Read(p []byte) (int, error) { … } // HalfReader returns a Reader that implements Read // by reading half as many requested bytes from r. func HalfReader(r io.Reader) io.Reader { … } type halfReader … func (r *halfReader) Read(p []byte) (int, error) { … } // DataErrReader changes the way errors are handled by a Reader. Normally, a // Reader returns an error (typically EOF) from the first Read call after the // last piece of data is read. DataErrReader wraps a Reader and changes its // behavior so the final error is returned along with the final data, instead // of in the first call after the final data. func DataErrReader(r io.Reader) io.Reader { … } type dataErrReader … func (r *dataErrReader) Read(p []byte) (n int, err error) { … } var ErrTimeout … // TimeoutReader returns [ErrTimeout] on the second read // with no data. Subsequent calls to read succeed. func TimeoutReader(r io.Reader) io.Reader { … } type timeoutReader … func (r *timeoutReader) Read(p []byte) (int, error) { … } // ErrReader returns an [io.Reader] that returns 0, err from all Read calls. func ErrReader(err error) io.Reader { … } type errReader … func (r *errReader) Read(p []byte) (int, error) { … } type smallByteReader … func (r *smallByteReader) Read(p []byte) (int, error) { … } // TestReader tests that reading from r returns the expected file content. // It does reads of different sizes, until EOF. // If r implements [io.ReaderAt] or [io.Seeker], TestReader also checks // that those operations behave as they should. // // If TestReader finds any misbehaviors, it returns an error reporting them. // The error text may span multiple lines. func TestReader(r io.Reader, content []byte) error { … }