Skip to content
This repository was archived by the owner on Aug 22, 2022. It is now read-only.

Commit a2c1679

Browse files
committed
implement reader at
1 parent d97c60c commit a2c1679

3 files changed

Lines changed: 48 additions & 0 deletions

File tree

pkging/file.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ type File interface {
2626
// Read reads up to len(b) bytes from the File. It returns the number of bytes read and any error encountered. At end of file, Read returns 0, io.EOF.
2727
Read(p []byte) (int, error)
2828

29+
// ReadAt implements the ReadAt interface for File
30+
// (reads len(b) bytes from the File starting at byte offset off.
31+
// It returns the number of bytes read and the error, if any.
32+
// ReadAt always returns a non-nil error when n < len(b).
33+
// At end of file, that error is io.EOF)
34+
ReadAt(p []byte, offset int64) (int, error);
35+
2936
// Readdir reads the contents of the directory associated with file and returns a slice of up to n FileInfo values, as would be returned by Lstat, in directory order. Subsequent calls on the same file will yield further FileInfos.
3037
//
3138
// If n > 0, Readdir returns at most n FileInfo structures. In this case, if Readdir returns an empty slice, it will return a non-nil error explaining why. At the end of a directory, the error is io.EOF.

pkging/mem/file.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,21 @@ func (f *File) Read(p []byte) (int, error) {
8181
return 0, fmt.Errorf("unable to read %s", f.Name())
8282
}
8383

84+
// ReadAt implements the ReadAt interface for File
85+
// (reads len(b) bytes from the File starting at byte offset off.
86+
// It returns the number of bytes read and the error, if any.
87+
// ReadAt always returns a non-nil error when n < len(b).
88+
// At end of file, that error is io.EOF)
89+
func (f *File) ReadAt(p []byte, offset int64) (int, error) {
90+
if len(f.data) == 0 || offset >= int64(len(f.data)) {
91+
return 0, io.EOF
92+
}
93+
94+
f.reader = bytes.NewReader(f.data[offset:])
95+
96+
return f.reader.Read(p)
97+
}
98+
8499
// Write writes len(b) bytes to the File. It returns the number of bytes written and an error, if any. Write returns a non-nil error when n != len(b).
85100
func (f *File) Write(b []byte) (int, error) {
86101
if f.writer == nil {

pkging/mem/file_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,29 @@ func Test_File_Seek(t *testing.T) {
6060
r.NotEqual(data, b)
6161
r.Equal([]byte("the arm"), b)
6262
}
63+
64+
func TestFileReadAt(t *testing.T) {
65+
r := require.New(t)
66+
67+
info, err := here.Current()
68+
r.NoError(err)
69+
70+
pkg, err := New(info)
71+
r.NoError(err)
72+
73+
f, err := pkg.Create(":/tolstoy")
74+
r.NoError(err)
75+
76+
data := []byte("pierre always loved natasha")
77+
f.Write(data)
78+
r.NoError(f.Close())
79+
80+
f, err = pkg.Open(":/tolstoy")
81+
r.NoError(err)
82+
83+
b := make([]byte, len(data))
84+
read, err := f.ReadAt(b, 7)
85+
r.NoError(err)
86+
r.Equal("always loved natasha", string(b[:read]))
87+
r.Equal(read, len(data[7:]))
88+
}

0 commit comments

Comments
 (0)