update io::Device::write

This commit is contained in:
MihailRis
2025-02-04 17:38:43 +03:00
parent 3e67d887f4
commit 1c98d6cb37
6 changed files with 50 additions and 12 deletions
+32 -3
View File
@@ -8,27 +8,56 @@
#include "../path.hpp" #include "../path.hpp"
namespace io { namespace io {
/// @brief Device interface for file system operations
class Device { class Device {
public: public:
virtual ~Device() = default; virtual ~Device() = default;
/// @brief Resolve path to the filesystem path
virtual std::filesystem::path resolve(std::string_view path) = 0; virtual std::filesystem::path resolve(std::string_view path) = 0;
virtual void write(std::string_view path, const void* data, size_t size) = 0; /// @brief Open file for writing
/// @throw std::runtime_error if file cannot be opened
virtual std::unique_ptr<std::ostream> write(std::string_view path) = 0;
/// @brief Open file for reading
/// @throw std::runtime_error if file cannot be opened
virtual std::unique_ptr<std::istream> read(std::string_view path) = 0; virtual std::unique_ptr<std::istream> read(std::string_view path) = 0;
/// @brief Get file size in bytes
virtual size_t size(std::string_view path) = 0; virtual size_t size(std::string_view path) = 0;
/// @brief Check if file or directory exists
virtual bool exists(std::string_view path) = 0; virtual bool exists(std::string_view path) = 0;
/// @brief Check if path is a directory
virtual bool isdir(std::string_view path) = 0; virtual bool isdir(std::string_view path) = 0;
/// @brief Check if path is a regular file
virtual bool isfile(std::string_view path) = 0; virtual bool isfile(std::string_view path) = 0;
/// @brief Create directory
/// @return true if directory was created
virtual bool mkdir(std::string_view path) = 0; virtual bool mkdir(std::string_view path) = 0;
/// @brief Create directories recursively
/// @return true if directory was created
virtual bool mkdirs(std::string_view path) = 0; virtual bool mkdirs(std::string_view path) = 0;
/// @brief Remove file or empty directory
/// @return true if file or directory was removed
virtual bool remove(std::string_view path) = 0; virtual bool remove(std::string_view path) = 0;
/// @brief Remove all files and directories in the folder recursively
/// @return number of removed files and directories
virtual uint64_t removeAll(std::string_view path) = 0; virtual uint64_t removeAll(std::string_view path) = 0;
/// @brief List directory contents
virtual std::unique_ptr<PathsGenerator> list(std::string_view path) = 0; virtual std::unique_ptr<PathsGenerator> list(std::string_view path) = 0;
}; };
/// @brief Subdevice is a wrapper around another device limited to a directory
class SubDevice : public Device { class SubDevice : public Device {
public: public:
SubDevice( SubDevice(
@@ -41,8 +70,8 @@ namespace io {
return parent->resolve((root / path).pathPart()); return parent->resolve((root / path).pathPart());
} }
void write(std::string_view path, const void* data, size_t size) override { std::unique_ptr<std::ostream> write(std::string_view path) override {
parent->write((root / path).pathPart(), data, size); return parent->write((root / path).pathPart());
} }
std::unique_ptr<std::istream> read(std::string_view path) override { std::unique_ptr<std::istream> read(std::string_view path) override {
+4 -4
View File
@@ -26,13 +26,13 @@ fs::path StdfsDevice::resolve(std::string_view path) {
return root / fs::u8path(io::path(std::string(path)).normalized().string()); return root / fs::u8path(io::path(std::string(path)).normalized().string());
} }
void StdfsDevice::write(std::string_view path, const void* data, size_t size) { std::unique_ptr<std::ostream> StdfsDevice::write(std::string_view path) {
auto resolved = resolve(path); auto resolved = resolve(path);
std::ofstream output(resolved, std::ios::binary); auto output = std::make_unique<std::ofstream>(resolved, std::ios::binary);
if (!output.is_open()) { if (!output->is_open()) {
throw std::runtime_error("could not to open file " + resolved.u8string()); throw std::runtime_error("could not to open file " + resolved.u8string());
} }
output.write((const char*)data, size); return output;
} }
std::unique_ptr<std::istream> StdfsDevice::read(std::string_view path) { std::unique_ptr<std::istream> StdfsDevice::read(std::string_view path) {
+2 -1
View File
@@ -1,12 +1,13 @@
#include "Device.hpp" #include "Device.hpp"
namespace io { namespace io {
/// @brief Device based on the standard filesystem
class StdfsDevice : public Device { class StdfsDevice : public Device {
public: public:
StdfsDevice(std::filesystem::path root, bool createDirectory = true); StdfsDevice(std::filesystem::path root, bool createDirectory = true);
std::filesystem::path resolve(std::string_view path) override; std::filesystem::path resolve(std::string_view path) override;
void write(std::string_view path, const void* data, size_t size) override; std::unique_ptr<std::ostream> write(std::string_view path) override;
std::unique_ptr<std::istream> read(std::string_view path) override; std::unique_ptr<std::istream> read(std::string_view path) override;
size_t size(std::string_view path) override; size_t size(std::string_view path) override;
bool exists(std::string_view path) override; bool exists(std::string_view path) override;
+4 -3
View File
@@ -90,10 +90,11 @@ bool io::write_bytes(
) { ) {
auto device = io::get_device(filename.entryPoint()); auto device = io::get_device(filename.entryPoint());
if (device == nullptr) { if (device == nullptr) {
return false; throw std::runtime_error("io-device not found: " + filename.entryPoint());
} }
device->write(filename.pathPart(), data, size); auto stream = device->write(filename.pathPart());
return true; stream->write(reinterpret_cast<const char*>(data), size);
return stream->good();
} }
bool io::read(const io::path& filename, char* data, size_t size) { bool io::read(const io::path& filename, char* data, size_t size) {
+7 -1
View File
@@ -142,11 +142,17 @@ namespace io {
bool compressed = false bool compressed = false
); );
bool read(const io::path& file, char* data, size_t size); /// @brief Open file for reading
/// @throw std::runtime_error if file cannot be opened
std::unique_ptr<std::istream> read(const io::path& file); std::unique_ptr<std::istream> read(const io::path& file);
/// @brief Read bytes array from the file
bool read(const io::path& file, char* data, size_t size);
util::Buffer<ubyte> read_bytes_buffer(const path& file); util::Buffer<ubyte> read_bytes_buffer(const path& file);
std::unique_ptr<ubyte[]> read_bytes(const path& file, size_t& length); std::unique_ptr<ubyte[]> read_bytes(const path& file, size_t& length);
std::vector<ubyte> read_bytes(const path& file); std::vector<ubyte> read_bytes(const path& file);
/// @brief Read string from the file
std::string read_string(const path& file); std::string read_string(const path& file);
/// @brief Read JSON or BJSON file /// @brief Read JSON or BJSON file
+1
View File
@@ -5,6 +5,7 @@
#include <filesystem> #include <filesystem>
namespace io { namespace io {
/// @brief Access violation error
class access_error : public std::runtime_error { class access_error : public std::runtime_error {
public: public:
access_error(const std::string& msg) : std::runtime_error(msg) { access_error(const std::string& msg) : std::runtime_error(msg) {