github.com/10XDev/rclone@v1.52.3-0.20200626220027-16af9ab76b2a/vfs/dir_handle.go (about)

     1  package vfs
     2  
     3  import (
     4  	"io"
     5  	"os"
     6  )
     7  
     8  // DirHandle represents an open directory
     9  type DirHandle struct {
    10  	baseHandle
    11  	d   *Dir
    12  	fis []os.FileInfo // where Readdir got to
    13  }
    14  
    15  // newDirHandle opens a directory for read
    16  func newDirHandle(d *Dir) *DirHandle {
    17  	return &DirHandle{
    18  		d: d,
    19  	}
    20  }
    21  
    22  // String converts it to printable
    23  func (fh *DirHandle) String() string {
    24  	if fh == nil {
    25  		return "<nil *DirHandle>"
    26  	}
    27  	if fh.d == nil {
    28  		return "<nil *DirHandle.d>"
    29  	}
    30  	return fh.d.String() + " (r)"
    31  }
    32  
    33  // Stat returns info about the current directory
    34  func (fh *DirHandle) Stat() (fi os.FileInfo, err error) {
    35  	return fh.d, nil
    36  }
    37  
    38  // Node returns the Node assocuated with this - satisfies Noder interface
    39  func (fh *DirHandle) Node() Node {
    40  	return fh.d
    41  }
    42  
    43  // Readdir reads the contents of the directory associated with file and returns
    44  // a slice of up to n FileInfo values, as would be returned by Lstat, in
    45  // directory order. Subsequent calls on the same file will yield further
    46  // FileInfos.
    47  //
    48  // If n > 0, Readdir returns at most n FileInfo structures. In this case, if
    49  // Readdir returns an empty slice, it will return a non-nil error explaining
    50  // why. At the end of a directory, the error is io.EOF.
    51  //
    52  // If n <= 0, Readdir returns all the FileInfo from the directory in a single
    53  // slice. In this case, if Readdir succeeds (reads all the way to the end of
    54  // the directory), it returns the slice and a nil error. If it encounters an
    55  // error before the end of the directory, Readdir returns the FileInfo read
    56  // until that point and a non-nil error.
    57  func (fh *DirHandle) Readdir(n int) (fis []os.FileInfo, err error) {
    58  	if fh.fis == nil {
    59  		nodes, err := fh.d.ReadDirAll()
    60  		if err != nil {
    61  			return nil, err
    62  		}
    63  		fh.fis = []os.FileInfo{}
    64  		for _, node := range nodes {
    65  			fh.fis = append(fh.fis, node)
    66  		}
    67  	}
    68  	nn := len(fh.fis)
    69  	if n > 0 {
    70  		if nn == 0 {
    71  			return nil, io.EOF
    72  		}
    73  		if nn > n {
    74  			nn = n
    75  		}
    76  	}
    77  	fis, fh.fis = fh.fis[:nn], fh.fis[nn:]
    78  	return fis, nil
    79  }
    80  
    81  // Readdirnames reads and returns a slice of names from the directory f.
    82  //
    83  // If n > 0, Readdirnames returns at most n names. In this case, if
    84  // Readdirnames returns an empty slice, it will return a non-nil error
    85  // explaining why. At the end of a directory, the error is io.EOF.
    86  //
    87  // If n <= 0, Readdirnames returns all the names from the directory in a single
    88  // slice. In this case, if Readdirnames succeeds (reads all the way to the end
    89  // of the directory), it returns the slice and a nil error. If it encounters an
    90  // error before the end of the directory, Readdirnames returns the names read
    91  // until that point and a non-nil error.
    92  func (fh *DirHandle) Readdirnames(n int) (names []string, err error) {
    93  	nodes, err := fh.Readdir(n)
    94  	if err != nil {
    95  		return nil, err
    96  	}
    97  	for _, node := range nodes {
    98  		names = append(names, node.Name())
    99  	}
   100  	return names, nil
   101  }
   102  
   103  // Close closes the handle
   104  func (fh *DirHandle) Close() (err error) {
   105  	fh.fis = nil
   106  	return nil
   107  }