|
|
- #pragma once
-
- #include <stddef.h>
- #include "gp_config.hpp"
- #include "gp/variant.hpp"
- #include "gp/optional.hpp"
- #include "gp/buffer.hpp"
- #include "gp/allocator/aggregator.hpp"
-
- namespace gp {
- class vfs {
- public:
- struct bad_file final {
- static constexpr auto _what = "bad_file";
- constexpr auto what() {
- return _what;
- }
- };
- struct faulty_buffer final {
- static constexpr auto _what = "faulty_buffer";
- constexpr auto what() {
- return _what;
- }
- };
- struct interrupted final {
- static constexpr auto _what = "interrupted";
- constexpr auto what() {
- return _what;
- }
- };
- struct io_error final {
- static constexpr auto _what = "io_error";
- constexpr auto what() {
- return _what;
- }
- };
- struct is_directory final {
- static constexpr auto _what = "is_directory";
- constexpr auto what() {
- return _what;
- }
- };
- struct try_again final {
- static constexpr auto _what = "try_again";
- constexpr auto what() {
- return _what;
- }
- };
- struct not_connected final {
- static constexpr auto _what = "not_connected";
- constexpr auto what() {
- return _what;
- }
- };
- struct impossible_io final {
- static constexpr auto _what = "impossible_io";
- constexpr auto what() {
- return _what;
- }
- };
- struct negative_offset final {
- static constexpr auto _what = "negative_offset";
- constexpr auto what() {
- return _what;
- }
- };
- struct is_pipe final {
- static constexpr auto _what = "is_pipe";
- constexpr auto what() {
- return _what;
- }
- };
- struct buffer_too_big final {
- static constexpr auto _what = "buffer_too_big";
- constexpr auto what() {
- return _what;
- }
- };
- struct path_not_directory final {
- static constexpr auto _what = "path_not_directory";
- constexpr auto what() {
- return _what;
- }
- };
- struct name_too_long final {
- static constexpr auto _what = "name_too_long";
- constexpr auto what() {
- return _what;
- }
- };
- struct does_not_exist final {
- static constexpr auto _what = "does_not_exist";
- constexpr auto what() {
- return _what;
- }
- };
- struct may_loop final {
- static constexpr auto _what = "may_loop";
- constexpr auto what() {
- return _what;
- }
- };
- struct invalid_flags final {
- static constexpr auto _what = "invalid_flags";
- constexpr auto what() {
- return _what;
- }
- };
- struct is_read_only final {
- static constexpr auto _what = "is_read_only";
- constexpr auto what() {
- return _what;
- }
- };
- struct fd_limit_reached final {
- static constexpr auto _what = "fd_limit_reached";
- constexpr auto what() {
- return _what;
- }
- };
- struct file_limit_reached final {
- static constexpr auto _what = "file_limit_reached";
- constexpr auto what() {
- return _what;
- }
- };
- struct no_locking final {
- static constexpr auto _what = "no_locking";
- constexpr auto what() {
- return _what;
- }
- };
- struct would_block final {
- static constexpr auto _what = "would_block";
- constexpr auto what() {
- return _what;
- }
- };
- struct no_inodes final {
- static constexpr auto _what = "no_inodes";
- constexpr auto what() {
- return _what;
- }
- };
- struct no_space final {
- static constexpr auto _what = "no_space";
- constexpr auto what() {
- return _what;
- }
- };
- struct quota_reached final {
- static constexpr auto _what = "quota_reached";
- constexpr auto what() {
- return _what;
- }
- };
- struct cannot_write_shared_text final {
- static constexpr auto _what = "cannot_write_shared_text";
- constexpr auto what() {
- return _what;
- }
- };
- struct faulty_filename final {
- static constexpr auto _what = "faulty_filename";
- constexpr auto what() {
- return _what;
- }
- };
- struct exists_already final {
- static constexpr auto _what = "exists_already";
- constexpr auto what() {
- return _what;
- }
- };
- struct is_append_only final {
- static constexpr auto _what = "is_append_only";
- constexpr auto what() {
- return _what;
- }
- };
- struct unimplemented_operation final {
- static constexpr auto _what = "unimplemented_operation";
- constexpr auto what() {
- return _what;
- }
- };
- struct is_busy final {
- static constexpr auto _what = "is_busy";
- constexpr auto what() {
- return _what;
- }
- };
- struct bad_relative_path final {
- static constexpr auto _what = "bad_relative_path";
- constexpr auto what() {
- return _what;
- }
- };
- struct no_permissions final {
- static constexpr auto _what = "no_permissions";
- constexpr auto what() {
- return _what;
- }
- };
- struct success final {
- static constexpr auto _what = "success";
- constexpr auto what() {
- return _what;
- }
- };
- struct too_big final {
- static constexpr auto _what = "too_big";
- constexpr auto what() {
- return _what;
- }
- };
- struct network_down final {
- static constexpr auto _what = "network_down";
- constexpr auto what() {
- return _what;
- }
- };
- struct destination_not_available final {
- static constexpr auto _what = "destination_not_available";
- constexpr auto what() {
- return _what;
- }
- };
- struct insufficient_buffer_space final {
- static constexpr auto _what = "insufficient_buffer_space";
- constexpr auto what() {
- return _what;
- }
- };
-
- using read_return = gp::fixed_variant<
- typename buffer<char>::associated_iterator, // iterator to last element read
- bad_file,
- faulty_buffer,
- interrupted,
- io_error,
- is_directory,
- try_again,
- not_connected,
- impossible_io,
- negative_offset,
- is_pipe,
- buffer_too_big
- >;
-
- using open_return = gp::fixed_variant<
- gp_config::file_descriptor_t,
- path_not_directory,
- name_too_long,
- does_not_exist,
- may_loop,
- is_directory,
- invalid_flags,
- is_read_only,
- fd_limit_reached,
- file_limit_reached,
- impossible_io,
- interrupted,
- no_locking,
- would_block,
- no_space,
- no_inodes,
- quota_reached,
- io_error,
- cannot_write_shared_text,
- faulty_filename,
- exists_already,
- is_append_only,
- unimplemented_operation,
- is_busy,
- bad_relative_path,
- no_permissions
- >;
-
- using close_return = gp::fixed_variant<
- success,
- bad_file,
- interrupted,
- io_error
- >;
-
- using write_return = gp::fixed_variant<
- typename buffer<char>::associated_iterator,
- bad_file,
- no_space,
- quota_reached,
- too_big,
- interrupted,
- io_error,
- faulty_buffer,
- is_pipe,
- try_again,
- network_down,
- destination_not_available,
- impossible_io,
- buffer_too_big,
- negative_offset,
- insufficient_buffer_space
- >;
-
- class file_flags{};
- class file_permissions{};
-
- private:
- struct virtual_fs
- {
- virtual ~virtual_fs() = default;
- virtual open_return open(buffer<char>, file_flags, file_permissions) = 0;
- virtual read_return read(gp_config::file_descriptor_t, buffer<char>) = 0;
- virtual write_return write(gp_config::file_descriptor_t, buffer<char>, size_t) = 0;
- virtual 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 open_return open(buffer<char> path, file_flags flags, file_permissions perms) override {
- return internal_representation.open(path, flags, perms);
- }
-
-
- virtual read_return read(gp_config::file_descriptor_t fd, buffer<char> buff) override {
- return internal_representation.read(fd, buff);
- }
-
- virtual write_return write(gp_config::file_descriptor_t fd, buffer<char> buff, size_t offset) override {
- return internal_representation.write(fd, buff, offset);
- }
-
- virtual 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))}
- {}
-
- open_return open(buffer<char> path, file_flags flags, file_permissions perms) {
- return file_system->open(path, flags, perms);
- }
-
-
- read_return read(gp_config::file_descriptor_t fd, buffer<char> buff) {
- return file_system->read(fd, buff);
- }
-
- write_return write(gp_config::file_descriptor_t fd, buffer<char> buff, size_t offset) {
- return file_system->write(fd, buff, offset);
- }
-
- close_return close(gp_config::file_descriptor_t fd) {
- return file_system->close(fd);
- }
-
- ~vfs() {
- file_system->~virtual_fs();
- allocator.get().deallocate(file_system);
- }
- };
- }
|