Skip to content

Commit

Permalink
FileSystem: reworked FindFileData struct; added SearchRecursive
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMostDiligent committed Dec 10, 2023
1 parent c96d0a3 commit 78d1bbe
Show file tree
Hide file tree
Showing 8 changed files with 189 additions and 62 deletions.
7 changes: 6 additions & 1 deletion Platforms/Basic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@ set(INTERFACE
interface/DebugUtilities.hpp
)

set(INCLUDE
include/SearchRecursive.inl
)

if(PLATFORM_LINUX OR PLATFORM_WIN32 OR PLATFORM_APPLE OR PLATFORM_EMSCRIPTEN)
list(APPEND SOURCE src/StandardFile.cpp)
list(APPEND INTERFACE interface/StandardFile.hpp)
endif()

add_library(Diligent-BasicPlatform STATIC ${SOURCE} ${INTERFACE})
add_library(Diligent-BasicPlatform STATIC ${SOURCE} ${INTERFACE} ${INCLUDE})
set_common_target_properties(Diligent-BasicPlatform)

target_include_directories(Diligent-BasicPlatform
Expand All @@ -37,6 +41,7 @@ PUBLIC

source_group("src" FILES ${SOURCE})
source_group("interface" FILES ${INTERFACE})
source_group("include" FILES ${INCLUDE})

set_target_properties(Diligent-BasicPlatform PROPERTIES
FOLDER DiligentCore/Platforms
Expand Down
81 changes: 81 additions & 0 deletions Platforms/Basic/include/SearchRecursive.inl
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright 2023 Diligent Graphics LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* In no event and under no legal theory, whether in tort (including negligence),
* contract, or otherwise, unless required by applicable law (such as deliberate
* and grossly negligent acts) or agreed to in writing, shall any Contributor be
* liable for any damages, including any direct, indirect, special, incidental,
* or consequential damages of any character arising as a result of this License or
* out of the use or inability to use the software (including but not limited to damages
* for loss of goodwill, work stoppage, computer failure or malfunction, or any and
* all other commercial damages or losses), even if such Contributor has been advised
* of the possibility of such damages.
*/

#pragma once

#include <string>
#include <vector>

namespace Diligent
{

template <typename FileSystem>
void SearchRecursiveImpl(const std::string& BaseDir, const std::string& SubDir, const Char* SearchPattern, std::vector<FindFileData>& Res)
{
std::string Dir = BaseDir + SubDir;

auto Files = FileSystem::Search((Dir + SearchPattern).c_str());
Res.reserve(Res.size() + Files.size());
for (auto& File : Files)
{
File.Name = SubDir + File.Name;
Res.emplace_back(std::move(File));
}

auto AllFiles = FileSystem::Search((Dir + '*').c_str());
for (const auto& File : AllFiles)
{
if (File.IsDirectory)
{
SearchRecursiveImpl<FileSystem>(BaseDir, SubDir + File.Name + FileSystem::SlashSymbol, SearchPattern, Res);
}
}
}

template <typename FileSystem>
typename FileSystem::SearchFilesResult SearchRecursive(const Char* Dir, const Char* SearchPattern)
{
if (Dir == nullptr || Dir[0] == '\0')
{
UNEXPECTED("Directory must not be null or empty");
return {};
}
if (SearchPattern == nullptr || SearchPattern[0] == '\0')
{
UNEXPECTED("Search pattern must not be null or empty");
return {};
}

std::string BaseDir = Dir;
if (BaseDir.back() != FileSystem::SlashSymbol)
BaseDir += FileSystem::SlashSymbol;

typename FileSystem::SearchFilesResult Res;
SearchRecursiveImpl<FileSystem>(BaseDir, "", SearchPattern, Res);
return Res;
}

} // namespace Diligent
8 changes: 4 additions & 4 deletions Platforms/Basic/interface/BasicFileSystem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,8 @@ struct FileDialogAttribs

struct FindFileData
{
virtual const Char* Name() const = 0;
virtual bool IsDirectory() const = 0;

virtual ~FindFileData() {}
String Name;
bool IsDirectory = false;
};

struct BasicFileSystem
Expand All @@ -148,6 +146,8 @@ struct BasicFileSystem
static constexpr Char SlashSymbol = '/';
#endif

using SearchFilesResult = std::vector<FindFileData>;

static BasicFile* OpenFile(FileOpenAttribs& OpenAttribs);
static void ReleaseFile(BasicFile*);

Expand Down
5 changes: 3 additions & 2 deletions Platforms/Linux/interface/LinuxFileSystem.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2022 Diligent Graphics LLC
* Copyright 2019-2023 Diligent Graphics LLC
* Copyright 2015-2019 Egor Yusov
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -54,7 +54,8 @@ struct LinuxFileSystem : public BasicFileSystem
static void ClearDirectory(const Char* strPath, bool Recursive = false);
static void DeleteFile(const Char* strPath);

static std::vector<std::unique_ptr<FindFileData>> Search(const Char* SearchPattern);
static SearchFilesResult Search(const Char* SearchPattern);
static SearchFilesResult SearchRecursive(const Char* Dir, const Char* SearchPattern);

// Thread-safe popen/pclose
static FILE* popen(const char* command, const char* type);
Expand Down
32 changes: 14 additions & 18 deletions Platforms/Linux/src/LinuxFileSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include "../interface/LinuxFileSystem.hpp"
#include "Errors.hpp"
#include "DebugUtilities.hpp"
#include "../../Basic/include/SearchRecursive.inl"

namespace Diligent
{
Expand Down Expand Up @@ -166,24 +167,9 @@ bool LinuxFileSystem::IsDirectory(const Char* strPath)
return S_ISDIR(StatBuff.st_mode);
}

struct LinuxFindFileData : public FindFileData
LinuxFileSystem::SearchFilesResult LinuxFileSystem::Search(const Char* SearchPattern)
{
virtual const Char* Name() const override { return m_Name.c_str(); }

virtual bool IsDirectory() const override { return m_IsDirectory; }

const std::string m_Name;
const bool m_IsDirectory;

LinuxFindFileData(std::string _Name, bool _IsDirectory) :
m_Name{std::move(_Name)},
m_IsDirectory{_IsDirectory}
{}
};

std::vector<std::unique_ptr<FindFileData>> LinuxFileSystem::Search(const Char* SearchPattern)
{
std::vector<std::unique_ptr<FindFileData>> SearchRes;
LinuxFileSystem::SearchFilesResult SearchRes;

#if PLATFORM_LINUX || PLATFORM_APPLE
glob_t glob_result = {};
Expand All @@ -198,7 +184,7 @@ std::vector<std::unique_ptr<FindFileData>> LinuxFileSystem::Search(const Char* S

std::string FileName;
GetPathComponents(path, nullptr, &FileName);
SearchRes.emplace_back(std::make_unique<LinuxFindFileData>(std::move(FileName), S_ISDIR(StatBuff.st_mode)));
SearchRes.emplace_back(FindFileData{std::move(FileName), S_ISDIR(StatBuff.st_mode)});
}
}
globfree(&glob_result);
Expand All @@ -209,6 +195,16 @@ std::vector<std::unique_ptr<FindFileData>> LinuxFileSystem::Search(const Char* S
return SearchRes;
}

LinuxFileSystem::SearchFilesResult LinuxFileSystem::SearchRecursive(const Char* Dir, const Char* SearchPattern)
{
#if PLATFORM_LINUX || PLATFORM_APPLE
return Diligent::SearchRecursive<LinuxFileSystem>(Dir, SearchPattern);
#else
UNSUPPORTED("Not implemented");
return {};
#endif
}

// popen/pclose are not thread-safe
static std::mutex g_popen_mtx{};

Expand Down
5 changes: 3 additions & 2 deletions Platforms/Win32/interface/Win32FileSystem.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2022 Diligent Graphics LLC
* Copyright 2019-2023 Diligent Graphics LLC
* Copyright 2015-2019 Egor Yusov
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -56,7 +56,8 @@ struct WindowsFileSystem : public BasicFileSystem
static void DeleteDirectory(const Char* strPath);
static bool IsDirectory(const Char* strPath);

static std::vector<std::unique_ptr<FindFileData>> Search(const Char* SearchPattern);
static SearchFilesResult Search(const Char* SearchPattern);
static SearchFilesResult SearchRecursive(const Char* Dir, const Char* SearchPattern);

static std::string FileDialog(const FileDialogAttribs& DialogAttribs);
static std::string OpenFolderDialog(const char* Title);
Expand Down
26 changes: 10 additions & 16 deletions Platforms/Win32/src/Win32FileSystem.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2022 Diligent Graphics LLC
* Copyright 2019-2023 Diligent Graphics LLC
* Copyright 2015-2019 Egor Yusov
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -28,6 +28,7 @@
#include "Win32FileSystem.hpp"
#include "Errors.hpp"
#include "../../Common/interface/StringTools.hpp"
#include "../../Basic/include/SearchRecursive.inl"

// We can't use namespace Diligent before #including <Windows.h> because Diligent::INTERFACE_ID will conflict with windows InterfaceID
//using namespace Diligent;
Expand Down Expand Up @@ -420,21 +421,9 @@ void WindowsFileSystem::SetWorkingDirectory(const Char* strWorkingDir)
WindowsPathHelper::SetWorkingDirectory(strWorkingDir);
}

struct WndFindFileData : public FindFileData
WindowsFileSystem::SearchFilesResult WindowsFileSystem::Search(const Char* SearchPattern)
{
virtual const Char* Name() const override { return ffd.cFileName; }

virtual bool IsDirectory() const override { return (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; }

WIN32_FIND_DATAA ffd;

WndFindFileData(const WIN32_FIND_DATAA& _ffd) :
ffd{_ffd} {}
};

std::vector<std::unique_ptr<FindFileData>> WindowsFileSystem::Search(const Char* SearchPattern)
{
std::vector<std::unique_ptr<FindFileData>> SearchRes;
SearchFilesResult SearchRes;

WIN32_FIND_DATAA ffd;
// Find the first file in the directory.
Expand All @@ -452,7 +441,7 @@ std::vector<std::unique_ptr<FindFileData>> WindowsFileSystem::Search(const Char*
if (IsDot(ffd.cFileName) || IsDblDot(ffd.cFileName))
continue;

SearchRes.emplace_back(std::make_unique<WndFindFileData>(ffd));
SearchRes.emplace_back(FindFileData{ffd.cFileName, (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0});
} while (FindNextFileA(hFind, &ffd) != 0);

auto dwError = GetLastError();
Expand All @@ -466,6 +455,11 @@ std::vector<std::unique_ptr<FindFileData>> WindowsFileSystem::Search(const Char*
return SearchRes;
}

WindowsFileSystem::SearchFilesResult WindowsFileSystem::SearchRecursive(const Char* Dir, const Char* SearchPattern)
{
return Diligent::SearchRecursive<WindowsFileSystem>(Dir, SearchPattern);
}

static DWORD FileDialogFlagsToOFNFlags(FILE_DIALOG_FLAGS FileDialogFlags)
{
DWORD OFNFlags = 0;
Expand Down
Loading

0 comments on commit 78d1bbe

Please sign in to comment.