diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/fud_drain.hpp | 2 | ||||
-rw-r--r-- | include/fud_file.hpp | 119 | ||||
-rw-r--r-- | include/fud_string.hpp | 17 | ||||
-rw-r--r-- | include/fud_vector.hpp | 7 |
4 files changed, 116 insertions, 29 deletions
diff --git a/include/fud_drain.hpp b/include/fud_drain.hpp index d630bc7..13c878a 100644 --- a/include/fud_drain.hpp +++ b/include/fud_drain.hpp @@ -32,6 +32,8 @@ struct DrainResult { { return status == FudStatus::Success; } + + constexpr bool operator==(const DrainResult&) const noexcept = default; }; template <typename Sink, typename Source> 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 diff --git a/include/fud_string.hpp b/include/fud_string.hpp index 935e1c1..a20b067 100644 --- a/include/fud_string.hpp +++ b/include/fud_string.hpp @@ -307,22 +307,31 @@ class String { * length is greater than zero. */ Option<utf8> pop(); + /** \brief Append a C string to the back of the string, growing it as necessary. */ FudStatus append(const char* source); + /** \brief Append a String to the back of the string, growing it as necessary. */ FudStatus append(const String& source); + /** \brief Append a StringView to the back of the string, growing it as necessary. */ FudStatus append(StringView source); + /** \brief Create a new string with the contents of this string and rhs. */ + [[nodiscard]] StringResult catenate(const String& rhs) const; + + /** \@copydoc String::catenate(const String& rhs) const */ + [[nodiscard]] StringResult catenate(const char* rhs) const; + + /** \brief Insert as much of source into the string as possible, returning + * how many bytes and the status of the insertion. */ DrainResult drain(const char* source); + /** @copydoc String::drain(const char* source) */ DrainResult drain(const String& source); + /** @copydoc String::drain(const char* source) */ DrainResult drain(StringView source); - [[nodiscard]] StringResult catenate(const String& rhs) const; - - [[nodiscard]] StringResult catenate(const char* rhs) const; - [[nodiscard]] bool compare(const String& rhs) const; FudStatus clear(); diff --git a/include/fud_vector.hpp b/include/fud_vector.hpp index a2a0984..9159770 100644 --- a/include/fud_vector.hpp +++ b/include/fud_vector.hpp @@ -120,7 +120,7 @@ class Vector { static Result<Vector<T>, FudStatus> withSize(size_t count, Allocator* allocator = &globalFudAllocator) { Vector<T> output{}; - auto status = initializeWithCapacity(output, count, allocator); + auto status = initializeWithSize(output, count, allocator); if (status != FudStatus::Success) { return FudError{status}; } @@ -402,7 +402,10 @@ class Vector { FudStatus clear() { if (m_allocator == nullptr || m_data == nullptr) { - return FudStatus::ObjectInvalid; + if (m_length > 0) { + return FudStatus::ObjectInvalid; + } + return FudStatus::Success; } for (size_t index = 0; index < m_length; ++index) { m_data[index].~T(); |