forked from TrueCloudLab/restic
92 lines
1.8 KiB
Go
92 lines
1.8 KiB
Go
package rofs
|
|
|
|
import (
|
|
"io"
|
|
"io/fs"
|
|
"slices"
|
|
|
|
"github.com/restic/restic/internal/debug"
|
|
)
|
|
|
|
// dirEntry holds data for a file or directory.
|
|
type dirEntry struct {
|
|
fileInfo fs.FileInfo
|
|
}
|
|
|
|
var _ fs.DirEntry = dirEntry{}
|
|
|
|
func (d dirEntry) Name() string { return d.fileInfo.Name() }
|
|
func (d dirEntry) IsDir() bool { return d.fileInfo.IsDir() }
|
|
func (d dirEntry) Type() fs.FileMode { return d.fileInfo.Mode().Type() }
|
|
func (d dirEntry) Info() (fs.FileInfo, error) { return d.fileInfo, nil }
|
|
|
|
// openDir represents a directory opened for reading.
|
|
type openDir struct {
|
|
path string
|
|
fileInfo fileInfo
|
|
entries []fs.DirEntry
|
|
offset int
|
|
}
|
|
|
|
var _ fs.ReadDirFile = &openDir{}
|
|
|
|
func (d *openDir) Close() error {
|
|
debug.Log("Close(%v)", d.path)
|
|
return nil
|
|
}
|
|
|
|
func (d *openDir) Stat() (fs.FileInfo, error) {
|
|
debug.Log("Stat(%v)", d.path)
|
|
return d.fileInfo, nil
|
|
}
|
|
|
|
func (d *openDir) Read([]byte) (int, error) {
|
|
return 0, &fs.PathError{Op: "read", Path: d.path, Err: fs.ErrInvalid}
|
|
}
|
|
|
|
func (d *openDir) ReadDir(count int) ([]fs.DirEntry, error) {
|
|
n := len(d.entries) - d.offset
|
|
|
|
if n == 0 && count > 0 {
|
|
debug.Log("ReadDir(%v, %v) -> EOF", d.path, count)
|
|
|
|
return nil, io.EOF
|
|
}
|
|
|
|
if count > 0 && n > count {
|
|
n = count
|
|
}
|
|
|
|
list := make([]fs.DirEntry, 0, n)
|
|
for i := 0; i < n; i++ {
|
|
list = append(list, d.entries[d.offset+i])
|
|
}
|
|
|
|
d.offset += n
|
|
|
|
debug.Log("ReadDir(%v, %v) -> %v entries", d.path, count, len(list))
|
|
|
|
return list, nil
|
|
}
|
|
|
|
func dirMap2DirEntry(m map[string]rofsEntry) []fs.DirEntry {
|
|
list := make([]fs.DirEntry, 0, len(m))
|
|
|
|
for _, entry := range m {
|
|
list = append(list, entry.DirEntry())
|
|
}
|
|
|
|
slices.SortFunc(list, func(a, b fs.DirEntry) int {
|
|
if a.Name() == b.Name() {
|
|
return 0
|
|
}
|
|
|
|
if a.Name() < b.Name() {
|
|
return -1
|
|
}
|
|
|
|
return 1
|
|
})
|
|
|
|
return list
|
|
}
|