summaryrefslogtreecommitdiff
path: root/include/fud_file.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'include/fud_file.hpp')
-rw-r--r--include/fud_file.hpp119
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