summaryrefslogtreecommitdiff
path: root/zen/file_traverser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'zen/file_traverser.cpp')
-rw-r--r--zen/file_traverser.cpp42
1 files changed, 23 insertions, 19 deletions
diff --git a/zen/file_traverser.cpp b/zen/file_traverser.cpp
index 3eb284e1..ef6d255c 100644
--- a/zen/file_traverser.cpp
+++ b/zen/file_traverser.cpp
@@ -28,8 +28,8 @@ using namespace zen;
void zen::traverseFolder(const Zstring& dirPath,
const std::function<void (const FileInfo& fi)>& onFile,
- const std::function<void (const DirInfo& di)>& onDir,
- const std::function<void (const SymlinkInfo& si)>& onLink,
+ const std::function<void (const FolderInfo& fi)>& onFolder,
+ const std::function<void (const SymlinkInfo& si)>& onSymlink,
const std::function<void (const std::wstring& errorMsg)>& onError)
{
try
@@ -41,12 +41,15 @@ void zen::traverseFolder(const Zstring& dirPath,
{
const DWORD ec = ::GetLastError(); //copy before directly/indirectly making other system calls!
if (ec == ERROR_FILE_NOT_FOUND)
- {
- //1. directory may not exist *or* 2. it is completely empty: not all directories contain "., .." entries, e.g. a drive's root directory; NetDrive
- // -> FindFirstFile() is a nice example of violation of API design principle of single responsibility
- if (dirExists(dirPath)) //yes, a race-condition, still the best we can do
- return;
- }
+ try
+ {
+ //1. directory may not exist *or* 2. it is completely empty: not all directories contain "., .." entries, e.g. a drive's root directory; NetDrive
+ // -> FindFirstFile() is a nice example of violating the API design principle of single responsibility
+ if (getItemType(dirPath) == ItemType::FOLDER) //throw FileError
+ return;
+ }
+ catch (FileError&) {} //previous exception is more relevant
+
throw FileError(replaceCpy(_("Cannot open directory %x."), L"%x", fmtPath(dirPath)), formatSystemError(L"FindFirstFile", ec));
}
ZEN_ON_SCOPE_EXIT(::FindClose(hDir));
@@ -75,22 +78,23 @@ void zen::traverseFolder(const Zstring& dirPath,
if (itemNameRaw[0] == 0)
throw FileError(replaceCpy(_("Cannot read directory %x."), L"%x", fmtPath(dirPath)), L"FindNextFile: Data corruption; item with empty name.");
- const Zstring& itemPath = appendSeparator(dirPath) + itemNameRaw;
+ const Zstring& itemName = itemNameRaw;
+ const Zstring& itemPath = appendSeparator(dirPath) + itemName;
if (zen::isSymlink(findData)) //check first!
{
- if (onLink)
- onLink({ itemPath, filetimeToTimeT(findData.ftLastWriteTime) });
+ if (onSymlink)
+ onSymlink({ itemName, itemPath, filetimeToTimeT(findData.ftLastWriteTime) });
}
else if ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
{
- if (onDir)
- onDir({ itemPath });
+ if (onFolder)
+ onFolder({ itemName, itemPath });
}
else //a file
{
if (onFile)
- onFile({ itemPath, get64BitUInt(findData.nFileSizeLow, findData.nFileSizeHigh), filetimeToTimeT(findData.ftLastWriteTime) });
+ onFile({ itemName, itemPath, get64BitUInt(findData.nFileSizeLow, findData.nFileSizeHigh), filetimeToTimeT(findData.ftLastWriteTime) });
}
}
@@ -159,18 +163,18 @@ void zen::traverseFolder(const Zstring& dirPath,
if (S_ISLNK(statData.st_mode)) //on Linux there is no distinction between file and directory symlinks!
{
- if (onLink)
- onLink({ itemPath, statData.st_mtime});
+ if (onSymlink)
+ onSymlink({ itemName, itemPath, statData.st_mtime});
}
else if (S_ISDIR(statData.st_mode)) //a directory
{
- if (onDir)
- onDir({ itemPath });
+ if (onFolder)
+ onFolder({ itemName, itemPath });
}
else //a file or named pipe, ect.
{
if (onFile)
- onFile({ itemPath, makeUnsigned(statData.st_size), statData.st_mtime });
+ onFile({ itemName, itemPath, makeUnsigned(statData.st_size), statData.st_mtime });
}
/*
It may be a good idea to not check "S_ISREG(statData.st_mode)" explicitly and to not issue an error message on other types to support these scenarios:
bgstack15