From ca1fe414218fc3880d1ac02f5ffcfe0225fa4eb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Ludwig?= Date: Tue, 12 Jan 2021 17:24:28 +0100 Subject: [PATCH] Add DirectoryListMode.shallowDirectories. Shallow iteration, returning only directories. DirectoryListMode is now defined using bit combinations for "recursive" and "directories-only". --- source/vibe/core/file.d | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/source/vibe/core/file.d b/source/vibe/core/file.d index 1acfded..cd0b55b 100644 --- a/source/vibe/core/file.d +++ b/source/vibe/core/file.d @@ -515,11 +515,13 @@ enum FileMode { enum DirectoryListMode { /// 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) - recursive, + recursive = 1<<0, /// Iterate only directories recursively (depth-first, pre-order) - recursiveDirectories, + recursiveDirectories = recursive | shallowDirectories, } @@ -948,7 +950,8 @@ private void performListDirectory(ListDirectoryRequest req) @trusted nothrow { 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) { @@ -1001,7 +1004,7 @@ private void performListDirectory(ListDirectoryRequest req) try req.channel.put(ListDirectoryData(fi, null)); catch (Exception e) return false; // channel got closed - if (req.spanMode != DirectoryListMode.shallow && fi.isDirectory) { + if (rec && fi.isDirectory) { if (fi.isSymlink && !req.followSymlinks) continue; try { @@ -1037,22 +1040,21 @@ private void performListDirectory(ListDirectoryRequest req) fi.name = de.d_name[0 .. zi].idup; fi.directory = path; + fi.hidden = de.d_name[0] == '.'; stat_t st; - if (fstatat(dfd, fi.name.toStringz, &st, AT_SYMLINK_NOFOLLOW) != 0) - continue; + if (fstatat(dfd, fi.name.toStringz, &st, AT_SYMLINK_NOFOLLOW) == 0) { + 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 + if (fi.isSymlink) fstatat(dfd, fi.name.toStringz, &st, 0); - // apart from the symlink flag, get the rest of the information from the link target - if (fi.isSymlink) fstatat(dfd, fi.name.toStringz, &st, 0); - - fi.size = st.st_size; - fi.timeModified = timebase + st.st_mtime.seconds + (st.st_mtimensec / 100).hnsecs; - fi.timeCreated = timebase + st.st_ctime.seconds + (st.st_ctimensec / 100).hnsecs; - fi.isDirectory = S_ISDIR(st.st_mode); - fi.isFile = S_ISREG(st.st_mode); - fi.hidden = de.d_name[0] == '.'; + fi.size = st.st_size; + fi.timeModified = timebase + st.st_mtime.seconds + (st.st_mtimensec / 100).hnsecs; + fi.timeCreated = timebase + st.st_ctime.seconds + (st.st_ctimensec / 100).hnsecs; + fi.isDirectory = S_ISDIR(st.st_mode); + fi.isFile = S_ISREG(st.st_mode); + } // skip non-directories if requested if (dirs_only && !fi.isDirectory) @@ -1061,7 +1063,7 @@ private void performListDirectory(ListDirectoryRequest req) try req.channel.put(ListDirectoryData(fi, null)); catch (Exception e) return false; // channel got closed - if (req.spanMode != DirectoryListMode.shallow && fi.isDirectory) { + if (rec && fi.isDirectory) { if (fi.isSymlink && !req.followSymlinks) continue; try {