From f2f001b19011f7c3bb5f0653214b520a45bd2835 Mon Sep 17 00:00:00 2001 From: Green Sky Date: Sun, 26 May 2024 21:32:44 +0200 Subject: [PATCH] refactor file2 and add span with ownership --- solanaceae/file/file2.hpp | 26 +++++++++++++++++++++++++- solanaceae/file/file2_mem.cpp | 9 +++++---- solanaceae/file/file2_mem.hpp | 4 ++-- solanaceae/file/file2_stack.hpp | 32 ++++++++++++++++++++++++++++++++ solanaceae/file/file2_std.cpp | 9 +++++---- solanaceae/file/file2_std.hpp | 4 ++-- solanaceae/util/span.hpp | 2 +- 7 files changed, 72 insertions(+), 14 deletions(-) create mode 100644 solanaceae/file/file2_stack.hpp diff --git a/solanaceae/file/file2.hpp b/solanaceae/file/file2.hpp index 1ede998..eaa9d3b 100644 --- a/solanaceae/file/file2.hpp +++ b/solanaceae/file/file2.hpp @@ -5,6 +5,29 @@ #include #include +// TODO: move to/next-to span +// a span that can also represent its ownership +template +struct SpanWithOwnership : public Span { + // TODO: allow for different owners + std::vector _data_owner; + + // self interactions + SpanWithOwnership(void) = delete; + constexpr SpanWithOwnership(const SpanWithOwnership&) = delete; + constexpr SpanWithOwnership(SpanWithOwnership&&) = default; + + // non-owning + constexpr SpanWithOwnership(const Span& span) : Span(span) {} + constexpr SpanWithOwnership(const Span&& span) : Span(span) {} + + // owning + constexpr SpanWithOwnership(std::vector&& data) : Span(data), _data_owner(std::move(data)) {} + + bool isOwning(void) const { return !_data_owner.empty(); } +}; +using ByteSpanWithOwnership = SpanWithOwnership; + struct File2I { // read only uint64_t _file_size {0}; @@ -20,6 +43,7 @@ struct File2I { // pos -1 means stream, append to last written, or read position (independent, like FILE*s) virtual bool write(const ByteSpan data, int64_t pos = -1) = 0; - [[nodiscard]] virtual std::variant> read(uint64_t size, int64_t pos = -1) = 0; + //[[nodiscard]] virtual std::variant> read(uint64_t size, int64_t pos = -1) = 0; + [[nodiscard]] virtual ByteSpanWithOwnership read(uint64_t size, int64_t pos = -1) = 0; }; diff --git a/solanaceae/file/file2_mem.cpp b/solanaceae/file/file2_mem.cpp index 9944157..1d65ab1 100644 --- a/solanaceae/file/file2_mem.cpp +++ b/solanaceae/file/file2_mem.cpp @@ -25,8 +25,8 @@ bool File2MemW::write(const ByteSpan data, int64_t pos) { return isGood(); } -std::variant> File2MemW::read(uint64_t size, int64_t pos) { - return {}; +ByteSpanWithOwnership File2MemW::read(uint64_t size, int64_t pos) { + return ByteSpan{}; } File2MemR::File2MemR(ByteSpan mem) : File2I(false, true), _mem(mem) { @@ -44,9 +44,9 @@ bool File2MemR::write(const ByteSpan data, int64_t pos) { return false; } -std::variant> File2MemR::read(uint64_t size, int64_t pos) { +ByteSpanWithOwnership File2MemR::read(uint64_t size, int64_t pos) { if (_read_pos >= _mem.size) { - return {}; + return ByteSpan{}; } ByteSpan ret { @@ -54,6 +54,7 @@ std::variant> File2MemR::read(uint64_t size, int6 std::min(size, _mem.size - _read_pos) }; _read_pos += ret.size; + // return non-owning return ret; } diff --git a/solanaceae/file/file2_mem.hpp b/solanaceae/file/file2_mem.hpp index 5b24383..be823fd 100644 --- a/solanaceae/file/file2_mem.hpp +++ b/solanaceae/file/file2_mem.hpp @@ -14,7 +14,7 @@ struct File2MemW : public File2I { bool isGood(void) override; bool write(const ByteSpan data, int64_t pos = -1) override; - std::variant> read(uint64_t size, int64_t pos = -1) override; + ByteSpanWithOwnership read(uint64_t size, int64_t pos = -1) override; }; struct File2MemR : public File2I { @@ -27,6 +27,6 @@ struct File2MemR : public File2I { bool isGood(void) override; bool write(const ByteSpan data, int64_t pos = -1) override; - std::variant> read(uint64_t size, int64_t pos = -1) override; + ByteSpanWithOwnership read(uint64_t size, int64_t pos = -1) override; }; diff --git a/solanaceae/file/file2_stack.hpp b/solanaceae/file/file2_stack.hpp new file mode 100644 index 0000000..4927a91 --- /dev/null +++ b/solanaceae/file/file2_stack.hpp @@ -0,0 +1,32 @@ +#pragma once + +#include "./file2.hpp" + +#include +#include + +// wrapper/container for a file "stack" +// has no file functionallity by itself + +struct File2Stack : public File2I { + std::stack> _stack; + + // TODO: change interface again and make r/w non const data members! + File2Stack(void) : File2I(false, false), _stack() {} + File2Stack(std::stack>&& stack) : File2I(false, false), _stack(std::move(stack)) {} + File2Stack(std::unique_ptr&& file) : File2I(false, false), _stack({std::move(file)}) {} + virtual ~File2Stack(void) {} + + bool isGood(void) override { + return _stack.top()->isGood(); + } + + bool write(const ByteSpan data, int64_t pos = -1) override { + return _stack.top()->write(data, pos); + } + + ByteSpanWithOwnership read(uint64_t size, int64_t pos = -1) override { + return _stack.top()->read(size, pos); + } +}; + diff --git a/solanaceae/file/file2_std.cpp b/solanaceae/file/file2_std.cpp index e516ceb..1993c1c 100644 --- a/solanaceae/file/file2_std.cpp +++ b/solanaceae/file/file2_std.cpp @@ -32,7 +32,6 @@ bool File2WFile::isGood(void) { return _file.is_open() && _file.good(); } - //bool write(const ByteSpan data, int64_t pos = -1) override; bool File2WFile::write(const ByteSpan data, int64_t pos) { if (pos != -1) { //std::cerr << "invalid pos\n"; @@ -49,7 +48,7 @@ bool File2WFile::write(const ByteSpan data, int64_t pos) { return _file.good(); } -std::variant> File2WFile::read(uint64_t, int64_t) { +ByteSpanWithOwnership File2WFile::read(uint64_t, int64_t) { return ByteSpan{}; } @@ -102,7 +101,7 @@ bool File2RWFile::write(const ByteSpan data, int64_t pos) { return _file.good(); } -std::variant> File2RWFile::read(uint64_t size, int64_t pos) { +ByteSpanWithOwnership File2RWFile::read(uint64_t size, int64_t pos) { if (pos >= int64_t(_file_size)) { return ByteSpan{}; } @@ -124,6 +123,8 @@ std::variant> File2RWFile::read(uint64_t size, in chunk.clear(); } - return chunk; + // return owning + return ByteSpanWithOwnership{std::move(chunk)}; + //return chunk; // is this the same? } diff --git a/solanaceae/file/file2_std.hpp b/solanaceae/file/file2_std.hpp index 60f55a1..5dd0868 100644 --- a/solanaceae/file/file2_std.hpp +++ b/solanaceae/file/file2_std.hpp @@ -19,7 +19,7 @@ struct File2WFile : public File2I { bool isGood(void) override; bool write(const ByteSpan data, int64_t pos = -1) override; - std::variant> read(uint64_t size, int64_t pos = -1) override; + ByteSpanWithOwnership read(uint64_t size, int64_t pos = -1) override; }; // read write, requires an existing file, file size is fixed @@ -35,7 +35,7 @@ struct File2RWFile : public File2I { bool isGood(void) override; bool write(const ByteSpan data, int64_t pos = -1) override; - std::variant> read(uint64_t size, int64_t pos = -1) override; + ByteSpanWithOwnership read(uint64_t size, int64_t pos = -1) override; }; // cut down interface (write disabled) diff --git a/solanaceae/util/span.hpp b/solanaceae/util/span.hpp index 0a7e954..cc7f159 100644 --- a/solanaceae/util/span.hpp +++ b/solanaceae/util/span.hpp @@ -7,7 +7,7 @@ // non owning view template -struct Span final { +struct Span { const T* ptr {nullptr}; uint64_t size {0};