first commit

This commit is contained in:
2024-12-06 04:58:55 -06:00
commit 856373b396
61 changed files with 5920 additions and 0 deletions

122
src/Filesystem/LocalFS.cpp Normal file
View File

@ -0,0 +1,122 @@
#include "TessesFramework/Filesystem/LocalFS.hpp"
#include "TessesFramework/Streams/FileStream.hpp"
#include <iostream>
namespace Tesses::Framework::Filesystem
{
VFSPath LocalFilesystem::ReadLink(VFSPath path)
{
return this->SystemToVFSPath(std::filesystem::read_symlink(this->VFSPathToSystem(path)));
}
Tesses::Framework::Streams::Stream* LocalFilesystem::OpenFile(VFSPath path, std::string mode)
{
return new Tesses::Framework::Streams::FileStream(VFSPathToSystem(path), mode);
}
void LocalFilesystem::DeleteDirectory(VFSPath path)
{
std::filesystem::remove(VFSPathToSystem(path));
}
void LocalFilesystem::DeleteFile(VFSPath path)
{
std::filesystem::remove(VFSPathToSystem(path));
}
void LocalFilesystem::CreateDirectory(VFSPath path)
{
std::filesystem::create_directories(VFSPathToSystem(path));
}
bool LocalFilesystem::DirectoryExists(VFSPath path)
{
return std::filesystem::is_directory(VFSPathToSystem(path));
}
bool LocalFilesystem::RegularFileExists(VFSPath path)
{
return std::filesystem::is_regular_file(VFSPathToSystem(path));
}
bool LocalFilesystem::SymlinkExists(VFSPath path)
{
return std::filesystem::is_symlink(VFSPathToSystem(path));
}
bool LocalFilesystem::BlockDeviceExists(VFSPath path)
{
return std::filesystem::is_block_file(VFSPathToSystem(path));
}
bool LocalFilesystem::CharacterDeviceExists(VFSPath path)
{
return std::filesystem::is_character_file(VFSPathToSystem(path));
}
bool LocalFilesystem::SocketFileExists(VFSPath path)
{
return std::filesystem::is_socket(VFSPathToSystem(path));
}
bool LocalFilesystem::FIFOFileExists(VFSPath path)
{
return std::filesystem::is_fifo(VFSPathToSystem(path));
}
void LocalFilesystem::CreateSymlink(VFSPath existingFile, VFSPath symlinkFile)
{
if(std::filesystem::is_directory(VFSPathToSystem(existingFile)))
{
std::filesystem::create_directory_symlink(VFSPathToSystem(existingFile),VFSPathToSystem(symlinkFile));
}
else
{
std::filesystem::create_symlink(VFSPathToSystem(existingFile),VFSPathToSystem(symlinkFile));
}
}
void LocalFilesystem::CreateHardlink(VFSPath existingFile, VFSPath newName)
{
std::filesystem::create_hard_link(VFSPathToSystem(existingFile),VFSPathToSystem(newName));
}
void LocalFilesystem::MoveFile(VFSPath src, VFSPath dest)
{
std::filesystem::rename(VFSPathToSystem(src),VFSPathToSystem(dest));
}
void LocalFilesystem::MoveDirectory(VFSPath src, VFSPath dest)
{
std::filesystem::rename(VFSPathToSystem(src),VFSPathToSystem(dest));
}
std::string LocalFilesystem::VFSPathToSystem(VFSPath path)
{
#if defined(WIN32)
bool first=true;
std::string p = {};
for(auto item : path.path)
{
if(!(first && !item.empty() && item.back()==':') && !(first && this->relative))
p.push_back('\\');
p.append(item);
first=false;
}
return p;
#else
return path.ToString();
#endif
}
VFSPath LocalFilesystem::SystemToVFSPath(std::string path)
{
VFSPath p;
p.path = VFSPath::SplitPath(path,true);
p.relative=true;
if(!path.empty())
{
if(path.front() == '/') p.relative=false;
if(!p.path.empty())
{
auto firstPartPath = p.path.front();
if(!firstPartPath.empty() && firstPartPath.back() == '/') p.relative=false;
}
}
return p;
}
void LocalFilesystem::GetPaths(VFSPath path, std::vector<VFSPath>& paths)
{
for(auto item : std::filesystem::directory_iterator(VFSPathToSystem(path)))
{
paths.push_back(VFSPath(path, item.path().filename().string()));
}
}
}
// C:/Users/Jim/Joel

