12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- package readers
- import (
- "errors"
- "fmt"
- "io"
- )
- // FakeSeeker adapts an io.Seeker into an io.ReadSeeker
- type FakeSeeker struct {
- in io.Reader
- readErr error
- length int64
- offset int64
- read bool
- }
- // NewFakeSeeker creates a fake io.ReadSeeker from an io.Reader
- //
- // This can be seeked before reading to discover the length passed in.
- func NewFakeSeeker(in io.Reader, length int64) io.ReadSeeker {
- if rs, ok := in.(io.ReadSeeker); ok {
- return rs
- }
- return &FakeSeeker{
- in: in,
- length: length,
- }
- }
- // Seek the stream - possible only before reading
- func (r *FakeSeeker) Seek(offset int64, whence int) (abs int64, err error) {
- if r.readErr != nil {
- return 0, r.readErr
- }
- if r.read {
- return 0, fmt.Errorf("FakeSeeker: can't Seek(%d, %d) after reading", offset, whence)
- }
- switch whence {
- case io.SeekStart:
- abs = offset
- case io.SeekCurrent:
- abs = r.offset + offset
- case io.SeekEnd:
- abs = r.length + offset
- default:
- return 0, errors.New("FakeSeeker: invalid whence")
- }
- if abs < 0 {
- return 0, errors.New("FakeSeeker: negative position")
- }
- r.offset = abs
- return abs, nil
- }
- // Read data from the stream. Will give an error if seeked.
- func (r *FakeSeeker) Read(p []byte) (n int, err error) {
- if r.readErr != nil {
- return 0, r.readErr
- }
- if !r.read && r.offset != 0 {
- return 0, errors.New("FakeSeeker: not at start: can't read")
- }
- n, err = r.in.Read(p)
- if n != 0 {
- r.read = true
- }
- if err != nil {
- r.readErr = err
- }
- return n, err
- }
|