Added more fixes

This commit is contained in:
Mike Nolan 2024-12-28 14:46:58 -06:00
parent cbc0f59400
commit 5b89d8c5de
14 changed files with 328 additions and 57 deletions

View File

@ -38,9 +38,8 @@ int main(int argc, char** argv)
{ {
std::string dir = "/"; std::string dir = "/";
if(argc > 2) dir = argv[2]; if(argc > 2) dir = argv[2];
std::vector<VFSPath> paths;
fs.GetPaths(dir, paths); for(auto item : fs.EnumeratePaths(dir))
for(auto item : paths)
{ {
std::cout << item.GetFileName() << std::endl; std::cout << item.GetFileName() << std::endl;
} }

View File

@ -17,12 +17,14 @@ namespace Tesses::Framework::Filesystem
bool DirectoryExists(VFSPath path); bool DirectoryExists(VFSPath path);
void DeleteFile(VFSPath path); void DeleteFile(VFSPath path);
void CreateSymlink(VFSPath existingFile, VFSPath symlinkFile); void CreateSymlink(VFSPath existingFile, VFSPath symlinkFile);
void GetPaths(VFSPath path, std::vector<VFSPath>& paths); VFSPathEnumerator EnumeratePaths(VFSPath path);
void CreateHardlink(VFSPath existingFile, VFSPath newName); void CreateHardlink(VFSPath existingFile, VFSPath newName);
void MoveFile(VFSPath src, VFSPath dest); void MoveFile(VFSPath src, VFSPath dest);
void MoveDirectory(VFSPath src, VFSPath dest); void MoveDirectory(VFSPath src, VFSPath dest);
VFSPath ReadLink(VFSPath path); VFSPath ReadLink(VFSPath path);
std::string VFSPathToSystem(VFSPath path); std::string VFSPathToSystem(VFSPath path);
VFSPath SystemToVFSPath(std::string path); VFSPath SystemToVFSPath(std::string path);
void GetDate(VFSPath path, time_t& lastWrite, time_t& lastAccess);
void SetDate(VFSPath path, time_t lastWrite, time_t lastAccess);
}; };
} }

View File

@ -41,7 +41,7 @@ namespace Tesses::Framework::Filesystem
bool DirectoryExists(VFSPath path); bool DirectoryExists(VFSPath path);
void DeleteFile(VFSPath path); void DeleteFile(VFSPath path);
void CreateSymlink(VFSPath existingFile, VFSPath symlinkFile); void CreateSymlink(VFSPath existingFile, VFSPath symlinkFile);
void GetPaths(VFSPath path, std::vector<VFSPath>& paths); VFSPathEnumerator EnumeratePaths(VFSPath path);
void CreateHardlink(VFSPath existingFile, VFSPath newName); void CreateHardlink(VFSPath existingFile, VFSPath newName);
void MoveFile(VFSPath src, VFSPath dest); void MoveFile(VFSPath src, VFSPath dest);
void MoveDirectory(VFSPath src, VFSPath dest); void MoveDirectory(VFSPath src, VFSPath dest);
@ -49,5 +49,7 @@ namespace Tesses::Framework::Filesystem
std::string VFSPathToSystem(VFSPath path); std::string VFSPathToSystem(VFSPath path);
VFSPath SystemToVFSPath(std::string path); VFSPath SystemToVFSPath(std::string path);
~MountableFilesystem(); ~MountableFilesystem();
void GetDate(VFSPath path, time_t& lastWrite, time_t& lastAccess);
void SetDate(VFSPath path, time_t lastWrite, time_t lastAccess);
}; };
} }

View File

@ -11,7 +11,7 @@ namespace Tesses::Framework::Filesystem
bool RegularFileExists(VFSPath path); bool RegularFileExists(VFSPath path);
bool DirectoryExists(VFSPath path); bool DirectoryExists(VFSPath path);
void DeleteFile(VFSPath path); void DeleteFile(VFSPath path);
void GetPaths(VFSPath path, std::vector<VFSPath>& paths); VFSPathEnumerator EnumeratePaths(VFSPath path);
void MoveFile(VFSPath src, VFSPath dest); void MoveFile(VFSPath src, VFSPath dest);
std::string VFSPathToSystem(VFSPath path); std::string VFSPathToSystem(VFSPath path);
VFSPath SystemToVFSPath(std::string path); VFSPath SystemToVFSPath(std::string path);

