From 1c98d6cb372ceb443c29fdcacf7e0f3f5d694e4c Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 4 Feb 2025 17:38:43 +0300 Subject: [PATCH] update io::Device::write --- src/io/devices/Device.hpp | 35 +++++++++++++++++++++++++++++++--- src/io/devices/StdfsDevice.cpp | 8 ++++---- src/io/devices/StdfsDevice.hpp | 3 ++- src/io/io.cpp | 7 ++++--- src/io/io.hpp | 8 +++++++- src/io/path.hpp | 1 + 6 files changed, 50 insertions(+), 12 deletions(-) diff --git a/src/io/devices/Device.hpp b/src/io/devices/Device.hpp index 98666415..a3addaf5 100644 --- a/src/io/devices/Device.hpp +++ b/src/io/devices/Device.hpp @@ -8,27 +8,56 @@ #include "../path.hpp" namespace io { + + /// @brief Device interface for file system operations class Device { public: virtual ~Device() = default; + /// @brief Resolve path to the filesystem path 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 write(std::string_view path) = 0; + + /// @brief Open file for reading + /// @throw std::runtime_error if file cannot be opened virtual std::unique_ptr read(std::string_view path) = 0; + /// @brief Get file size in bytes virtual size_t size(std::string_view path) = 0; + /// @brief Check if file or directory exists virtual bool exists(std::string_view path) = 0; + + /// @brief Check if path is a directory virtual bool isdir(std::string_view path) = 0; + + /// @brief Check if path is a regular file 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; + + /// @brief Create directories recursively + /// @return true if directory was created 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; + + /// @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; + + /// @brief List directory contents virtual std::unique_ptr list(std::string_view path) = 0; }; + /// @brief Subdevice is a wrapper around another device limited to a directory class SubDevice : public Device { public: SubDevice( @@ -41,8 +70,8 @@ namespace io { return parent->resolve((root / path).pathPart()); } - void write(std::string_view path, const void* data, size_t size) override { - parent->write((root / path).pathPart(), data, size); + std::unique_ptr write(std::string_view path) override { + return parent->write((root / path).pathPart()); } std::unique_ptr read(std::string_view path) override { diff --git a/src/io/devices/StdfsDevice.cpp b/src/io/devices/StdfsDevice.cpp index e5009e00..cb47c2e6 100644 --- a/src/io/devices/StdfsDevice.cpp +++ b/src/io/devices/StdfsDevice.cpp @@ -26,13 +26,13 @@ fs::path StdfsDevice::resolve(std::string_view path) { 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 StdfsDevice::write(std::string_view path) { auto resolved = resolve(path); - std::ofstream output(resolved, std::ios::binary); - if (!output.is_open()) { + auto output = std::make_unique(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); + return output; } std::unique_ptr StdfsDevice::read(std::string_view path) { diff --git a/src/io/devices/StdfsDevice.hpp b/src/io/devices/StdfsDevice.hpp index 9112f2f9..ec1a9526 100644 --- a/src/io/devices/StdfsDevice.hpp +++ b/src/io/devices/StdfsDevice.hpp @@ -1,12 +1,13 @@ #include "Device.hpp" namespace io { + /// @brief Device based on the standard filesystem class StdfsDevice : public Device { public: StdfsDevice(std::filesystem::path root, bool createDirectory = true); 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 write(std::string_view path) override; std::unique_ptr read(std::string_view path) override; size_t size(std::string_view path) override; bool exists(std::string_view path) override; diff --git a/src/io/io.cpp b/src/io/io.cpp index efb241d4..bef794b4 100644 --- a/src/io/io.cpp +++ b/src/io/io.cpp @@ -90,10 +90,11 @@ bool io::write_bytes( ) { auto device = io::get_device(filename.entryPoint()); if (device == nullptr) { - return false; + throw std::runtime_error("io-device not found: " + filename.entryPoint()); } - device->write(filename.pathPart(), data, size); - return true; + auto stream = device->write(filename.pathPart()); + stream->write(reinterpret_cast(data), size); + return stream->good(); } bool io::read(const io::path& filename, char* data, size_t size) { diff --git a/src/io/io.hpp b/src/io/io.hpp index ba63688e..46582400 100644 --- a/src/io/io.hpp +++ b/src/io/io.hpp @@ -142,11 +142,17 @@ namespace io { 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 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 read_bytes_buffer(const path& file); std::unique_ptr read_bytes(const path& file, size_t& length); std::vector read_bytes(const path& file); + + /// @brief Read string from the file std::string read_string(const path& file); /// @brief Read JSON or BJSON file diff --git a/src/io/path.hpp b/src/io/path.hpp index 3911b1ef..4c35d824 100644 --- a/src/io/path.hpp +++ b/src/io/path.hpp @@ -5,6 +5,7 @@ #include namespace io { + /// @brief Access violation error class access_error : public std::runtime_error { public: access_error(const std::string& msg) : std::runtime_error(msg) {