package vfs import ( "io" "os" ) // DirHandle represents an open directory type DirHandle struct { baseHandle d *Dir fis []os.FileInfo // where Readdir got to } // newDirHandle opens a directory for read func newDirHandle(d *Dir) *DirHandle { return &DirHandle{ d: d, } } // String converts it to printable func (fh *DirHandle) String() string { if fh == nil { return "" } if fh.d == nil { return "" } return fh.d.String() + " (r)" } // Stat returns info about the current directory func (fh *DirHandle) Stat() (fi os.FileInfo, err error) { return fh.d, nil } // Node returns the Node assocuated with this - satisfies Noder interface func (fh *DirHandle) Node() Node { return fh.d } // 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. // // If n <= 0, Readdir returns all the FileInfo from the directory in a single // slice. In this case, if Readdir succeeds (reads all the way to the end of // the directory), it returns the slice and a nil error. If it encounters an // error before the end of the directory, Readdir returns the FileInfo read // until that point and a non-nil error. func (fh *DirHandle) Readdir(n int) (fis []os.FileInfo, err error) { if fh.fis == nil { nodes, err := fh.d.ReadDirAll() if err != nil { return nil, err } fh.fis = []os.FileInfo{} for _, node := range nodes { fh.fis = append(fh.fis, node) } } nn := len(fh.fis) if n > 0 { if nn == 0 { return nil, io.EOF } if nn > n { nn = n } } fis, fh.fis = fh.fis[:nn], fh.fis[nn:] return fis, nil } // Readdirnames reads and returns a slice of names from the directory f. // // If n > 0, Readdirnames returns at most n names. In this case, if // Readdirnames returns an empty slice, it will return a non-nil error // explaining why. At the end of a directory, the error is io.EOF. // // If n <= 0, Readdirnames returns all the names from the directory in a single // slice. In this case, if Readdirnames succeeds (reads all the way to the end // of the directory), it returns the slice and a nil error. If it encounters an // error before the end of the directory, Readdirnames returns the names read // until that point and a non-nil error. func (fh *DirHandle) Readdirnames(n int) (names []string, err error) { nodes, err := fh.Readdir(n) if err != nil { return nil, err } for _, node := range nodes { names = append(names, node.Name()) } return names, nil } // Close closes the handle func (fh *DirHandle) Close() (err error) { fh.fis = nil return nil }