View File

@ -25,7 +25,7 @@ namespace Tesses::Framework::Filesystem
bool DirectoryExists(VFSPath path); bool DirectoryExists(VFSPath path);
void DeleteFile(VFSPath path); void DeleteFile(VFSPath path);
void CreateSymlink(VFSPath existingFile, VFSPath symlinkFile); void CreateSymlink(VFSPath existingFile, VFSPath symlinkFile);
void GetPaths(VFSPath path, std::vector<VFSPath>& paths); VFSPathEnumerator EnumeratePaths(VFSPath path);
void CreateHardlink(VFSPath existingFile, VFSPath newName); void CreateHardlink(VFSPath existingFile, VFSPath newName);
void MoveFile(VFSPath src, VFSPath dest); void MoveFile(VFSPath src, VFSPath dest);
void MoveDirectory(VFSPath src, VFSPath dest); void MoveDirectory(VFSPath src, VFSPath dest);
@ -34,5 +34,8 @@ namespace Tesses::Framework::Filesystem
std::string VFSPathToSystem(VFSPath path); std::string VFSPathToSystem(VFSPath path);
VFSPath SystemToVFSPath(std::string path); VFSPath SystemToVFSPath(std::string path);
~SubdirFilesystem(); ~SubdirFilesystem();
void GetDate(VFSPath path, time_t& lastWrite, time_t& lastAccess);
void SetDate(VFSPath path, time_t lastWrite, time_t lastAccess);
}; };
} }

View File