View File

@ -0,0 +1,553 @@
#include "TessesFramework/Filesystem/MountableFilesystem.hpp"
#include "TessesFramework/Filesystem/NullFilesystem.hpp"
#include <iostream>
namespace Tesses::Framework::Filesystem
{
MountableFilesystem::MountableFilesystem() : MountableFilesystem(new NullFilesystem(),true)
{
}
MountableFilesystem::MountableFilesystem(VFS* root, bool owns)
{
this->root = root;
this->owns = owns;
}
MountableDirectory::~MountableDirectory()
{
if(this->owns && this->vfs) delete this->vfs;
for(auto dir : this->dirs) delete dir;
}
MountableFilesystem::~MountableFilesystem()
{
if(this->owns && this->root) delete root;
for(auto item : this->directories) delete item;
}
void MountableFilesystem::GetFS(VFSPath srcPath, VFSPath& destRoot, VFSPath& destPath, VFS*& vfs)
{
if(srcPath.path.empty()) return;
for(auto item : this->directories)
{
if(srcPath.path.front() == item->name)
{
if(item->vfs != nullptr)
{
vfs = item->vfs;
VFSPath srcPath1(std::vector(srcPath.path.begin()+1,srcPath.path.end()));
srcPath1.relative=false;
destPath = srcPath1;
destRoot = VFSPath(VFSPath(),item->name);
}
VFSPath srcPath2(std::vector(srcPath.path.begin()+1,srcPath.path.end()));
srcPath2.relative=false;
item->GetFS(srcPath2,VFSPath(VFSPath(),item->name), destRoot,destPath,vfs);
return;
}
}
}
void MountableDirectory::GetFS(VFSPath srcPath, VFSPath curDir, VFSPath& destRoot, VFSPath& destPath, VFS*& vfs)
{
if(srcPath.path.empty()) return;
for(auto item : this->dirs)
{
if(!srcPath.path.empty() && srcPath.path.front() == item->name)
{
if(item->vfs != nullptr)
{
vfs = item->vfs;
VFSPath srcPath1(std::vector(srcPath.path.begin()+1,srcPath.path.end()));
srcPath1.relative=false;
destPath = srcPath1;
destRoot = curDir;
}
VFSPath srcPath2(std::vector(srcPath.path.begin()+1,srcPath.path.end()));
srcPath2.relative=false;
item->GetFS(srcPath2,VFSPath(curDir,item->name), destRoot,destPath,vfs);
return;
}
}
}
VFSPath MountableFilesystem::ReadLink(VFSPath path)
{
path = path.CollapseRelativeParents();
VFSPath destRoot;
VFSPath destPath = path;
VFS* vfs = root;
GetFS(path, destRoot, destPath, vfs);
if(vfs != nullptr)
return VFSPath(destRoot,vfs->ReadLink(destPath));
return VFSPath();
}
Tesses::Framework::Streams::Stream* MountableFilesystem::OpenFile(VFSPath path, std::string mode)
{
path = path.CollapseRelativeParents();
VFSPath destRoot;
VFSPath destPath = path;
VFS* vfs = root;
GetFS(path, destRoot, destPath, vfs);
if(vfs != nullptr)
return vfs->OpenFile(destPath,mode);
return nullptr;
}
void MountableFilesystem::CreateDirectory(VFSPath path)
{
path = path.CollapseRelativeParents();
VFSPath destRoot;
VFSPath destPath = path;
VFS* vfs = root;
GetFS(path, destRoot, destPath, vfs);
if(destPath.path.empty()) return;
if(vfs != nullptr)
vfs->CreateDirectory(destPath);
}
void MountableFilesystem::DeleteDirectory(VFSPath path)
{
path = path.CollapseRelativeParents();
VFSPath destRoot;
VFSPath destPath = path;
VFS* vfs = root;
GetFS(path, destRoot, destPath, vfs);
if(destPath.path.empty()) return;
if(vfs != nullptr)
vfs->DeleteDirectory(destPath);
}
bool MountableFilesystem::SpecialFileExists(VFSPath path)
{
path = path.CollapseRelativeParents();
VFSPath destRoot;
VFSPath destPath = path;
VFS* vfs = root;
GetFS(path, destRoot, destPath, vfs);
if(vfs != nullptr)
return vfs->SpecialFileExists(destPath);
return false;
}
bool MountableFilesystem::FileExists(VFSPath path)
{
path = path.CollapseRelativeParents();
VFSPath destRoot;
VFSPath destPath = path;
VFS* vfs = root;
GetFS(path, destRoot, destPath, vfs);
if(vfs != nullptr)
return vfs->FileExists(destPath);
return false;
}
bool MountableFilesystem::RegularFileExists(VFSPath path)
{
path = path.CollapseRelativeParents();
VFSPath destRoot;
VFSPath destPath = path;
VFS* vfs = root;
GetFS(path, destRoot, destPath, vfs);
if(vfs != nullptr)
return vfs->RegularFileExists(destPath);
return false;
}
bool MountableFilesystem::SymlinkExists(VFSPath path)
{
path = path.CollapseRelativeParents();
VFSPath destRoot;
VFSPath destPath = path;
VFS* vfs = root;
GetFS(path, destRoot, destPath, vfs);
if(vfs != nullptr)
return vfs->SymlinkExists(destPath);
return false;
}
bool MountableFilesystem::CharacterDeviceExists(VFSPath path)
{
path = path.CollapseRelativeParents();
VFSPath destRoot;
VFSPath destPath = path;
VFS* vfs = root;
GetFS(path, destRoot, destPath, vfs);
if(vfs != nullptr)
return vfs->CharacterDeviceExists(destPath);
return false;
}
bool MountableFilesystem::BlockDeviceExists(VFSPath path)
{
path = path.CollapseRelativeParents();
VFSPath destRoot;
VFSPath destPath = path;
VFS* vfs = root;
GetFS(path, destRoot, destPath, vfs);
if(vfs != nullptr)
return vfs->BlockDeviceExists(destPath);
return false;
}
bool MountableFilesystem::SocketFileExists(VFSPath path)
{
path = path.CollapseRelativeParents();
VFSPath destRoot;
VFSPath destPath = path;
VFS* vfs = root;
GetFS(path, destRoot, destPath, vfs);
if(vfs != nullptr)
return vfs->SocketFileExists(destPath);
return false;
}
bool MountableFilesystem::FIFOFileExists(VFSPath path)
{
path = path.CollapseRelativeParents();
VFSPath destRoot;
VFSPath destPath = path;
VFS* vfs = root;
GetFS(path, destRoot, destPath, vfs);
if(vfs != nullptr)
return vfs->FIFOFileExists(destPath);
return false;
}
bool MountableFilesystem::DirectoryExists(VFSPath path)
{
path = path.CollapseRelativeParents();
VFSPath destRoot;
VFSPath destPath = path;
VFS* vfs = root;
GetFS(path, destRoot, destPath, vfs);
if(destPath.path.empty()) return true;
if(vfs != nullptr)
return vfs->DirectoryExists(destPath);
return false;
}
void MountableFilesystem::DeleteFile(VFSPath path)
{
path = path.CollapseRelativeParents();
VFSPath destRoot;
VFSPath destPath = path;
VFS* vfs = root;
GetFS(path, destRoot, destPath, vfs);
if(vfs != nullptr)
vfs->DeleteFile(destPath);
}
void MountableFilesystem::CreateSymlink(VFSPath existingFile, VFSPath symlinkFile)
{
existingFile = existingFile.CollapseRelativeParents();
symlinkFile = existingFile.CollapseRelativeParents();
VFSPath existingDestRoot;
VFSPath existingDestPath = existingFile;
VFS* existingVFS = root;
VFSPath symlinkDestRoot;
VFSPath symlinkDestPath = symlinkFile;
VFS* symlinkVFS = root;
GetFS(existingFile, existingDestRoot, existingDestPath, existingVFS);
GetFS(symlinkFile, symlinkDestRoot, symlinkDestPath, symlinkVFS);
if(existingVFS != nullptr && existingVFS == symlinkVFS)
existingVFS->CreateSymlink(existingDestPath, symlinkDestPath);
}
void MountableFilesystem::MoveDirectory(VFSPath src, VFSPath dest)
{
src = src.CollapseRelativeParents();
dest = dest.CollapseRelativeParents();
VFSPath srcDestRoot;
VFSPath srcDestPath = src;
VFS* srcVFS = root;
VFSPath destDestRoot;
VFSPath destDestPath = dest;
VFS* destVFS = root;
GetFS(src, srcDestRoot, srcDestPath, srcVFS);
GetFS(dest, destDestRoot, destDestPath, destVFS);
if(srcVFS != nullptr && srcVFS == destVFS)
srcVFS->MoveDirectory(srcDestPath, destDestPath);
}
void MountableFilesystem::MoveFile(VFSPath src, VFSPath dest)
{
src = src.CollapseRelativeParents();
dest = dest.CollapseRelativeParents();
VFSPath srcDestRoot;
VFSPath srcDestPath = src;
VFS* srcVFS = root;
VFSPath destDestRoot;
VFSPath destDestPath = dest;
VFS* destVFS = root;
GetFS(src, srcDestRoot, srcDestPath, srcVFS);
GetFS(dest, destDestRoot, destDestPath, destVFS);
if(srcVFS != nullptr && srcVFS == destVFS)
srcVFS->MoveFile(srcDestPath, destDestPath);
}
void MountableFilesystem::CreateHardlink(VFSPath existingFile, VFSPath newName)
{
existingFile = existingFile.CollapseRelativeParents();
newName = existingFile.CollapseRelativeParents();
VFSPath existingDestRoot;
VFSPath existingDestPath = existingFile;
VFS* existingVFS = root;
VFSPath newNameRoot;
VFSPath newNamePath = newName;
VFS* newNameVFS = root;
GetFS(existingFile, existingDestRoot, existingDestPath, existingVFS);
GetFS(newName, newNameRoot, newNamePath, newNameVFS);
if(existingVFS != nullptr && existingVFS == newNameVFS)
existingVFS->CreateHardlink(existingDestPath, newNamePath);
}
void MountableFilesystem::GetPaths(VFSPath path, std::vector<VFSPath>& paths)
{
path = path.CollapseRelativeParents();
bool mydirs = path.path.empty();
std::vector<MountableDirectory*>* dirs = &this->directories;
if(!path.path.empty())
for(auto p : path.path)
{
mydirs=true;
bool hasSet=false;
for(auto itm : *dirs)
{
if(itm->name == p)
{
hasSet=true;
dirs = &itm->dirs;
break;
}
}
if(!hasSet)
{
mydirs=false;
break;
}
}
VFSPath destRoot;
VFSPath destPath = path;
VFS* vfs = root;
GetFS(path, destRoot, destPath, vfs);
if(vfs != nullptr)
{
std::vector<VFSPath> paths2;
if(vfs->DirectoryExists(destPath) || !mydirs)
vfs->GetPaths(destPath,paths2);
for(auto item : paths2)
{
paths.push_back(VFSPath(destPath, item.GetFileName()));
}
if(mydirs)
for(auto item : *dirs)
{
bool cantAdd=false;
for(auto d : paths) {
if(d.GetFileName() == item->name)
{
cantAdd=true;
break;
}
}
if(!cantAdd) paths.push_back(VFSPath(destPath, item->name));
}
}
}
void MountableFilesystem::Mount(VFSPath path, VFS* fs, bool owns)
{
path = path.CollapseRelativeParents();
if(path.path.empty())
{
if(owns) delete fs;
return;
}
auto* fsLs = &this->directories;
bool needToCreate=true;
for(auto index = path.path.begin(); index < path.path.end()-1; index++)
{
needToCreate=true;
for(auto item : *fsLs)
{
if(item->name == *index)
{
needToCreate=false;
fsLs = &(item->dirs);
break;
}
}
if(needToCreate)
{
MountableDirectory* dir = new MountableDirectory();
dir->name = *index;
dir->owns=false;
dir->vfs=NULL;
fsLs->push_back(dir);
fsLs = &(dir->dirs);
}
}
needToCreate=true;
std::string lastDir = path.GetFileName();
for(auto item : *fsLs)
{
if(item->name == lastDir)
{
needToCreate=false;
if(item->owns && item->vfs) delete item->vfs;
item->vfs = fs;
break;
}
}
if(needToCreate)
{
MountableDirectory* dir = new MountableDirectory();
dir->name = lastDir;
dir->owns=owns;
dir->vfs=fs;
fsLs->push_back(dir);
}
}
static bool myumount(MountableDirectory* dir,VFSPath path)
{
if(path.path.empty())
{
if(dir->owns && dir->vfs) delete dir->vfs;
dir->vfs = nullptr;
}
if(dir->dirs.empty())
{
delete dir;
return true;
}
for(auto index = dir->dirs.begin(); index < dir->dirs.end(); index++)
{
auto item = *index;
if(!path.path.empty() && path.path.front() == item->name)
{
VFSPath srcPath2(std::vector(path.path.begin()+1,path.path.end()));
if(myumount(item,srcPath2))
{
dir->dirs.erase(index);
}
if(dir->dirs.empty())
{
delete dir;
return true;
}
return false;
}
}
return false;
}
void MountableFilesystem::Unmount(VFSPath path)
{
path = path.CollapseRelativeParents();
for(auto index = this->directories.begin(); index < this->directories.end(); index++)
{
auto item = *index;
if(!path.path.empty() && path.path.front() == item->name)
{
VFSPath srcPath2(std::vector(path.path.begin()+1,path.path.end()));
if(myumount(item,srcPath2))
{
this->directories.erase(index);
}
return;
}
}
}
std::string MountableFilesystem::VFSPathToSystem(VFSPath path)
{
return path.ToString();
}
VFSPath MountableFilesystem::SystemToVFSPath(std::string path)
{
return VFSPath(path);
}
}

