diff options
Diffstat (limited to 'include/fud_file.hpp')
-rw-r--r-- | include/fud_file.hpp | 119 |
1 files changed, 96 insertions, 23 deletions
diff --git a/include/fud_file.hpp b/include/fud_file.hpp index 7a53468..82f8291 100644 --- a/include/fud_file.hpp +++ b/include/fud_file.hpp @@ -18,13 +18,13 @@ #ifndef FUD_FILE_HPP #define FUD_FILE_HPP +#include "fud_drain.hpp" #include "fud_option.hpp" #include "fud_permissions.hpp" #include "fud_result.hpp" #include "fud_status.hpp" #include "fud_string_view.hpp" #include "fud_vector.hpp" -#include "fud_drain.hpp" #include <fcntl.h> @@ -92,7 +92,8 @@ class OpenFlags { return mode; } - constexpr uint32_t flags() const noexcept { + constexpr uint32_t flags() const noexcept + { uint32_t openFlags = 0; openFlags |= static_cast<uint32_t>(hasFlag(OpenFlagEnum::Append)) * O_APPEND; openFlags |= static_cast<uint32_t>(hasFlag(OpenFlagEnum::Truncate)) * O_TRUNC; @@ -125,18 +126,15 @@ using FileResult = Result<RegularFile, FudStatus>; class RegularFile { public: - static FileResult open( - StringView filename, - FileAccessMode mode, - OpenFlags flags, - Option<int> dirFdoption); + friend class BufferedRegularFile; + static FileResult open(StringView filename, FileAccessMode mode, OpenFlags flags, Option<int> dirFdoption); static FileResult create( StringView filename, FileAccessMode mode, OpenFlags flags, Permissions permissions, - bool exclusive, + bool createOnly, Option<int> dirFdOption); FudStatus close(); @@ -145,13 +143,40 @@ class RegularFile { Result<size_t, FudStatus> size() const; + constexpr int fileDescriptor() const + { + return m_fd; + } + + [[nodiscard]] constexpr bool isOpen() const + { + return m_fd >= 0; + } + + FudStatus seekStart(); + + FudStatus seekEnd(); + + FudStatus seek(size_t position); + + /** \brief Write from source to file as sink. */ + DrainResult write(const std::byte* source, size_t length, size_t maxExtraAttempts = 0); + + DrainResult read(std::byte* sink, size_t length, size_t maxExtraAttempts = 0); + private: - RegularFile() = default; + constexpr RegularFile() = default; + + FudStatus validateIOParameters(const std::byte* source) const; public: RegularFile(const RegularFile& rhs) = delete; - RegularFile(RegularFile&& rhs) noexcept; + constexpr RegularFile(RegularFile&& rhs) noexcept : + m_position{rhs.m_position}, m_fd{rhs.m_fd}, m_openFlags{rhs.m_openFlags}, m_modeFlags{rhs.m_modeFlags} + { + rhs.m_fd = -1; + } ~RegularFile(); @@ -160,28 +185,76 @@ class RegularFile { RegularFile& operator=(RegularFile&& rhs) noexcept; private: + size_t m_position{0}; int m_fd{-1}; OpenFlags m_openFlags{}; FileAccessMode m_modeFlags{}; }; -enum class ReadPolicy { - Unbuffered, - ReadAhead, -}; - class BufferedRegularFile { -public: + public: + static BufferedRegularFile make(RegularFile&& file, Vector<std::byte>&& buffer = Vector<std::byte>::NullVector()); + + FudStatus close(bool discardBuffer); + /** \brief Write from source to file as sink. */ - DrainResult write(const std::byte* source, size_t sourceSize, size_t length, size_t offset); + DrainResult write(const std::byte* source, size_t length, Option<size_t> maxExtraAttempts); + /** \brief Read from file as source to sink. */ - DrainResult read(std::byte* sink, size_t sinkSize, size_t length, size_t offset); -private: - Vector<std::byte> m_readBuffer{Vector<std::byte>::NullVector()}; - Vector<std::byte> m_writeBuffer{Vector<std::byte>::NullVector()}; + DrainResult read(std::byte* sink, size_t length, Option<size_t> maxExtraAttempts); + + FudStatus setBuffer(Vector<std::byte>&& buffer, bool discardOldBuffer); + + DrainResult flush(size_t maxExtraAttempts = 0); + + void discard(); + + FudStatus resizeBuffer(size_t size); + + FudStatus seekStart(); + + FudStatus seekEnd(); + + FudStatus seek(size_t position); + + constexpr const RegularFile& file() const + { + return m_file; + } + + constexpr RegularFile& file() + { + return m_file; + } + + [[nodiscard]] constexpr bool bufferEmpty() const + { + return m_bufferLength == 0; + } + + private: + constexpr BufferedRegularFile() noexcept = default; + + constexpr BufferedRegularFile(RegularFile&& regularFile, Vector<std::byte>&& buffer) noexcept : + m_buffer{std::move(buffer)}, m_file{std::move(regularFile)} + { + } + + Vector<std::byte> m_buffer{Vector<std::byte>::NullVector()}; + RegularFile m_file; - bool m_readBuffered{false}; - bool m_writeBuffered{false}; + + size_t m_bufferLength{0}; + size_t m_bufferPosition{0}; + + enum class Operation : uint8_t + { + None, + Write, + Read + }; + + Operation m_lastOperation{Operation::None}; }; } // namespace fud |