|
@ -1,319 +1,22 @@ |
|
|
#pragma once
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
#include <stddef.h>
|
|
|
#include <stddef.h>
|
|
|
#include "gp_config.hpp"
|
|
|
#include "gp_config.hpp"
|
|
|
#include "gp/variant.hpp"
|
|
|
#include "gp/variant.hpp"
|
|
|
#include "gp/optional.hpp"
|
|
|
#include "gp/optional.hpp"
|
|
|
#include "gp/buffer.hpp"
|
|
|
#include "gp/buffer.hpp"
|
|
|
|
|
|
#include "gp/vfs/fs_types.hpp"
|
|
|
#include "gp/allocator/aggregator.hpp"
|
|
|
#include "gp/allocator/aggregator.hpp"
|
|
|
|
|
|
|
|
|
namespace gp { |
|
|
namespace gp { |
|
|
class vfs { |
|
|
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: |
|
|
private: |
|
|
struct virtual_fs |
|
|
struct virtual_fs |
|
|
{ |
|
|
{ |
|
|
virtual ~virtual_fs() = default; |
|
|
virtual ~virtual_fs() = default; |
|
|
virtual open_return f">open(buffer<char>, file_flags, file_permissions) = 0; |
|
|
|
|
|
virtual read_return f">read(gp_config::file_descriptor_t, buffer<char>) = 0; |
|
|
|
|
|
virtual write_return f">write(gp_config::file_descriptor_t, buffer<char>, size_t) = 0; |
|
|
|
|
|
virtual close_return f">close(gp_config::file_descriptor_t) = 0; |
|
|
|
|
|
|
|
|
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> |
|
|
template<typename concrete> |
|
@ -332,20 +35,20 @@ namespace gp { |
|
|
|
|
|
|
|
|
virtual ~abstract_fs() override = default; |
|
|
virtual ~abstract_fs() override = default; |
|
|
|
|
|
|
|
|
virtual open_return f">open(buffer<char> path, file_flags flags, file_permissions perms) override { |
|
|
|
|
|
|
|
|
virtual fs::open_return open(buffer<char> path, fs::file_flags flags, fs::file_permissions perms) override { |
|
|
return internal_representation.open(path, flags, perms); |
|
|
return internal_representation.open(path, flags, perms); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
virtual read_return f">read(gp_config::file_descriptor_t fd, buffer<char> buff) override { |
|
|
|
|
|
|
|
|
virtual fs::read_return read(gp_config::file_descriptor_t fd, buffer<char> buff) override { |
|
|
return internal_representation.read(fd, buff); |
|
|
return internal_representation.read(fd, buff); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
virtual write_return f">write(gp_config::file_descriptor_t fd, buffer<char> buff, size_t offset) override { |
|
|
|
|
|
|
|
|
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); |
|
|
return internal_representation.write(fd, buff, offset); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
virtual close_return f">close(gp_config::file_descriptor_t fd) override { |
|
|
|
|
|
|
|
|
virtual fs::close_return close(gp_config::file_descriptor_t fd) override { |
|
|
return internal_representation.close(fd); |
|
|
return internal_representation.close(fd); |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
@ -360,20 +63,20 @@ namespace gp { |
|
|
, file_system{new(allocator.get().allocate(sizeof(T))) T(gp::move(v))} |
|
|
, file_system{new(allocator.get().allocate(sizeof(T))) T(gp::move(v))} |
|
|
{} |
|
|
{} |
|
|
|
|
|
|
|
|
open_return f">open(buffer<char> path, file_flags flags, file_permissions perms) { |
|
|
|
|
|
|
|
|
fs::open_return open(buffer<char> path, fs::file_flags flags, fs::file_permissions perms) { |
|
|
return file_system->open(path, flags, perms); |
|
|
return file_system->open(path, flags, perms); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
read_return f">read(gp_config::file_descriptor_t fd, buffer<char> buff) { |
|
|
|
|
|
|
|
|
fs::read_return read(gp_config::file_descriptor_t fd, buffer<char> buff) { |
|
|
return file_system->read(fd, buff); |
|
|
return file_system->read(fd, buff); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
write_return f">write(gp_config::file_descriptor_t fd, buffer<char> buff, size_t offset) { |
|
|
|
|
|
|
|
|
fs::write_return write(gp_config::file_descriptor_t fd, buffer<char> buff, size_t offset) { |
|
|
return file_system->write(fd, buff, offset); |
|
|
return file_system->write(fd, buff, offset); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
close_return f">close(gp_config::file_descriptor_t fd) { |
|
|
|
|
|
|
|
|
fs::close_return close(gp_config::file_descriptor_t fd) { |
|
|
return file_system->close(fd); |
|
|
return file_system->close(fd); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|