View File

@ -0,0 +1,45 @@
#include "TessesFramework/Filesystem/NullFilesystem.hpp"
namespace Tesses::Framework::Filesystem
{
Tesses::Framework::Streams::Stream* NullFilesystem::OpenFile(VFSPath path, std::string mode)
{
return nullptr;
}
void NullFilesystem::CreateDirectory(VFSPath path)
{
}
void NullFilesystem::DeleteDirectory(VFSPath path)
{
}
bool NullFilesystem::RegularFileExists(VFSPath path)
{
return false;
}
bool NullFilesystem::DirectoryExists(VFSPath path)
{
return false;
}
void NullFilesystem::DeleteFile(VFSPath path)
{
}
void NullFilesystem::GetPaths(VFSPath path, std::vector<VFSPath>& paths)
{
}
void NullFilesystem::MoveFile(VFSPath src, VFSPath dest)
{
}
std::string NullFilesystem::VFSPathToSystem(VFSPath path)
{
return path.ToString();
}
VFSPath NullFilesystem::SystemToVFSPath(std::string path)
{
return VFSPath(path);
}
}

View File

@ -0,0 +1,132 @@
#include "TessesFramework/Filesystem/SubdirFilesystem.hpp"
#include <iostream>
namespace Tesses::Framework::Filesystem
{
VFSPath SubdirFilesystem::ReadLink(VFSPath path)
{
return FromParent(this->parent->ReadLink(ToParent(path)));
}
VFSPath SubdirFilesystem::FromParent(VFSPath path)
{
// /a/b/c
// /a/b/c
VFSPath newPath;
newPath.relative=false;
if(path.path.size() >= this->path.path.size())
{
newPath.path.reserve(path.path.size()-this->path.path.size());
for(size_t i = this->path.path.size(); i < path.path.size();i++)
{
newPath.path.push_back(path.path[i]);
}
}
return newPath;
}
VFSPath SubdirFilesystem::ToParent(VFSPath path)
{
return VFSPath(this->path, path.CollapseRelativeParents());
}
SubdirFilesystem::SubdirFilesystem(VFS* parent, VFSPath path, bool owns)
{
this->parent = parent;
this->path = path;
this->owns=owns;
}
Tesses::Framework::Streams::Stream* SubdirFilesystem::OpenFile(VFSPath path, std::string mode)
{
return this->parent->OpenFile(ToParent(path),mode);
}
void SubdirFilesystem::CreateDirectory(VFSPath path)
{
this->parent->CreateDirectory(ToParent(path));
}
void SubdirFilesystem::DeleteDirectory(VFSPath path)
{
this->parent->DeleteDirectory(ToParent(path));
}
bool SubdirFilesystem::RegularFileExists(VFSPath path)
{
return this->parent->RegularFileExists(ToParent(path));
}
bool SubdirFilesystem::SymlinkExists(VFSPath path)
{
return this->parent->SymlinkExists(ToParent(path));
}
bool SubdirFilesystem::CharacterDeviceExists(VFSPath path)
{
return this->parent->CharacterDeviceExists(ToParent(path));
}
bool SubdirFilesystem::BlockDeviceExists(VFSPath path)
{
return this->parent->BlockDeviceExists(ToParent(path));
}
bool SubdirFilesystem::SocketFileExists(VFSPath path)
{
return this->parent->SocketFileExists(ToParent(path));
}
bool SubdirFilesystem::FIFOFileExists(VFSPath path)
{
return this->parent->FIFOFileExists(ToParent(path));
}
bool SubdirFilesystem::DirectoryExists(VFSPath path)
{
return this->parent->DirectoryExists(ToParent(path));
}
void SubdirFilesystem::DeleteFile(VFSPath path)
{
this->parent->DeleteFile(ToParent(path));
}
void SubdirFilesystem::CreateSymlink(VFSPath existingFile, VFSPath symlinkFile)
{
this->parent->CreateSymlink(ToParent(existingFile),ToParent(symlinkFile));
}
void SubdirFilesystem::GetPaths(VFSPath path, std::vector<VFSPath>& paths)
{
std::vector<VFSPath> paths2;
this->parent->GetPaths(ToParent(path),paths2);
for(auto item : paths2)
{
paths.push_back(FromParent(item));
}
}
void SubdirFilesystem::CreateHardlink(VFSPath existingFile, VFSPath newName)
{
this->parent->CreateHardlink(ToParent(existingFile),ToParent(newName));
}
void SubdirFilesystem::MoveFile(VFSPath src, VFSPath dest)
{
this->parent->MoveFile(ToParent(src),ToParent(dest));
}
void SubdirFilesystem::MoveDirectory(VFSPath src, VFSPath dest)
{
this->parent->MoveDirectory(ToParent(src),ToParent(dest));
}
std::string SubdirFilesystem::VFSPathToSystem(VFSPath path)
{
return this->parent->VFSPathToSystem(ToParent(path));
}
VFSPath SubdirFilesystem::SystemToVFSPath(std::string path)
{
return FromParent(this->parent->SystemToVFSPath(path));
}
void SubdirFilesystem::DeleteDirectoryRecurse(VFSPath path)
{
this->parent->DeleteDirectoryRecurse(ToParent(path));
}
bool SubdirFilesystem::SpecialFileExists(VFSPath path)
{
return this->parent->SpecialFileExists(ToParent(path));
}
bool SubdirFilesystem::FileExists(VFSPath path)
{
return this->parent->FileExists(ToParent(path));
}
SubdirFilesystem::~SubdirFilesystem()
{
if(this->owns)
delete this->parent;
}
}

