fix: misc fixes, cleanup
This commit is contained in:
+34
-56
@@ -30,14 +30,16 @@ std::string FileBuffer::toString() const
|
|||||||
void VirtualFileSystem::mount(const std::string& virtualPath, std::unique_ptr<IFileProvider> provider, int priority)
|
void VirtualFileSystem::mount(const std::string& virtualPath, std::unique_ptr<IFileProvider> provider, int priority)
|
||||||
{
|
{
|
||||||
if (!provider) return;
|
if (!provider) return;
|
||||||
|
std::string path = trimPathSeparators(normalizePath(virtualPath));
|
||||||
|
|
||||||
std::string normalizedPath = normalizePath(virtualPath);
|
std::unique_lock lock(_mutex);
|
||||||
normalizedPath = trimPathSeparators(normalizedPath);
|
|
||||||
|
|
||||||
std::unique_lock<std::shared_mutex> lock(_mutex);
|
_mounts.emplace_back(path, std::move(provider), priority);
|
||||||
|
|
||||||
_mounts.emplace_back(normalizedPath, std::move(provider), priority);
|
std::sort(_mounts.begin(), _mounts.end(), [](const MountPoint& a, const MountPoint& b) {
|
||||||
sortMounts();
|
if (a.priority != b.priority) return a.priority > b.priority;
|
||||||
|
return a.pathDepth > b.pathDepth;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VirtualFileSystem::unmount(const std::string& virtualPath)
|
bool VirtualFileSystem::unmount(const std::string& virtualPath)
|
||||||
@@ -84,64 +86,62 @@ void VirtualFileSystem::unmountAll()
|
|||||||
|
|
||||||
bool VirtualFileSystem::exists(const std::string& path) const
|
bool VirtualFileSystem::exists(const std::string& path) const
|
||||||
{
|
{
|
||||||
|
std::shared_lock lock(_mutex);
|
||||||
std::string relativePath;
|
std::string relativePath;
|
||||||
const MountPoint* mount = findBestMount(path, relativePath);
|
const MountPoint* mount = findBestMount(path, relativePath);
|
||||||
|
|
||||||
if (!mount) return false;
|
return mount ? mount->provider->exists(relativePath) : false;
|
||||||
|
|
||||||
return mount->provider->exists(relativePath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VFSResult VirtualFileSystem::readFile(const std::string& path, FileBuffer& out_buffer) const
|
VFSResult VirtualFileSystem::readFile(const std::string& path, FileBuffer& out_buffer) const
|
||||||
{
|
{
|
||||||
|
std::shared_lock lock(_mutex);
|
||||||
std::string relativePath;
|
std::string relativePath;
|
||||||
const MountPoint* mount = findBestMount(path, relativePath);
|
const MountPoint* mount = findBestMount(path, relativePath);
|
||||||
|
|
||||||
if (!mount) return VFSResult::FileNotFound;
|
if (!mount) return VFSResult::FileNotFound;
|
||||||
|
return mount->provider->readFile(relativePath, out_buffer);
|
||||||
VFSResult result = mount->provider->readFile(relativePath, out_buffer);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VFSResult VirtualFileSystem::writeFile(const std::string& path, const FileBuffer& buffer)
|
VFSResult VirtualFileSystem::writeFile(const std::string& path, const FileBuffer& buffer)
|
||||||
{
|
{
|
||||||
if (!buffer.isValid()) return VFSResult::Unknown;
|
if (!buffer.isValid()) return VFSResult::Unknown;
|
||||||
|
|
||||||
|
std::shared_lock lock(_mutex);
|
||||||
std::string relativePath;
|
std::string relativePath;
|
||||||
MountPoint* mount = findBestMount(path, relativePath);
|
MountPoint* mount = findBestMount(path, relativePath);
|
||||||
|
|
||||||
if (!mount) return VFSResult::AccessDenied;
|
if (!mount) return VFSResult::InvalidPath;
|
||||||
|
|
||||||
return mount->provider->writeFile(relativePath, buffer);
|
return mount->provider->writeFile(relativePath, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
VFSResult VirtualFileSystem::deleteFile(const std::string& path)
|
VFSResult VirtualFileSystem::deleteFile(const std::string& path)
|
||||||
{
|
{
|
||||||
|
std::shared_lock lock(_mutex);
|
||||||
std::string relativePath;
|
std::string relativePath;
|
||||||
MountPoint* mount = findBestMount(path, relativePath);
|
MountPoint* mount = findBestMount(path, relativePath);
|
||||||
|
|
||||||
if (!mount) return VFSResult::FileNotFound;
|
if (!mount) return VFSResult::FileNotFound;
|
||||||
|
|
||||||
return mount->provider->deleteFile(relativePath);
|
return mount->provider->deleteFile(relativePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
VFSResult VirtualFileSystem::createDirectory(const std::string& path)
|
VFSResult VirtualFileSystem::createDirectory(const std::string& path)
|
||||||
{
|
{
|
||||||
|
std::shared_lock lock(_mutex);
|
||||||
std::string relativePath;
|
std::string relativePath;
|
||||||
MountPoint* mount = findBestMount(path, relativePath);
|
MountPoint* mount = findBestMount(path, relativePath);
|
||||||
|
|
||||||
if (!mount) return VFSResult::InvalidPath;
|
if (!mount) return VFSResult::InvalidPath;
|
||||||
|
|
||||||
return mount->provider->createDirectory(relativePath);
|
return mount->provider->createDirectory(relativePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> VirtualFileSystem::listDirectory(const std::string& path) const
|
std::vector<std::string> VirtualFileSystem::listDirectory(const std::string& path) const
|
||||||
{
|
{
|
||||||
|
std::shared_lock lock(_mutex);
|
||||||
std::string relativePath;
|
std::string relativePath;
|
||||||
const MountPoint* mount = findBestMount(path, relativePath);
|
const MountPoint* mount = findBestMount(path, relativePath);
|
||||||
|
|
||||||
if (!mount) return {};
|
if (!mount) return {};
|
||||||
|
|
||||||
return mount->provider->listDirectory(relativePath);
|
return mount->provider->listDirectory(relativePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,7 +157,7 @@ std::string VirtualFileSystem::normalizePath(const std::string& path) const
|
|||||||
if (isPathSeparator(c))
|
if (isPathSeparator(c))
|
||||||
result += '/';
|
result += '/';
|
||||||
else
|
else
|
||||||
result += static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
|
result += c;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> parts;
|
std::vector<std::string> parts;
|
||||||
@@ -194,51 +194,36 @@ std::string VirtualFileSystem::normalizePath(const std::string& path) const
|
|||||||
const VirtualFileSystem::MountPoint* VirtualFileSystem::findBestMount(const std::string& path,
|
const VirtualFileSystem::MountPoint* VirtualFileSystem::findBestMount(const std::string& path,
|
||||||
std::string& relativePath) const
|
std::string& relativePath) const
|
||||||
{
|
{
|
||||||
std::string normalizedFullPath = normalizePath(path);
|
std::string searchPath = trimPathSeparators(normalizePath(path));
|
||||||
std::string searchPath = trimPathSeparators(normalizedFullPath);
|
|
||||||
|
|
||||||
std::shared_lock<std::shared_mutex> lock(_mutex);
|
|
||||||
|
|
||||||
for (const auto& mount : _mounts)
|
for (const auto& mount : _mounts)
|
||||||
{
|
{
|
||||||
bool match = false;
|
|
||||||
|
|
||||||
if (searchPath == mount.virtualPath)
|
if (searchPath == mount.virtualPath)
|
||||||
{
|
{
|
||||||
match = true;
|
|
||||||
relativePath = "/";
|
relativePath = "/";
|
||||||
}
|
return &mount;
|
||||||
else if (searchPath.length() > mount.virtualPath.length() && searchPath.find(mount.virtualPath + '/') == 0)
|
|
||||||
{
|
|
||||||
match = true;
|
|
||||||
relativePath = searchPath.substr(mount.virtualPath.length() + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (match)
|
if (mount.virtualPath == "/")
|
||||||
{
|
{
|
||||||
if (relativePath.empty()) relativePath = "/";
|
relativePath = searchPath;
|
||||||
|
return &mount;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string prefix = mount.virtualPath + '/';
|
||||||
|
if (searchPath.length() > prefix.length() && searchPath.compare(0, prefix.length(), prefix) == 0)
|
||||||
|
{
|
||||||
|
relativePath = searchPath.substr(prefix.length());
|
||||||
return &mount;
|
return &mount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtualFileSystem::MountPoint* VirtualFileSystem::findBestMount(const std::string& path, std::string& relativePath)
|
VirtualFileSystem::MountPoint* VirtualFileSystem::findBestMount(const std::string& path, std::string& relativePath)
|
||||||
{
|
{
|
||||||
const auto* constResult = const_cast<const VirtualFileSystem*>(this)->findBestMount(path, relativePath);
|
const auto* res = static_cast<const VirtualFileSystem*>(this)->findBestMount(path, relativePath);
|
||||||
return const_cast<MountPoint*>(constResult);
|
return const_cast<MountPoint*>(res);
|
||||||
}
|
|
||||||
|
|
||||||
void VirtualFileSystem::sortMounts()
|
|
||||||
{
|
|
||||||
for (auto& m : _mounts)
|
|
||||||
m.pathDepth = MountPoint::countPathDepth(m.virtualPath);
|
|
||||||
|
|
||||||
std::sort(_mounts.begin(), _mounts.end(), [](const MountPoint& a, const MountPoint& b) {
|
|
||||||
if (a.priority != b.priority) return a.priority > b.priority;
|
|
||||||
return a.pathDepth > b.pathDepth;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VirtualFileSystem::isPathSeparator(char c)
|
bool VirtualFileSystem::isPathSeparator(char c)
|
||||||
@@ -248,18 +233,11 @@ bool VirtualFileSystem::isPathSeparator(char c)
|
|||||||
|
|
||||||
std::string VirtualFileSystem::trimPathSeparators(const std::string& path)
|
std::string VirtualFileSystem::trimPathSeparators(const std::string& path)
|
||||||
{
|
{
|
||||||
if (path.empty()) return path;
|
size_t start = path.find_first_not_of("/\\");
|
||||||
|
if (start == std::string::npos) return "/";
|
||||||
|
|
||||||
size_t start = 0;
|
size_t end = path.find_last_not_of("/\\");
|
||||||
size_t end = path.length();
|
return path.substr(start, end - start + 1);
|
||||||
|
|
||||||
while (start < end && isPathSeparator(path[start]))
|
|
||||||
start++;
|
|
||||||
|
|
||||||
while (end > start && isPathSeparator(path[end - 1]))
|
|
||||||
end--;
|
|
||||||
|
|
||||||
return path.substr(start, end - start);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -97,7 +97,6 @@ namespace seallib
|
|||||||
const MountPoint* findBestMount(const std::string& path, std::string& relativePath) const;
|
const MountPoint* findBestMount(const std::string& path, std::string& relativePath) const;
|
||||||
MountPoint* findBestMount(const std::string& path, std::string& relativePath);
|
MountPoint* findBestMount(const std::string& path, std::string& relativePath);
|
||||||
|
|
||||||
void sortMounts();
|
|
||||||
static bool isPathSeparator(char c);
|
static bool isPathSeparator(char c);
|
||||||
static std::string trimPathSeparators(const std::string& path);
|
static std::string trimPathSeparators(const std::string& path);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user