Added a generic ReaderAt
This commit is contained in:
parent
e61bf67b85
commit
c0603b1c30
@ -3,6 +3,7 @@
|
|||||||
package cursor
|
package cursor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -32,6 +33,26 @@ type Cursor[Datum any] interface {
|
|||||||
At(pos uint64) Cursor[Datum]
|
At(pos uint64) Cursor[Datum]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ReaderAt[T any] interface {
|
||||||
|
ReadAt(p []T, off int64) (n int, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type SliceReaderAt[T any] []T
|
||||||
|
|
||||||
|
func (s SliceReaderAt[T]) ReadAt(dst []T, off int64) (n int, err error) {
|
||||||
|
if off < 0 {
|
||||||
|
return 0, errors.New("SliceReaderAt.ReadAt: negative offset")
|
||||||
|
}
|
||||||
|
if off >= int64(len(s)) {
|
||||||
|
return 0, io.EOF
|
||||||
|
}
|
||||||
|
n = copy(dst, s[off:])
|
||||||
|
if n < len(dst) {
|
||||||
|
err = io.EOF
|
||||||
|
}
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
type SliceCursor[Datum any] struct {
|
type SliceCursor[Datum any] struct {
|
||||||
data []Datum
|
data []Datum
|
||||||
offset uint64
|
offset uint64
|
||||||
@ -66,16 +87,16 @@ func (sc SliceCursor[Datum]) At(pos uint64) Cursor[Datum] {
|
|||||||
return sc
|
return sc
|
||||||
}
|
}
|
||||||
|
|
||||||
type ReaderAtCursor struct {
|
type ReaderAtCursor[T any] struct {
|
||||||
r io.ReaderAt
|
r ReaderAt[T]
|
||||||
pos uint64
|
pos uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewReaderAt(r io.ReaderAt) ReaderAtCursor {
|
func NewReaderAt[T any](r ReaderAt[T]) ReaderAtCursor[T] {
|
||||||
return ReaderAtCursor{r: r}
|
return ReaderAtCursor[T]{r: r}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rac ReaderAtCursor) Read(dst []byte) (uint64, Cursor[byte], error) {
|
func (rac ReaderAtCursor[T]) Read(dst []T) (uint64, Cursor[T], error) {
|
||||||
n, err := rac.r.ReadAt(dst, int64(rac.pos))
|
n, err := rac.r.ReadAt(dst, int64(rac.pos))
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
rac.pos += uint64(n)
|
rac.pos += uint64(n)
|
||||||
@ -83,11 +104,11 @@ func (rac ReaderAtCursor) Read(dst []byte) (uint64, Cursor[byte], error) {
|
|||||||
return uint64(n), rac, err
|
return uint64(n), rac, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rac ReaderAtCursor) Pos() uint64 {
|
func (rac ReaderAtCursor[T]) Pos() uint64 {
|
||||||
return rac.pos
|
return rac.pos
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rac ReaderAtCursor) At(pos uint64) Cursor[byte] {
|
func (rac ReaderAtCursor[T]) At(pos uint64) Cursor[T] {
|
||||||
rac.pos = pos
|
rac.pos = pos
|
||||||
return rac
|
return rac
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@ func TestSliceCursor(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestReaderAtCursor(t *testing.T) {
|
func TestReaderAtCursor(t *testing.T) {
|
||||||
testCursor(t, func(b []byte) cursor.ReaderAtCursor {
|
testCursor(t, func(b []byte) cursor.ReaderAtCursor[byte] {
|
||||||
return cursor.NewReaderAt(bytes.NewReader(b))
|
return cursor.NewReaderAt(bytes.NewReader(b))
|
||||||
})
|
})
|
||||||
t.Run("Read returns an error if the ReaderAt fails", rapid.MakeCheck(func(t *rapid.T) {
|
t.Run("Read returns an error if the ReaderAt fails", rapid.MakeCheck(func(t *rapid.T) {
|
||||||
|
Loading…
Reference in New Issue
Block a user