@ -1,6 +1,8 @@
#pragma once #pragma once
#include "../Common.hpp" #include "../Common.hpp"
#include "../Streams/Stream.hpp" #include "../Streams/Stream.hpp"
#include <functional>
#include <memory>
namespace Tesses::Framework::Filesystem namespace Tesses::Framework::Filesystem
{ {
class VFSPath { class VFSPath {
@ -28,6 +30,58 @@ namespace Tesses::Framework::Filesystem
VFSPath operator+(VFSPath p, VFSPath p2); VFSPath operator+(VFSPath p, VFSPath p2);
VFSPath operator+(VFSPath p, std::string p2); VFSPath operator+(VFSPath p, std::string p2);
VFSPath operator+(std::string p, VFSPath p2); VFSPath operator+(std::string p, VFSPath p2);
class VFSPathEnumeratorData {
public:
VFSPathEnumeratorData(std::function<bool(VFSPath&)> moveNext, std::function<void()> destroy)
{
this->eof=false;
this->moveNext=moveNext;
this->destroy=destroy;
}
bool eof;
std::function<bool(VFSPath&)> moveNext;
std::function<void()> destroy;
~VFSPathEnumeratorData()
{
this->destroy();
}
};
class VFSPathEnumerator;
class VFSPathEnumeratorItterator
{
VFSPath e;
VFSPathEnumerator* enumerator;
public:
VFSPathEnumeratorItterator();
VFSPathEnumeratorItterator(VFSPathEnumerator* enumerator);
VFSPathEnumeratorItterator& operator++();
VFSPathEnumeratorItterator& operator++(int);
VFSPath& operator*();
VFSPath* operator->();
bool operator!=(VFSPathEnumeratorItterator right);
bool operator==(VFSPathEnumeratorItterator right);
};
class VFSPathEnumerator {
std::shared_ptr<VFSPathEnumeratorData> data;
public:
VFSPathEnumerator();
VFSPathEnumerator* MakePointer();
VFSPathEnumerator(std::function<bool(VFSPath&)> moveNext, std::function<void()> destroy);
VFSPath Current;
bool MoveNext();
bool IsDone();
VFSPathEnumeratorItterator begin();
VFSPathEnumeratorItterator end();
};
class VFS { class VFS {
@ -49,13 +103,17 @@ namespace Tesses::Framework::Filesystem
virtual bool DirectoryExists(VFSPath path)=0; virtual bool DirectoryExists(VFSPath path)=0;
virtual void DeleteFile(VFSPath path)=0; virtual void DeleteFile(VFSPath path)=0;
virtual void DeleteDirectoryRecurse(VFSPath path); virtual void DeleteDirectoryRecurse(VFSPath path);
virtual void GetPaths(VFSPath path, std::vector<VFSPath>& paths)=0; virtual VFSPathEnumerator EnumeratePaths(VFSPath path) = 0;
virtual void MoveFile(VFSPath src, VFSPath dest)=0; virtual void MoveFile(VFSPath src, VFSPath dest)=0;
virtual void MoveDirectory(VFSPath src, VFSPath dest); virtual void MoveDirectory(VFSPath src, VFSPath dest);
virtual VFSPath ReadLink(VFSPath path); virtual VFSPath ReadLink(VFSPath path);
virtual std::string VFSPathToSystem(VFSPath path)=0; virtual std::string VFSPathToSystem(VFSPath path)=0;
virtual VFSPath SystemToVFSPath(std::string path)=0; virtual VFSPath SystemToVFSPath(std::string path)=0;
virtual void GetDate(VFSPath path, time_t& lastWrite, time_t& lastAccess);
virtual void SetDate(VFSPath path, time_t lastWrite, time_t lastAccess);
virtual ~VFS(); virtual ~VFS();
}; };
} }

View File

@ -11,7 +11,6 @@ namespace Tesses::Framework::Streams
public: public:
int32_t ReadByte(); int32_t ReadByte();
void WriteByte(uint8_t b); void WriteByte(uint8_t b);
virtual bool EndOfStream(); virtual bool EndOfStream();
virtual size_t Read(uint8_t* buff, size_t sz); virtual size_t Read(uint8_t* buff, size_t sz);
virtual size_t Write(const uint8_t* buff, size_t sz); virtual size_t Write(const uint8_t* buff, size_t sz);

View File

@ -1,8 +1,28 @@
#include "TessesFramework/Filesystem/LocalFS.hpp" #include "TessesFramework/Filesystem/LocalFS.hpp"
#include "TessesFramework/Streams/FileStream.hpp" #include "TessesFramework/Streams/FileStream.hpp"
#include <iostream> #include <iostream>
#include <sys/stat.h>
#include <utime.h>
namespace Tesses::Framework::Filesystem namespace Tesses::Framework::Filesystem
{ {
void LocalFilesystem::GetDate(VFSPath path, time_t& lastWrite, time_t& lastAccess)
{
std::string s = VFSPathToSystem(path);
struct stat st;
if(stat(s.c_str(),&st) == 0)
{
lastAccess = st.st_atime;
lastWrite = st.st_mtime;
}
}
void LocalFilesystem::SetDate(VFSPath path, time_t lastWrite, time_t lastAccess)
{
std::string s = VFSPathToSystem(path);
struct utimbuf utim;
utim.actime = lastAccess;
utim.modtime = lastWrite;
utime(s.c_str(),&utim);
}
VFSPath LocalFilesystem::ReadLink(VFSPath path) VFSPath LocalFilesystem::ReadLink(VFSPath path)
{ {
return this->SystemToVFSPath(std::filesystem::read_symlink(this->VFSPathToSystem(path))); return this->SystemToVFSPath(std::filesystem::read_symlink(this->VFSPathToSystem(path)));
@ -110,12 +130,22 @@ namespace Tesses::Framework::Filesystem
} }
return p; return p;
} }
void LocalFilesystem::GetPaths(VFSPath path, std::vector<VFSPath>& paths)
VFSPathEnumerator LocalFilesystem::EnumeratePaths(VFSPath path)
{ {
for(auto item : std::filesystem::directory_iterator(VFSPathToSystem(path))) auto dir = new std::filesystem::directory_iterator(VFSPathToSystem(path));
{ return VFSPathEnumerator([dir,path](VFSPath& path0)->bool {
paths.push_back(VFSPath(path, item.path().filename().string())); std::filesystem::directory_iterator& ittr = *dir;
} if(ittr != std::filesystem::directory_iterator())
{
path0 = VFSPath(path, ittr->path().filename().string());
ittr++;
return true;
}
return false;
},[dir]()->void{
delete dir;
});
} }
} }

