102 lines
1.6 KiB
Go
102 lines
1.6 KiB
Go
package ctxio
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
"sync"
|
|
)
|
|
|
|
type ioSeekerWrapper struct {
|
|
ctx context.Context
|
|
|
|
mu sync.Mutex
|
|
pos int64
|
|
size int64
|
|
|
|
r ReaderAt
|
|
}
|
|
|
|
func IoReadSeekerWrapper(ctx context.Context, r ReaderAt, size int64) io.ReadSeeker {
|
|
return &ioSeekerWrapper{
|
|
ctx: ctx,
|
|
r: r,
|
|
size: size,
|
|
}
|
|
}
|
|
|
|
func (r *ioSeekerWrapper) Seek(offset int64, whence int) (int64, error) {
|
|
r.mu.Lock()
|
|
defer r.mu.Unlock()
|
|
|
|
switch whence {
|
|
case io.SeekStart:
|
|
r.pos = offset
|
|
case io.SeekCurrent:
|
|
r.pos = r.pos + offset
|
|
case io.SeekEnd:
|
|
r.pos = r.size + offset
|
|
}
|
|
|
|
return r.pos, nil
|
|
}
|
|
|
|
func (r *ioSeekerWrapper) Read(p []byte) (int, error) {
|
|
r.mu.Lock()
|
|
defer r.mu.Unlock()
|
|
|
|
n, err := r.r.ReadAt(r.ctx, p, r.pos)
|
|
r.pos += int64(n)
|
|
|
|
return n, err
|
|
}
|
|
|
|
var _ io.ReadSeekCloser = (*ioSeekerCloserWrapper)(nil)
|
|
|
|
type ioSeekerCloserWrapper struct {
|
|
ctx context.Context
|
|
|
|
mu sync.Mutex
|
|
pos int64
|
|
size int64
|
|
|
|
r FileReader
|
|
}
|
|
|
|
func IoReadSeekCloserWrapper(ctx context.Context, r FileReader, size int64) io.ReadSeekCloser {
|
|
return &ioSeekerCloserWrapper{
|
|
ctx: ctx,
|
|
r: r,
|
|
size: size,
|
|
}
|
|
}
|
|
|
|
func (r *ioSeekerCloserWrapper) Seek(offset int64, whence int) (int64, error) {
|
|
r.mu.Lock()
|
|
defer r.mu.Unlock()
|
|
|
|
switch whence {
|
|
case io.SeekStart:
|
|
r.pos = offset
|
|
case io.SeekCurrent:
|
|
r.pos = r.pos + offset
|
|
case io.SeekEnd:
|
|
r.pos = r.size + offset
|
|
}
|
|
|
|
return r.pos, nil
|
|
}
|
|
|
|
func (r *ioSeekerCloserWrapper) Read(p []byte) (int, error) {
|
|
r.mu.Lock()
|
|
defer r.mu.Unlock()
|
|
|
|
n, err := r.r.ReadAt(r.ctx, p, r.pos)
|
|
r.pos += int64(n)
|
|
|
|
return n, err
|
|
}
|
|
|
|
// Close implements io.ReadSeekCloser.
|
|
func (r *ioSeekerCloserWrapper) Close() error {
|
|
return r.r.Close(r.ctx)
|
|
}
|