File system base Implementation #11

Merged
XiaoQiDigipen merged 4 commits from SP3-14-FileSystem into main 2022-09-13 11:42:30 +08:00
2 changed files with 94 additions and 22 deletions
Showing only changes of commit 47f716f72b - Show all commits

View File

@ -1,15 +1,19 @@
#include "SHpch.h"
#include "SHFileSystem.h"
#include "fileapi.h"
#include <filesystem>
#include <cassert>
#include <queue>
namespace SHADE
{
char const FOLDER_MAX_COUNT {15};
std::unordered_map<FolderLocation, std::unique_ptr<SHFolder>> SHFileSystem::folders;
FolderPointer SHFileSystem::root {nullptr};
SHFolder::SHFolder(FolderHandle id, FolderName name)
:id{id}, name{name}, subFolders(0)
:id{ id }, name{ name }, subFolders(0), folded{ false }, path{""}
{
}
@ -22,54 +26,110 @@ namespace SHADE
folders[0] = std::make_unique<SHFolder>(0, "root");
}
FolderCounter const count = static_cast<FolderCounter>(folders[here]->subFolders.size());
auto const count = static_cast<FolderCounter>(folders[here]->subFolders.size());
assert(count < FOLDER_MAX_COUNT, "Max subfolders reached\n");
FolderHandle const location = static_cast<FolderLocation>(count);
auto const location = static_cast<FolderLocation>(count);
CreateFolderHelper(folders[0]->path, here, location, name);
CreateFolder(folders[0]->path, here, location, name);
return location;
}
assert(folders.contains(here), "Folder creation location does not exist/invalid\n");
FolderCounter const count = static_cast<FolderCounter>(folders[here]->subFolders.size());
auto const count = static_cast<FolderCounter>(folders[here]->subFolders.size());
FolderHandle location = here;
location <<= 4;
location <<= FOLDER_BIT_ALLOCATE;
location |= count;
assert(count < FOLDER_MAX_COUNT, "Max subfolders reached\n");
CreateFolderHelper(folders[0]->path, here, location, name);
CreateFolder(folders[0]->path, here, location, name);
return location;
}
bool SHFileSystem::DeleteFolder(FolderLocation location) noexcept
bool SHFileSystem::DeleteFolder(FolderPointer location) noexcept
{
assert(folders.contains(location), "Delete target does not exist/invalid.\n");
assert(folders.contains(location->id), "Delete target does not exist/invalid.\n");
for (auto const& subFolder : folders[location]->subFolders)
for (auto const& subFolder : folders[location->id]->subFolders)
{
DeleteFolder(subFolder);
}
RemoveDirectoryA(folders[location]->path.string().c_str());
RemoveDirectoryA(folders[location->id]->path.c_str());
return true;
}
bool SHFileSystem::CreateFolderHelper(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept
void SHFileSystem::StartupFillDirectories(FolderPath path) noexcept
{
std::queue<FolderPointer> folderQueue;
folderQueue.push(RegisterFolder(path, 0, 0, "Root"));
while (!folderQueue.empty())
{
auto folder = folderQueue.front();
folderQueue.pop();
FolderCounter count = 0;
for (auto const& dirEntry : std::filesystem::directory_iterator(folder->path))
{
if (!dirEntry.is_directory())
{
continue;
}
FolderLocation location = folder->id;
location <<= FOLDER_BIT_ALLOCATE;
location |= ++count;
std::string name = dirEntry.path().string();
name = name.substr(name.find_last_of('/') + 1, name.length() - name.find_last_of('/'));
FolderPointer newFolder{ RegisterFolder(
dirEntry.path().string(),
folder->id,
location,
name)
};
folderQueue.push(newFolder);
folder->subFolders.push_back(newFolder);
}
}
}
FolderPointer SHFileSystem::CreateFolder(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept
{
assert(
CreateDirectoryA(path.string().c_str(), nullptr),
CreateDirectoryA(path.c_str(), nullptr),
"Failed to create folder\n"
);
folders[location] = std::make_unique<SHFolder>(location, name);
folders[parent]->subFolders.push_back(location);
folders[location]->path = path;
folders[parent]->subFolders.push_back(folders[location].get());
return true;
return FolderMakeHelper(path, parent, location, name);
}
FolderPointer SHFileSystem::RegisterFolder(FolderPath path, FolderLocation parent, FolderHandle location,
FolderName name) noexcept
{
return FolderMakeHelper(path, parent, location, name);
}
FolderPointer SHFileSystem::FolderMakeHelper(FolderPath path, FolderLocation parent, FolderHandle location,
FolderName name) noexcept
{
folders[location] = std::make_unique<SHFolder>(location, name);
folders[location]->path = path;
folders[parent]->subFolders.push_back(folders[location].get());
return folders[location].get();
}
}

View File

@ -3,17 +3,21 @@
#include <string>
#include <vector>
#include <memory>
#include <filesystem>
#include <unordered_map>
namespace SHADE
{
class SHFolder;
typedef unsigned char FolderCounter;
typedef unsigned char FileCounter;
typedef uint32_t FolderLocation;
typedef uint32_t FolderHandle;
typedef uint64_t FolderLocation;
typedef uint64_t FolderHandle;
typedef std::string FolderName;
typedef std::filesystem::path FolderPath;
typedef std::string FolderPath;
typedef SHFolder* FolderPointer;
constexpr char FOLDER_BIT_ALLOCATE{ 4 };
constexpr char FOLDER_MAX_DEPTH{ 26 };
class SHFolder
{
@ -22,7 +26,9 @@ namespace SHADE
FolderHandle id;
FolderName name;
std::vector<FolderHandle> subFolders;
std::vector<FolderPointer> subFolders;
bool folded;
private:
FolderPath path;
@ -34,11 +40,17 @@ namespace SHADE
public:
static FolderLocation CreateNewFolderHere(FolderName name, FolderLocation here = 0) noexcept;
static bool DeleteFolder(FolderLocation location) noexcept;
static bool DeleteFolder(FolderPointer location) noexcept;
static void StartupFillDirectories(FolderPath path) noexcept;
private:
static FolderPointer root;
static std::unordered_map<FolderLocation, std::unique_ptr<SHFolder>> folders;
static bool CreateFolderHelper(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept;
static FolderPointer CreateFolder(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept;
static FolderPointer RegisterFolder(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept;
static FolderPointer FolderMakeHelper(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept;
};
}