2018-10-11 18:15:12 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2024-03-18 12:42:19 +00:00
|
|
|
"errors"
|
|
|
|
"fmt"
|
2018-10-11 18:15:12 +00:00
|
|
|
"io"
|
|
|
|
)
|
|
|
|
|
|
|
|
type progressSeeker struct {
|
|
|
|
Size int64
|
|
|
|
Progress int64
|
|
|
|
|
2024-03-18 12:42:19 +00:00
|
|
|
next io.ReadSeeker
|
2018-10-11 18:15:12 +00:00
|
|
|
}
|
|
|
|
|
2024-03-18 12:42:19 +00:00
|
|
|
func newProgressSeeker(next io.ReadSeeker) (*progressSeeker, error) {
|
|
|
|
lastByte, err := next.Seek(0, io.SeekEnd)
|
2018-10-11 18:15:12 +00:00
|
|
|
if err != nil {
|
2024-03-18 12:42:19 +00:00
|
|
|
return nil, fmt.Errorf("seeking end of reader: %w", err)
|
2018-10-11 18:15:12 +00:00
|
|
|
}
|
|
|
|
|
2024-03-18 12:42:19 +00:00
|
|
|
if _, err := next.Seek(0, io.SeekStart); err != nil {
|
|
|
|
return nil, fmt.Errorf("seeking start of reader: %w", err)
|
2018-10-11 18:15:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return &progressSeeker{
|
2024-03-18 12:42:19 +00:00
|
|
|
next: next,
|
|
|
|
Size: lastByte,
|
2018-10-11 18:15:12 +00:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *progressSeeker) Read(o []byte) (n int, err error) {
|
2024-03-18 12:42:19 +00:00
|
|
|
i, err := p.next.Read(o)
|
|
|
|
if err != nil {
|
|
|
|
if errors.Is(err, io.EOF) {
|
|
|
|
return i, io.EOF
|
|
|
|
}
|
|
|
|
return i, fmt.Errorf("reading next reader: %w", err)
|
|
|
|
}
|
2018-10-11 18:15:12 +00:00
|
|
|
|
|
|
|
p.Progress += int64(i)
|
|
|
|
|
2024-03-18 12:42:19 +00:00
|
|
|
return i, nil
|
2018-10-11 18:15:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (p *progressSeeker) Seek(offset int64, whence int) (int64, error) {
|
2024-03-18 12:42:19 +00:00
|
|
|
pos, err := p.next.Seek(offset, whence)
|
|
|
|
if err != nil {
|
|
|
|
return pos, fmt.Errorf("seeking next reader: %w", err)
|
2018-10-11 18:15:12 +00:00
|
|
|
}
|
|
|
|
|
2024-03-18 12:42:19 +00:00
|
|
|
p.Progress = pos
|
|
|
|
return pos, nil
|
2018-10-11 18:15:12 +00:00
|
|
|
}
|