refactor file2 and add span with ownership

This commit is contained in:
Green Sky 2024-05-26 21:32:44 +02:00
parent 2420af464f
commit f2f001b190
No known key found for this signature in database
7 changed files with 72 additions and 14 deletions

View File

@ -5,6 +5,29 @@
#include <vector>
#include <variant>
// TODO: move to/next-to span
// a span that can also represent its ownership
template<typename T>
struct SpanWithOwnership : public Span<T> {
// TODO: allow for different owners
std::vector<T> _data_owner;
// self interactions
SpanWithOwnership(void) = delete;
constexpr SpanWithOwnership(const SpanWithOwnership&) = delete;
constexpr SpanWithOwnership(SpanWithOwnership&&) = default;
// non-owning
constexpr SpanWithOwnership(const Span<T>& span) : Span<T>(span) {}
constexpr SpanWithOwnership(const Span<T>&& span) : Span<T>(span) {}
// owning
constexpr SpanWithOwnership(std::vector<T>&& data) : Span<T>(data), _data_owner(std::move(data)) {}
bool isOwning(void) const { return !_data_owner.empty(); }
};
using ByteSpanWithOwnership = SpanWithOwnership<uint8_t>;
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<ByteSpan, std::vector<uint8_t>> read(uint64_t size, int64_t pos = -1) = 0;
//[[nodiscard]] virtual std::variant<ByteSpan, std::vector<uint8_t>> read(uint64_t size, int64_t pos = -1) = 0;
[[nodiscard]] virtual ByteSpanWithOwnership read(uint64_t size, int64_t pos = -1) = 0;
};

View File

@ -25,8 +25,8 @@ bool File2MemW::write(const ByteSpan data, int64_t pos) {
return isGood();
}
std::variant<ByteSpan, std::vector<uint8_t>> 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<ByteSpan, std::vector<uint8_t>> 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<ByteSpan, std::vector<uint8_t>> File2MemR::read(uint64_t size, int6
std::min(size, _mem.size - _read_pos)
};
_read_pos += ret.size;
// return non-owning
return ret;
}

View File

@ -14,7 +14,7 @@ struct File2MemW : public File2I {
bool isGood(void) override;
bool write(const ByteSpan data, int64_t pos = -1) override;
std::variant<ByteSpan, std::vector<uint8_t>> 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<ByteSpan, std::vector<uint8_t>> read(uint64_t size, int64_t pos = -1) override;
ByteSpanWithOwnership read(uint64_t size, int64_t pos = -1) override;
};

View File

@ -0,0 +1,32 @@
#pragma once
#include "./file2.hpp"
#include <stack>
#include <memory>
// wrapper/container for a file "stack"
// has no file functionallity by itself
struct File2Stack : public File2I {
std::stack<std::unique_ptr<File2I>> _stack;
// TODO: change interface again and make r/w non const data members!
File2Stack(void) : File2I(false, false), _stack() {}
File2Stack(std::stack<std::unique_ptr<File2I>>&& stack) : File2I(false, false), _stack(std::move(stack)) {}
File2Stack(std::unique_ptr<File2I>&& 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);
}
};

View File

@ -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<ByteSpan, std::vector<uint8_t>> 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<ByteSpan, std::vector<uint8_t>> 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<ByteSpan, std::vector<uint8_t>> File2RWFile::read(uint64_t size, in
chunk.clear();
}
return chunk;
// return owning
return ByteSpanWithOwnership{std::move(chunk)};
//return chunk; // is this the same?
}

View File

@ -19,7 +19,7 @@ struct File2WFile : public File2I {
bool isGood(void) override;
bool write(const ByteSpan data, int64_t pos = -1) override;
std::variant<ByteSpan, std::vector<uint8_t>> 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<ByteSpan, std::vector<uint8_t>> read(uint64_t size, int64_t pos = -1) override;
ByteSpanWithOwnership read(uint64_t size, int64_t pos = -1) override;
};
// cut down interface (write disabled)

View File

@ -7,7 +7,7 @@
// non owning view
template<typename T>
struct Span final {
struct Span {
const T* ptr {nullptr};
uint64_t size {0};