Skip to content

Commit a3a0a4c

Browse files
Merge pull request #365 from teo-tsirpanis/vfsfh-readat
Add `VFSfh.ReadAt`.
2 parents 1ed8dab + eb12a3d commit a3a0a4c

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

Diff for: vfs.go

+41
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,47 @@ func (v *VFSfh) Read(p []byte) (int, error) {
522522
return int(nbytes), nil
523523
}
524524

525+
// ReadAt reads part of a file at a given offset, without updating the object's internal offset.
526+
func (v *VFSfh) ReadAt(p []byte, off int64) (int, error) {
527+
if off < 0 {
528+
return 0, errors.New("offset cannot be negative")
529+
}
530+
531+
nbytes := uint64(len(p))
532+
533+
// If the size is empty, fetch it
534+
if v.size == nil {
535+
err := v.fetchAndSetSize()
536+
if err != nil {
537+
return 0, err
538+
}
539+
}
540+
541+
// If the requested read size is beyond the limit, truncate the read size.
542+
// In this case we need to return io.EOF.
543+
var err error = nil
544+
if uint64(off)+nbytes >= *v.size {
545+
if uint64(off) > *v.size {
546+
return 0, io.EOF
547+
}
548+
nbytes = *v.size - uint64(off)
549+
err = io.EOF
550+
}
551+
552+
if nbytes == 0 {
553+
return 0, err
554+
}
555+
556+
cbuffer := slicePtr(p)
557+
ret := C.tiledb_vfs_read(v.context.tiledbContext, v.tiledbVFSfh, C.uint64_t(off), cbuffer, C.uint64_t(nbytes))
558+
559+
if ret != C.TILEDB_OK {
560+
return 0, fmt.Errorf("unknown error in VFS.Read: %w", v.context.LastError())
561+
}
562+
563+
return int(nbytes), err
564+
}
565+
525566
// Write writes the contents of a buffer into a file. Note that this function only
526567
// appends data at the end of the file. If the file does not exist,
527568
// it will be created.

Diff for: vfs_test.go

+22
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,28 @@ func TestVFSFH(t *testing.T) {
155155
assert.Equal(t, 3, n)
156156
require.NoError(t, err)
157157
assert.ElementsMatch(t, b, bRead)
158+
// Check value of offset.
159+
noffset, err = r.Seek(0, io.SeekCurrent)
160+
require.NoError(t, err)
161+
assert.EqualValues(t, 3, noffset)
162+
163+
n, err = r.ReadAt(bRead, 0)
164+
require.Equal(t, io.EOF, err)
165+
assert.EqualValues(t, 3, n)
166+
assert.ElementsMatch(t, b, bRead)
167+
// Check that offset was not changed.
168+
noffset, err = r.Seek(0, io.SeekCurrent)
169+
require.NoError(t, err)
170+
assert.EqualValues(t, 3, noffset)
171+
172+
n, err = r.ReadAt(bRead[:1], 0)
173+
require.NoError(t, err)
174+
assert.EqualValues(t, 1, n)
175+
assert.Equal(t, b[0], bRead[0])
176+
// Check that offset was not changed.
177+
noffset, err = r.Seek(0, io.SeekCurrent)
178+
require.NoError(t, err)
179+
assert.EqualValues(t, 3, noffset)
158180

159181
n, err = r.Read(bRead)
160182
assert.Error(t, err)

0 commit comments

Comments
 (0)