208
src/Filesystem/VFS.cpp Normal file
View File

@ -0,0 +1,208 @@
#include "TessesFramework/Filesystem/VFS.hpp"
#include "TessesFramework/Http/HttpUtils.hpp"
namespace Tesses::Framework::Filesystem
{
VFSPath VFS::ReadLink(VFSPath path)
{
return VFSPath("/");
}
VFSPath VFSPath::CollapseRelativeParents()
{
std::vector<std::string> parts;
for(auto item : this->path)
{
if(item == "..")
{
if(!parts.empty())
{
parts.erase(parts.end()-1);
}
}
else if(item == ".")
{
//do nothing but don't emit this
}
else
{
parts.push_back(item);
}
}
VFSPath newpath;
newpath.relative = relative;
newpath.path = parts;
return newpath;
}
VFSPath VFSPath::RelativeCurrentDirectory()
{
VFSPath path;
path.relative=true;
return path;
}
std::vector<std::string> VFSPath::SplitPath(std::string path,bool nativePath)
{
std::vector<std::string> parts;
std::string curPath = {};
for(auto c : path)
{
if(c == '/')
{
if(!curPath.empty())
{
parts.push_back(curPath);
curPath = {};
}
}
#if defined(WIN32)
else if(c == '\\' && nativePath)
{
if(!curPath.empty())
{
parts.push_back(curPath);
curPath = {};
}
}
#endif
else
{
curPath.push_back(c);
}
}
if(!curPath.empty())
{
parts.push_back(curPath);
curPath = {};
}
return parts;
}
VFSPath::VFSPath()
{
this->relative=false;
}
VFSPath::VFSPath(std::vector<std::string> p)
{
this->path = p;
}
VFSPath::VFSPath(std::string str)
{
this->path = SplitPath(str);
this->relative=true;
if(!str.empty())
{
if(str.front() == '/') this->relative=false;
if(!this->path.empty())
{
auto firstPartPath = this->path.front();
if(!firstPartPath.empty() && firstPartPath.back() == '/') this->relative=false;
}
}
}
VFSPath::VFSPath(VFSPath p1, VFSPath p2)
{
this->relative = p1.relative;
this->path.insert(this->path.end(),p1.path.begin(),p1.path.end());
this->path.insert(this->path.end(),p2.path.begin(),p2.path.end());
}
VFSPath::VFSPath(VFSPath p1, std::string subpath) : VFSPath(p1, VFSPath(subpath))
{
}
VFSPath VFSPath::GetParent()
{
std::vector<std::string> paths;
if(this->path.empty()) return VFSPath();
paths.insert(paths.begin(), this->path.begin(), this->path.end()-1);
return VFSPath(paths);
}
std::string VFSPath::GetFileName()
{
if(this->path.empty()) return "";
return this->path.back();
}
std::string VFSPath::ToString()
{
if(this->path.empty() && !this->relative) return "/";
bool first=true;
std::string p = {};
for(auto item : this->path)
{
if(!(first && !item.empty() && item.back()==':') && !(first && this->relative))
p.push_back('/');
p.append(item);
first=false;
}
return p;
}
VFS::~VFS()
{
}
bool VFS::FIFOFileExists(VFSPath path) {return false;}
bool VFS::SocketFileExists(VFSPath path) {return false;}
bool VFS::CharacterDeviceExists(VFSPath path) {return false;}
bool VFS::BlockDeviceExists(VFSPath path) {return false;}
bool VFS::SymlinkExists(VFSPath path) {return false;}
void VFS::MoveDirectory(VFSPath src, VFSPath dest)
{
std::vector<VFSPath> paths;
GetPaths(src, paths);
for(auto item : paths)
{
if(DirectoryExists(item))
{
MoveDirectory(item, VFSPath(dest, item.GetFileName()));
}
else
{
MoveFile(item, VFSPath(dest, item.GetFileName()));
}
}
DeleteDirectory(src);
}
void VFS::CreateSymlink(VFSPath existingFile, VFSPath symlinkFile)
{
}
void VFS::CreateHardlink(VFSPath existingFile, VFSPath newName)
{
}
bool VFS::SpecialFileExists(VFSPath path)
{
return SymlinkExists(path) || BlockDeviceExists(path) || CharacterDeviceExists(path) || SocketFileExists(path) || FIFOFileExists(path);
}
bool VFS::FileExists(VFSPath path)
{
return RegularFileExists(path) || SpecialFileExists(path);
}
void VFS::DeleteDirectoryRecurse(VFSPath path)
{
if(!DirectoryExists(path)) return;
std::vector<VFSPath> paths;
GetPaths(path, paths);
for(auto item : paths)
{
if(DirectoryExists(item))
{
DeleteDirectoryRecurse(item);
}
else
{
DeleteFile(item);
}
}
DeleteDirectory(path);
}
}