Skip to content
This repository was archived by the owner on Aug 22, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions pkging/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ type File interface {
// 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.
Read(p []byte) (int, error)

// ReadAt implements the ReadAt interface for File
// (reads len(b) bytes from the File starting at byte offset off.
// It returns the number of bytes read and the error, if any.
// ReadAt always returns a non-nil error when n < len(b).
// At end of file, that error is io.EOF)
ReadAt(p []byte, offset int64) (int, error)

// 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.
//
// 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.
Expand Down
15 changes: 15 additions & 0 deletions pkging/mem/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,21 @@ func (f *File) Read(p []byte) (int, error) {
return 0, fmt.Errorf("unable to read %s", f.Name())
}

// ReadAt implements the ReadAt interface for File
// (reads len(b) bytes from the File starting at byte offset off.
// It returns the number of bytes read and the error, if any.
// ReadAt always returns a non-nil error when n < len(b).
// At end of file, that error is io.EOF)
func (f *File) ReadAt(p []byte, offset int64) (int, error) {
if len(f.data) == 0 || offset >= int64(len(f.data)) {
return 0, io.EOF
}

f.reader = bytes.NewReader(f.data[offset:])

return f.reader.Read(p)
}

// 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).
func (f *File) Write(b []byte) (int, error) {
if f.writer == nil {
Expand Down
26 changes: 26 additions & 0 deletions pkging/mem/file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,29 @@ func Test_File_Seek(t *testing.T) {
r.NotEqual(data, b)
r.Equal([]byte("the arm"), b)
}

func TestFileReadAt(t *testing.T) {
r := require.New(t)

info, err := here.Current()
r.NoError(err)

pkg, err := New(info)
r.NoError(err)

f, err := pkg.Create(":/tolstoy")
r.NoError(err)

data := []byte("pierre always loved natasha")
f.Write(data)
r.NoError(f.Close())

f, err = pkg.Open(":/tolstoy")
r.NoError(err)

b := make([]byte, len(data))
read, err := f.ReadAt(b, 7)
r.NoError(err)
r.Equal("always loved natasha", string(b[:read]))
r.Equal(read, len(data[7:]))
}