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 = "/";
if(argc > 2) dir = argv[2];
std::vector<VFSPath> paths;
fs.GetPaths(dir, paths);
for(auto item : paths)
for(auto item : fs.EnumeratePaths(dir))
{
std::cout << item.GetFileName() << std::endl;
}

View File

@ -17,12 +17,14 @@ namespace Tesses::Framework::Filesystem
bool DirectoryExists(VFSPath path);
void DeleteFile(VFSPath path);
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 MoveFile(VFSPath src, VFSPath dest);
void MoveDirectory(VFSPath src, VFSPath dest);
VFSPath ReadLink(VFSPath path);
std::string VFSPathToSystem(VFSPath 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);
void DeleteFile(VFSPath path);
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 MoveFile(VFSPath src, VFSPath dest);
void MoveDirectory(VFSPath src, VFSPath dest);
@ -49,5 +49,7 @@ namespace Tesses::Framework::Filesystem
std::string VFSPathToSystem(VFSPath path);
VFSPath SystemToVFSPath(std::string path);
~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 DirectoryExists(VFSPath path);
void DeleteFile(VFSPath path);
void GetPaths(VFSPath path, std::vector<VFSPath>& paths);
VFSPathEnumerator EnumeratePaths(VFSPath path);
void MoveFile(VFSPath src, VFSPath dest);
std::string VFSPathToSystem(VFSPath path);
VFSPath SystemToVFSPath(std::string path);

View File

@ -25,7 +25,7 @@ namespace Tesses::Framework::Filesystem
bool DirectoryExists(VFSPath path);
void DeleteFile(VFSPath path);
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 MoveFile(VFSPath src, VFSPath dest);
void MoveDirectory(VFSPath src, VFSPath dest);
@ -34,5 +34,8 @@ namespace Tesses::Framework::Filesystem
std::string VFSPathToSystem(VFSPath path);
VFSPath SystemToVFSPath(std::string path);
~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
#include "../Common.hpp"
#include "../Streams/Stream.hpp"
#include <functional>
#include <memory>
namespace Tesses::Framework::Filesystem
{
class VFSPath {
@ -28,6 +30,58 @@ namespace Tesses::Framework::Filesystem
VFSPath operator+(VFSPath p, VFSPath p2);
VFSPath operator+(VFSPath p, std::string 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 {
@ -49,13 +103,17 @@ namespace Tesses::Framework::Filesystem
virtual bool DirectoryExists(VFSPath path)=0;
virtual void DeleteFile(VFSPath path)=0;
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 MoveDirectory(VFSPath src, VFSPath dest);
virtual VFSPath ReadLink(VFSPath path);
virtual std::string VFSPathToSystem(VFSPath 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();
};
}

View File

@ -11,7 +11,6 @@ namespace Tesses::Framework::Streams
public:
int32_t ReadByte();
void WriteByte(uint8_t b);
virtual bool EndOfStream();
virtual size_t Read(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/Streams/FileStream.hpp"
#include <iostream>
#include <sys/stat.h>
#include <utime.h>
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)
{
return this->SystemToVFSPath(std::filesystem::read_symlink(this->VFSPathToSystem(path)));
@ -110,12 +130,22 @@ namespace Tesses::Framework::Filesystem
}
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)))
{
paths.push_back(VFSPath(path, item.path().filename().string()));
}
auto dir = new std::filesystem::directory_iterator(VFSPathToSystem(path));
return VFSPathEnumerator([dir,path](VFSPath& path0)->bool {
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)
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)
{
@ -361,11 +389,19 @@ namespace Tesses::Framework::Filesystem
if(existingVFS != nullptr && existingVFS == newNameVFS)
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();
bool mydirs = path.path.empty();
std::vector<MountableDirectory*>* dirs = &this->directories;
if(!path.path.empty())
for(auto p : path.path)
{
@ -396,32 +432,50 @@ namespace Tesses::Framework::Filesystem
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)
MountableEnumerationState* state = new MountableEnumerationState();
state->dirs = *dirs;
state->index = 0;
if(vfs->DirectoryExists(destPath) || !mydirs)
state->enumerator = vfs->EnumeratePaths(destPath).MakePointer();
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()));
}
if(mydirs)
for(auto item : *dirs)
{
bool cantAdd=false;
for(auto d : paths) {
if(d.GetFileName() == item->name)
auto fname = state->enumerator->Current.GetFileName();
bool mustContinue=false;
for(auto item : state->dirs)
{
if(item->name == fname)
{
cantAdd=true;
mustContinue=true;
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)
{
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)
{

View File

@ -82,15 +82,31 @@ namespace Tesses::Framework::Filesystem
{
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;
this->parent->GetPaths(ToParent(path),paths2);
for(auto item : paths2)
{
paths.push_back(FromParent(item));
}
VFSPathEnumerator* enumerator = this->parent->EnumeratePaths(ToParent(path)).MakePointer();
return VFSPathEnumerator([enumerator,path,this](VFSPath& path0)->bool{
if(enumerator->MoveNext())
{
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)
{
this->parent->CreateHardlink(ToParent(existingFile),ToParent(newName));

View File

@ -2,6 +2,110 @@
#include "TessesFramework/Http/HttpUtils.hpp"
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)
{
return VFSPath(p,p2);
@ -198,10 +302,8 @@ namespace Tesses::Framework::Filesystem
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)
for(auto item : EnumeratePaths(src))
{
if(DirectoryExists(item))
{
@ -236,10 +338,8 @@ namespace Tesses::Framework::Filesystem
void VFS::DeleteDirectoryRecurse(VFSPath path)
{
if(!DirectoryExists(path)) return;
std::vector<VFSPath> paths;
GetPaths(path, paths);
for(auto item : paths)
for(auto item : EnumeratePaths(path))
{
if(DirectoryExists(item))
{
@ -252,4 +352,13 @@ namespace Tesses::Framework::Filesystem
}
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(p);
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))
{

View File

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