aboutsummaryrefslogtreecommitdiff
path: root/src/zencore/filesystem.cpp
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2023-09-20 15:22:03 +0200
committerGitHub <[email protected]>2023-09-20 15:22:03 +0200
commit14d7568f9c7d970b7bbf7b6463a0a8530f98bb6f (patch)
treebf24ac15759385cea339f7e1cf5380f984f5699a /src/zencore/filesystem.cpp
parentchangelog version bump (diff)
downloadzen-14d7568f9c7d970b7bbf7b6463a0a8530f98bb6f.tar.xz
zen-14d7568f9c7d970b7bbf7b6463a0a8530f98bb6f.zip
VFS implementation for local storage service (#396)
currently, only Windows (using Projected File System) is supported
Diffstat (limited to 'src/zencore/filesystem.cpp')
-rw-r--r--src/zencore/filesystem.cpp75
1 files changed, 67 insertions, 8 deletions
diff --git a/src/zencore/filesystem.cpp b/src/zencore/filesystem.cpp
index b1ec14a37..e9f7ba72c 100644
--- a/src/zencore/filesystem.cpp
+++ b/src/zencore/filesystem.cpp
@@ -92,7 +92,7 @@ CreateDirectories(const wchar_t* Dir)
// behind
static bool
-WipeDirectory(const wchar_t* DirPath)
+WipeDirectory(const wchar_t* DirPath, bool KeepDotFiles)
{
ExtendableWideStringBuilder<128> Pattern;
Pattern.Append(DirPath);
@@ -107,7 +107,7 @@ WipeDirectory(const wchar_t* DirPath)
{
do
{
- bool IsRegular = true;
+ bool AttemptDelete = true;
if (FindData.cFileName[0] == L'.')
{
@@ -115,16 +115,21 @@ WipeDirectory(const wchar_t* DirPath)
{
if (FindData.cFileName[2] == L'\0')
{
- IsRegular = false;
+ AttemptDelete = false;
}
}
else if (FindData.cFileName[1] == L'\0')
{
- IsRegular = false;
+ AttemptDelete = false;
+ }
+
+ if (KeepDotFiles)
+ {
+ AttemptDelete = false;
}
}
- if (IsRegular)
+ if (AttemptDelete)
{
ExtendableWideStringBuilder<128> Path;
Path.Append(DirPath);
@@ -188,7 +193,8 @@ WipeDirectory(const wchar_t* DirPath)
bool
DeleteDirectories(const wchar_t* DirPath)
{
- return WipeDirectory(DirPath) && RemoveDirectoryW(DirPath) == TRUE;
+ const bool KeepDotFiles = false;
+ return WipeDirectory(DirPath, KeepDotFiles) && RemoveDirectoryW(DirPath) == TRUE;
}
bool
@@ -196,7 +202,20 @@ CleanDirectory(const wchar_t* DirPath)
{
if (std::filesystem::exists(DirPath))
{
- return WipeDirectory(DirPath);
+ const bool KeepDotFiles = false;
+
+ return WipeDirectory(DirPath, KeepDotFiles);
+ }
+
+ return CreateDirectories(DirPath);
+}
+
+bool
+CleanDirectory(const wchar_t* DirPath, bool KeepDotFiles)
+{
+ if (std::filesystem::exists(DirPath))
+ {
+ return WipeDirectory(DirPath, KeepDotFiles);
}
return CreateDirectories(DirPath);
@@ -262,6 +281,19 @@ CleanDirectory(const std::filesystem::path& Dir)
#endif
}
+bool
+CleanDirectoryExceptDotFiles(const std::filesystem::path& Dir)
+{
+#if ZEN_PLATFORM_WINDOWS
+ const bool KeepDotFiles = true;
+ return CleanDirectory(Dir.c_str(), KeepDotFiles);
+#else
+ ZEN_UNUSED(Dir);
+
+ ZEN_NOT_IMPLEMENTED();
+#endif
+}
+
//////////////////////////////////////////////////////////////////////////
bool
@@ -950,7 +982,7 @@ FileSystemTraversal::TraverseFileSystem(const std::filesystem::path& RootDir, Tr
if (FAILED(hRes))
{
- ThrowSystemException(hRes, "Failed to open handle to volume root");
+ ThrowSystemException(hRes, fmt::format("Failed to open handle to '{}'", RootDir));
}
while (Continue)
@@ -1063,6 +1095,33 @@ FileSystemTraversal::TraverseFileSystem(const std::filesystem::path& RootDir, Tr
closedir(Dir);
#endif // ZEN_PLATFORM_WINDOWS
}
+
+std::filesystem::path
+CanonicalPath(std::filesystem::path InPath, std::error_code& Ec)
+{
+ ZEN_UNUSED(Ec);
+
+#if ZEN_PLATFORM_WINDOWS
+ windows::FileHandle Handle;
+ HRESULT hRes = Handle.Create(InPath.c_str(),
+ GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS);
+
+ if (FAILED(hRes))
+ {
+ Ec = MakeErrorCodeFromLastError();
+
+ return {};
+ }
+
+ return PathFromHandle(Handle, Ec);
+#else
+ return InPath;
+#endif
+}
+
std::filesystem::path
PathFromHandle(void* NativeHandle, std::error_code& Ec)
{