48 lines
1,002 B
Go
48 lines
1,002 B
Go
|
package ctxio
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"sync"
|
||
|
)
|
||
|
|
||
|
type ReaderReaderAtWrapper struct {
|
||
|
mu sync.Mutex
|
||
|
rat ReaderAt
|
||
|
offset int64
|
||
|
}
|
||
|
|
||
|
func NewReaderReaderAtWrapper(rat ReaderAt) *ReaderReaderAtWrapper {
|
||
|
return &ReaderReaderAtWrapper{
|
||
|
rat: rat,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var _ Reader = (*ReaderReaderAtWrapper)(nil)
|
||
|
var _ ReaderAt = (*ReaderReaderAtWrapper)(nil)
|
||
|
var _ Closer = (*ReaderReaderAtWrapper)(nil)
|
||
|
|
||
|
// Read implements Reader.
|
||
|
func (r *ReaderReaderAtWrapper) Read(ctx context.Context, p []byte) (n int, err error) {
|
||
|
r.mu.Lock()
|
||
|
defer r.mu.Unlock()
|
||
|
n, err = r.rat.ReadAt(ctx, p, r.offset)
|
||
|
r.offset += int64(n)
|
||
|
return n, err
|
||
|
}
|
||
|
|
||
|
// ReadAt implements ReaderAt.
|
||
|
func (r *ReaderReaderAtWrapper) ReadAt(ctx context.Context, p []byte, off int64) (n int, err error) {
|
||
|
return r.rat.ReadAt(ctx, p, off)
|
||
|
}
|
||
|
|
||
|
// Close implements Closer.
|
||
|
func (r *ReaderReaderAtWrapper) Close(ctx context.Context) (err error) {
|
||
|
if c, ok := r.rat.(Closer); ok {
|
||
|
err = c.Close(ctx)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
return nil
|
||
|
}
|