VoxelEngine/src/io/devices/StdfsDevice.cpp
2025-02-04 14:10:23 +03:00

128 lines
3.4 KiB
C++

#include "StdfsDevice.hpp"
#include <fstream>
#include <filesystem>
#include "debug/Logger.hpp"
using namespace io;
namespace fs = std::filesystem;
static debug::Logger logger("io-stdfs");
StdfsDevice::StdfsDevice(fs::path root, bool createDirectory)
: root(std::move(root)) {
if (createDirectory && !fs::is_directory(this->root)) {
std::error_code ec;
fs::create_directories(this->root, ec);
if (ec) {
logger.error() << "error creating root directory " << this->root
<< ": " << ec.message();
}
}
}
fs::path StdfsDevice::resolve(std::string_view path) {
return root / fs::u8path(path);
}
void StdfsDevice::write(std::string_view path, const void* data, size_t size) {
auto resolved = resolve(path);
std::ofstream output(resolved, std::ios::binary);
if (!output.is_open()) {
throw std::runtime_error("could not to open file " + resolved.u8string());
}
output.write((const char*)data, size);
}
void StdfsDevice::read(std::string_view path, void* data, size_t size) {
auto resolved = resolve(path);
std::ifstream input(resolved, std::ios::binary);
if (!input.is_open()) {
throw std::runtime_error("could not to open file " + resolved.u8string());
}
input.read((char*)data, size);
}
size_t StdfsDevice::size(std::string_view path) {
auto resolved = resolve(path);
return fs::file_size(resolved);
}
bool StdfsDevice::exists(std::string_view path) {
auto resolved = resolve(path);
return fs::exists(resolved);
}
bool StdfsDevice::isdir(std::string_view path) {
auto resolved = resolve(path);
return fs::is_directory(resolved);
}
bool StdfsDevice::isfile(std::string_view path) {
auto resolved = resolve(path);
return fs::is_regular_file(resolved);
}
bool StdfsDevice::mkdir(std::string_view path) {
auto resolved = resolve(path);
std::error_code ec;
bool created = fs::create_directory(resolved, ec);
if (ec) {
logger.error() << "error creating directory " << resolved << ": "
<< ec.message();
}
return created;
}
bool StdfsDevice::mkdirs(std::string_view path) {
auto resolved = resolve(path);
std::error_code ec;
bool created = fs::create_directories(resolved, ec);
if (ec) {
logger.error() << "error creating directories " << resolved << ": "
<< ec.message();
}
return created;
}
bool StdfsDevice::remove(std::string_view path) {
auto resolved = resolve(path);
return fs::remove(resolved);
}
uint64_t StdfsDevice::removeAll(std::string_view path) {
auto resolved = resolve(path);
if (fs::exists(resolved)) {
logger.info() << "removeAll " << resolved;
return fs::remove_all(resolved);
} else {
return 0;
}
}
class StdfsPathsGenerator : public PathsGenerator {
public:
StdfsPathsGenerator(fs::path root) : root(std::move(root)) {
it = fs::directory_iterator(this->root);
}
bool next(io::path& path) override {
if (it == fs::directory_iterator()) {
return false;
}
path = it->path().filename().u8string();
it++;
return true;
}
private:
fs::path root;
fs::directory_iterator it;
};
std::unique_ptr<PathsGenerator> StdfsDevice::list(std::string_view path) {
return std::make_unique<StdfsPathsGenerator>(root / fs::u8path(path));
}