first commit
This commit is contained in:
122
src/Filesystem/LocalFS.cpp
Normal file
122
src/Filesystem/LocalFS.cpp
Normal 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
|
||||
553
src/Filesystem/MountableFilesystem.cpp
Normal file
553
src/Filesystem/MountableFilesystem.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
45
src/Filesystem/NullFilesystem.cpp
Normal file
45
src/Filesystem/NullFilesystem.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
132
src/Filesystem/SubdirFilesystem.cpp
Normal file
132
src/Filesystem/SubdirFilesystem.cpp
Normal 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
208
src/Filesystem/VFS.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user