#pragma once
|
|
|
|
#include "gp_config.hpp"
|
|
|
|
#include "gp/allocator/aggregator.hpp"
|
|
#include "gp/buffer.hpp"
|
|
#include "gp/optional.hpp"
|
|
#include "gp/variant.hpp"
|
|
#include "gp/vfs/fs_types.hpp"
|
|
|
|
#include <stddef.h>
|
|
|
|
namespace gp {
|
|
class vfs {
|
|
private:
|
|
struct virtual_fs
|
|
{
|
|
virtual ~virtual_fs() = default;
|
|
virtual fs::open_return open(buffer<char>, fs::file_flags, fs::file_permissions) = 0;
|
|
virtual fs::read_return read(gp_config::file_descriptor_t, buffer<char>) = 0;
|
|
virtual fs::write_return write(gp_config::file_descriptor_t, buffer<char>, size_t) = 0;
|
|
virtual fs::close_return close(gp_config::file_descriptor_t) = 0;
|
|
};
|
|
|
|
template<typename concrete>
|
|
class abstract_fs final : public virtual_fs{
|
|
concrete internal_representation;
|
|
public:
|
|
abstract_fs(abstract_fs& v) = delete;
|
|
abstract_fs(abstract_fs&& v)
|
|
: internal_representation{v.internal_representation}
|
|
{}
|
|
|
|
abstract_fs(concrete& v) = delete;
|
|
abstract_fs(concrete&& v)
|
|
: internal_representation{v}
|
|
{}
|
|
|
|
virtual ~abstract_fs() override = default;
|
|
|
|
virtual fs::open_return open(buffer<char> path, fs::file_flags flags, fs::file_permissions perms) override {
|
|
return internal_representation.open(path, flags, perms);
|
|
}
|
|
|
|
|
|
virtual fs::read_return read(gp_config::file_descriptor_t fd, buffer<char> buff) override {
|
|
return internal_representation.read(fd, buff);
|
|
}
|
|
|
|
virtual fs::write_return write(gp_config::file_descriptor_t fd, buffer<char> buff, size_t offset) override {
|
|
return internal_representation.write(fd, buff, offset);
|
|
}
|
|
|
|
virtual fs::close_return close(gp_config::file_descriptor_t fd) override {
|
|
return internal_representation.close(fd);
|
|
}
|
|
};
|
|
|
|
reference_wrapper<aggregator> allocator;
|
|
virtual_fs* file_system;
|
|
|
|
public:
|
|
template<typename T>
|
|
vfs(T&& v, reference_wrapper<aggregator> _ref)
|
|
: allocator{_ref}
|
|
, file_system{new(allocator.get().allocate(sizeof(T))) T(gp::move(v))}
|
|
{}
|
|
|
|
fs::open_return open(buffer<char> path, fs::file_flags flags, fs::file_permissions perms) {
|
|
return file_system->open(path, flags, perms);
|
|
}
|
|
|
|
|
|
fs::read_return read(gp_config::file_descriptor_t fd, buffer<char> buff) {
|
|
return file_system->read(fd, buff);
|
|
}
|
|
|
|
fs::write_return write(gp_config::file_descriptor_t fd, buffer<char> buff, size_t offset) {
|
|
return file_system->write(fd, buff, offset);
|
|
}
|
|
|
|
fs::close_return close(gp_config::file_descriptor_t fd) {
|
|
return file_system->close(fd);
|
|
}
|
|
|
|
~vfs() {
|
|
file_system->~virtual_fs();
|
|
allocator.get().deallocate(file_system);
|
|
}
|
|
};
|
|
}
|