Add DirectoryListMode.shallowDirectories.

Shallow iteration, returning only directories. DirectoryListMode is now defined using bit combinations for "recursive" and "directories-only".
This commit is contained in:
Sönke Ludwig 2021-01-12 17:24:28 +01:00
parent d1273ca08b
commit ca1fe41421

View file

@ -515,11 +515,13 @@ enum FileMode {
enum DirectoryListMode { enum DirectoryListMode {
/// Only iterate the directory itself /// Only iterate the directory itself
shallow, shallow = 0,
/// Only iterate over directories directly within the given directory
shallowDirectories = 1<<1,
/// Iterate recursively (depth-first, pre-order) /// Iterate recursively (depth-first, pre-order)
recursive, recursive = 1<<0,
/// Iterate only directories recursively (depth-first, pre-order) /// Iterate only directories recursively (depth-first, pre-order)
recursiveDirectories, recursiveDirectories = recursive | shallowDirectories,
} }
@ -948,7 +950,8 @@ private void performListDirectory(ListDirectoryRequest req)
@trusted nothrow { @trusted nothrow {
scope (exit) req.channel.close(); scope (exit) req.channel.close();
auto dirs_only = req.spanMode == DirectoryListMode.recursiveDirectories; auto dirs_only = !!(req.spanMode & DirectoryListMode.shallowDirectories);
auto rec = !!(req.spanMode & DirectoryListMode.recursive);
bool scanRec(NativePath path) bool scanRec(NativePath path)
{ {
@ -1001,7 +1004,7 @@ private void performListDirectory(ListDirectoryRequest req)
try req.channel.put(ListDirectoryData(fi, null)); try req.channel.put(ListDirectoryData(fi, null));
catch (Exception e) return false; // channel got closed catch (Exception e) return false; // channel got closed
if (req.spanMode != DirectoryListMode.shallow && fi.isDirectory) { if (rec && fi.isDirectory) {
if (fi.isSymlink && !req.followSymlinks) if (fi.isSymlink && !req.followSymlinks)
continue; continue;
try { try {
@ -1037,11 +1040,10 @@ private void performListDirectory(ListDirectoryRequest req)
fi.name = de.d_name[0 .. zi].idup; fi.name = de.d_name[0 .. zi].idup;
fi.directory = path; fi.directory = path;
fi.hidden = de.d_name[0] == '.';
stat_t st; stat_t st;
if (fstatat(dfd, fi.name.toStringz, &st, AT_SYMLINK_NOFOLLOW) != 0) if (fstatat(dfd, fi.name.toStringz, &st, AT_SYMLINK_NOFOLLOW) == 0) {
continue;
fi.isSymlink = S_ISLNK(st.st_mode); fi.isSymlink = S_ISLNK(st.st_mode);
// apart from the symlink flag, get the rest of the information from the link target // apart from the symlink flag, get the rest of the information from the link target
@ -1052,7 +1054,7 @@ private void performListDirectory(ListDirectoryRequest req)
fi.timeCreated = timebase + st.st_ctime.seconds + (st.st_ctimensec / 100).hnsecs; fi.timeCreated = timebase + st.st_ctime.seconds + (st.st_ctimensec / 100).hnsecs;
fi.isDirectory = S_ISDIR(st.st_mode); fi.isDirectory = S_ISDIR(st.st_mode);
fi.isFile = S_ISREG(st.st_mode); fi.isFile = S_ISREG(st.st_mode);
fi.hidden = de.d_name[0] == '.'; }
// skip non-directories if requested // skip non-directories if requested
if (dirs_only && !fi.isDirectory) if (dirs_only && !fi.isDirectory)
@ -1061,7 +1063,7 @@ private void performListDirectory(ListDirectoryRequest req)
try req.channel.put(ListDirectoryData(fi, null)); try req.channel.put(ListDirectoryData(fi, null));
catch (Exception e) return false; // channel got closed catch (Exception e) return false; // channel got closed
if (req.spanMode != DirectoryListMode.shallow && fi.isDirectory) { if (rec && fi.isDirectory) {
if (fi.isSymlink && !req.followSymlinks) if (fi.isSymlink && !req.followSymlinks)
continue; continue;
try { try {