View File

@ -287,6 +287,34 @@ namespace Tesses::Framework::Filesystem
if(vfs != nullptr) if(vfs != nullptr)
vfs->DeleteFile(destPath); vfs->DeleteFile(destPath);
}
void MountableFilesystem::GetDate(VFSPath path, time_t& lastWrite, time_t& lastAccess)
{
path = path.CollapseRelativeParents();
VFSPath destRoot;
VFSPath destPath = path;
VFS* vfs = root;
GetFS(path, destRoot, destPath, vfs);
if(vfs != nullptr)
vfs->GetDate(destPath,lastWrite,lastAccess);
}
void MountableFilesystem::SetDate(VFSPath path, time_t lastWrite, time_t lastAccess)
{
path = path.CollapseRelativeParents();
VFSPath destRoot;
VFSPath destPath = path;
VFS* vfs = root;
GetFS(path, destRoot, destPath, vfs);
if(vfs != nullptr)
vfs->SetDate(destPath,lastWrite,lastAccess);
} }
void MountableFilesystem::CreateSymlink(VFSPath existingFile, VFSPath symlinkFile) void MountableFilesystem::CreateSymlink(VFSPath existingFile, VFSPath symlinkFile)
{ {
@ -361,11 +389,19 @@ namespace Tesses::Framework::Filesystem
if(existingVFS != nullptr && existingVFS == newNameVFS) if(existingVFS != nullptr && existingVFS == newNameVFS)
existingVFS->CreateHardlink(existingDestPath, newNamePath); existingVFS->CreateHardlink(existingDestPath, newNamePath);
} }
void MountableFilesystem::GetPaths(VFSPath path, std::vector<VFSPath>& paths) class MountableEnumerationState {
public:
VFSPathEnumerator* enumerator;
std::vector<MountableDirectory*> dirs;
size_t index;
};
VFSPathEnumerator MountableFilesystem::EnumeratePaths(VFSPath path)
{ {
path = path.CollapseRelativeParents(); path = path.CollapseRelativeParents();
bool mydirs = path.path.empty(); bool mydirs = path.path.empty();
std::vector<MountableDirectory*>* dirs = &this->directories; std::vector<MountableDirectory*>* dirs = &this->directories;
if(!path.path.empty()) if(!path.path.empty())
for(auto p : path.path) for(auto p : path.path)
{ {
@ -396,32 +432,50 @@ namespace Tesses::Framework::Filesystem
GetFS(path, destRoot, destPath, vfs); GetFS(path, destRoot, destPath, vfs);
if(vfs != nullptr) MountableEnumerationState* state = new MountableEnumerationState();
{ state->dirs = *dirs;
std::vector<VFSPath> paths2; state->index = 0;
if(vfs->DirectoryExists(destPath) || !mydirs) if(vfs->DirectoryExists(destPath) || !mydirs)
vfs->GetPaths(destPath,paths2); state->enumerator = vfs->EnumeratePaths(destPath).MakePointer();
for(auto item : paths2) else
state->enumerator = nullptr;
return VFSPathEnumerator([state,path](VFSPath& path0)->bool{
while(state->enumerator != nullptr && state->enumerator->MoveNext())
{ {
paths.push_back(VFSPath(destPath, item.GetFileName())); auto fname = state->enumerator->Current.GetFileName();
}
if(mydirs) bool mustContinue=false;
for(auto item : *dirs) for(auto item : state->dirs)
{ {
bool cantAdd=false; if(item->name == fname)
for(auto d : paths) {
if(d.GetFileName() == item->name)
{ {
cantAdd=true; mustContinue=true;
break; break;
} }
} }
if(!cantAdd) paths.push_back(VFSPath(destPath, item->name)); if(mustContinue) continue;
path0 = path / fname;
return true;
} }
} if(state->enumerator != nullptr)
{
delete state->enumerator;
state->enumerator = nullptr;
}
if(state->index < state->dirs.size())
{
path0 = path / state->dirs[state->index++]->name;
return true;
}
return false;
},[state]()->void{
if(state->enumerator) delete state->enumerator;
delete state;
});
} }
void MountableFilesystem::Mount(VFSPath path, VFS* fs, bool owns) void MountableFilesystem::Mount(VFSPath path, VFS* fs, bool owns)
{ {
path = path.CollapseRelativeParents(); path = path.CollapseRelativeParents();

View File

@ -26,9 +26,9 @@ namespace Tesses::Framework::Filesystem
{ {
} }
void NullFilesystem::GetPaths(VFSPath path, std::vector<VFSPath>& paths) VFSPathEnumerator NullFilesystem::EnumeratePaths(VFSPath path)
{ {
return VFSPathEnumerator();
} }
void NullFilesystem::MoveFile(VFSPath src, VFSPath dest) void NullFilesystem::MoveFile(VFSPath src, VFSPath dest)
{ {

View File

@ -82,15 +82,31 @@ namespace Tesses::Framework::Filesystem
{ {
this->parent->CreateSymlink(ToParent(existingFile),ToParent(symlinkFile)); this->parent->CreateSymlink(ToParent(existingFile),ToParent(symlinkFile));
} }
void SubdirFilesystem::GetPaths(VFSPath path, std::vector<VFSPath>& paths)
VFSPathEnumerator SubdirFilesystem::EnumeratePaths(VFSPath path)
{ {
std::vector<VFSPath> paths2; VFSPathEnumerator* enumerator = this->parent->EnumeratePaths(ToParent(path)).MakePointer();
this->parent->GetPaths(ToParent(path),paths2);
for(auto item : paths2) return VFSPathEnumerator([enumerator,path,this](VFSPath& path0)->bool{
{ if(enumerator->MoveNext())
paths.push_back(FromParent(item)); {
} path0 = FromParent( path / enumerator->Current);
return true;
}
return false;
},[enumerator]()->void{
delete enumerator;
});
} }
void SubdirFilesystem::GetDate(VFSPath path, time_t& lastWrite, time_t& lastAccess)
{
this->parent->GetDate(ToParent(path),lastWrite,lastAccess);
}
void SubdirFilesystem::SetDate(VFSPath path, time_t lastWrite, time_t lastAccess)
{
this->parent->SetDate(ToParent(path),lastWrite,lastAccess);
}
void SubdirFilesystem::CreateHardlink(VFSPath existingFile, VFSPath newName) void SubdirFilesystem::CreateHardlink(VFSPath existingFile, VFSPath newName)
{ {
this->parent->CreateHardlink(ToParent(existingFile),ToParent(newName)); this->parent->CreateHardlink(ToParent(existingFile),ToParent(newName));

View File

@ -2,6 +2,110 @@
#include "TessesFramework/Http/HttpUtils.hpp" #include "TessesFramework/Http/HttpUtils.hpp"
namespace Tesses::Framework::Filesystem namespace Tesses::Framework::Filesystem
{ {
VFSPathEnumeratorItterator::VFSPathEnumeratorItterator()
{
this->enumerator=nullptr;
}
VFSPathEnumeratorItterator::VFSPathEnumeratorItterator(VFSPathEnumerator* enumerator)
{
this->enumerator = enumerator;
}
VFSPathEnumeratorItterator& VFSPathEnumeratorItterator::operator++(int)
{
enumerator->MoveNext();
return *this;
}
VFSPathEnumeratorItterator& VFSPathEnumeratorItterator::operator++()
{
enumerator->MoveNext();
return *this;
}
VFSPath& VFSPathEnumeratorItterator::operator*()
{
std::filesystem::directory_iterator i;
if(enumerator != nullptr)
return enumerator->Current;
return this->e;
}
VFSPath* VFSPathEnumeratorItterator::operator->()
{
if(enumerator != nullptr)
return &enumerator->Current;
return nullptr;
}
bool VFSPathEnumeratorItterator::operator!=(VFSPathEnumeratorItterator right)
{
if(enumerator == right.enumerator)
{
return false;
}
if(right.enumerator == nullptr)
{
auto r = !enumerator->IsDone();
return r;
}
return true;
}
bool VFSPathEnumeratorItterator::operator==(VFSPathEnumeratorItterator right)
{
if(enumerator == right.enumerator)
{
return true;
}
if(right.enumerator == nullptr)
return enumerator->IsDone();
return false;
}
VFSPathEnumerator::VFSPathEnumerator()
{
data = nullptr;
}
VFSPathEnumerator* VFSPathEnumerator::MakePointer()
{
VFSPathEnumerator* enumerator = new VFSPathEnumerator();
enumerator->Current = Current;
enumerator->data = data;
return enumerator;
}
VFSPathEnumerator::VFSPathEnumerator(std::function<bool(VFSPath&)> moveNext, std::function<void()> destroy)
{
data = std::make_shared<VFSPathEnumeratorData>(moveNext,destroy);
}
bool VFSPathEnumerator::MoveNext()
{
if(this->data)
{
auto r = data->moveNext(Current);
if(!r) data->eof=true;
return r;
}
return false;
}
bool VFSPathEnumerator::IsDone()
{
if(this->data)
{
return data->eof;
}
return true;
}
VFSPathEnumeratorItterator VFSPathEnumerator::begin()
{
MoveNext();
VFSPathEnumeratorItterator ittr(this);
return ittr;
}
VFSPathEnumeratorItterator VFSPathEnumerator::end()
{
return VFSPathEnumeratorItterator();
}
VFSPath operator/(VFSPath p, VFSPath p2) VFSPath operator/(VFSPath p, VFSPath p2)
{ {
return VFSPath(p,p2); return VFSPath(p,p2);
@ -198,10 +302,8 @@ namespace Tesses::Framework::Filesystem
bool VFS::SymlinkExists(VFSPath path) {return false;} bool VFS::SymlinkExists(VFSPath path) {return false;}
void VFS::MoveDirectory(VFSPath src, VFSPath dest) void VFS::MoveDirectory(VFSPath src, VFSPath dest)
{ {
std::vector<VFSPath> paths;
GetPaths(src, paths); for(auto item : EnumeratePaths(src))
for(auto item : paths)
{ {
if(DirectoryExists(item)) if(DirectoryExists(item))
{ {
@ -236,10 +338,8 @@ namespace Tesses::Framework::Filesystem
void VFS::DeleteDirectoryRecurse(VFSPath path) void VFS::DeleteDirectoryRecurse(VFSPath path)
{ {
if(!DirectoryExists(path)) return; if(!DirectoryExists(path)) return;
std::vector<VFSPath> paths;
GetPaths(path, paths); for(auto item : EnumeratePaths(path))
for(auto item : paths)
{ {
if(DirectoryExists(item)) if(DirectoryExists(item))
{ {
@ -252,4 +352,13 @@ namespace Tesses::Framework::Filesystem
} }
DeleteDirectory(path); DeleteDirectory(path);
} }
void VFS::GetDate(VFSPath path, time_t& lastWrite, time_t& lastAccess)
{
}
void VFS::SetDate(VFSPath path, time_t lastWrite, time_t lastAccess)
{
}
} }

View File

@ -74,10 +74,9 @@ namespace Tesses::Framework::Http
html.append("</title></head><body><h1>Index of "); html.append("</title></head><body><h1>Index of ");
html.append(p); html.append(p);
html.append("</h1><hr><pre><a href=\"../\">../</a>\r\n"); html.append("</h1><hr><pre><a href=\"../\">../</a>\r\n");
std::vector<VFSPath> ents;
vfs->GetPaths(path, ents);
for(auto item : ents) for(auto item : vfs->EnumeratePaths(path))
{ {
if(vfs->DirectoryExists(item)) if(vfs->DirectoryExists(item))
{ {

View File

@ -94,8 +94,8 @@ namespace Tesses::Framework::Streams {
} }
void Stream::CopyTo(Stream* strm, size_t buffSize) void Stream::CopyTo(Stream* strm, size_t buffSize)
{ {
if(strm == nullptr) if(strm != nullptr)
strm->CopyTo(strm, buffSize); strm->CopyTo(*strm, buffSize);
} }
void Stream::CopyTo(Stream& strm, size_t buffSize) void Stream::CopyTo(Stream& strm, size_t buffSize)
{ {
@ -112,4 +112,4 @@ namespace Tesses::Framework::Streams {
{ {
} }
} }