diff options
author | Aki <please@ignore.pl> | 2024-03-18 23:41:20 +0100 |
---|---|---|
committer | Aki <please@ignore.pl> | 2024-03-18 23:41:20 +0100 |
commit | 2066e4911948d11cac5a234d2f7773dc5f06ba96 (patch) | |
tree | 27c7672aad884d1307736b3d15e704d7d786b314 | |
parent | 3df6ccddcbd881c2474746f5f1758b095c866a67 (diff) | |
download | starshatter-2066e4911948d11cac5a234d2f7773dc5f06ba96.zip starshatter-2066e4911948d11cac5a234d2f7773dc5f06ba96.tar.gz starshatter-2066e4911948d11cac5a234d2f7773dc5f06ba96.tar.bz2 |
Added filesystem-only starshatter::data DataLoader replacement
Step by step. The intent is to find a good spot between current data
representations and the standard library and put the intermediate
stage there. After it matures a bit, we can move further away.
-rw-r--r-- | FoundationEx/CMakeLists.txt | 4 | ||||
-rw-r--r-- | FoundationEx/include/starshatter/foundation/data.h | 26 | ||||
-rw-r--r-- | FoundationEx/include/starshatter/foundation/reader.h | 6 | ||||
-rw-r--r-- | FoundationEx/src/data.cpp | 42 | ||||
-rw-r--r-- | FoundationEx/src/reader.cpp | 4 | ||||
-rw-r--r-- | FoundationEx/src/reader/buffer.h | 9 | ||||
-rw-r--r-- | FoundationEx/src/reader/buffer.inl.h | 16 | ||||
-rw-r--r-- | FoundationEx/src/reader/file.cpp | 129 | ||||
-rw-r--r-- | FoundationEx/src/reader/file.h | 49 | ||||
-rw-r--r-- | FoundationEx/test/data.cpp | 26 | ||||
-rw-r--r-- | FoundationEx/test/reader.cpp | 13 |
11 files changed, 304 insertions, 20 deletions
diff --git a/FoundationEx/CMakeLists.txt b/FoundationEx/CMakeLists.txt index 646ee58..972a242 100644 --- a/FoundationEx/CMakeLists.txt +++ b/FoundationEx/CMakeLists.txt @@ -5,9 +5,11 @@ add_library( src/Text.cpp src/Utils.cpp src/reader.cpp + src/data.cpp + src/reader/file.cpp ) target_include_directories(${PROJECT_NAME} PUBLIC include) -add_executable(${PROJECT_NAME}_test test/Text.cpp test/reader.cpp) +add_executable(${PROJECT_NAME}_test test/Text.cpp test/reader.cpp test/data.cpp) target_link_libraries(${PROJECT_NAME}_test PRIVATE ${PROJECT_NAME} GTest::gtest_main) generate_emulator(${PROJECT_NAME}_test) gtest_discover_tests(${PROJECT_NAME}_test DISCOVERY_TIMEOUT 60) diff --git a/FoundationEx/include/starshatter/foundation/data.h b/FoundationEx/include/starshatter/foundation/data.h new file mode 100644 index 0000000..20308a2 --- /dev/null +++ b/FoundationEx/include/starshatter/foundation/data.h @@ -0,0 +1,26 @@ +/* Starshatter: The Open Source Project + Copyright (c) 2021-2024, Starshatter: The Open Source Project Contributors + Copyright (c) 2011-2012, Starshatter OpenSource Distribution Contributors + Copyright (c) 1997-2006, Destroyer Studios LLC. +*/ + +#pragma once + +#include "reader.h" + + +namespace starshatter +{ +namespace foundation +{ +namespace data +{ + + +bool toggle_filesystem(bool enabled); +Reader open(const char* pathname); + + +} // namespace data +} // namespace foundation +} // namespace starshatter diff --git a/FoundationEx/include/starshatter/foundation/reader.h b/FoundationEx/include/starshatter/foundation/reader.h index 7ec81b4..69472c8 100644 --- a/FoundationEx/include/starshatter/foundation/reader.h +++ b/FoundationEx/include/starshatter/foundation/reader.h @@ -9,6 +9,8 @@ #include <cstddef> #include <memory> +#include <Text.h> + namespace starshatter { @@ -40,7 +42,7 @@ struct BaseReader virtual Count read(Char* dest, Count bytes) = 0; virtual Count peek(Char* dest) const = 0; virtual Count peek(Char* dest, Count bytes) const = 0; - virtual const Char* data() const = 0; + virtual Text more() = 0; }; @@ -73,7 +75,7 @@ struct Reader : public BaseReader<char> Count read(char* dest, Count bytes) override; Count peek(char* dest) const override; Count peek(char* dest, Count bytes) const override; - const char* data() const override; + Text more() override; private: Base actual; }; diff --git a/FoundationEx/src/data.cpp b/FoundationEx/src/data.cpp new file mode 100644 index 0000000..643e823 --- /dev/null +++ b/FoundationEx/src/data.cpp @@ -0,0 +1,42 @@ +/* Starshatter: The Open Source Project + Copyright (c) 2021-2024, Starshatter: The Open Source Project Contributors + Copyright (c) 2011-2012, Starshatter OpenSource Distribution Contributors + Copyright (c) 1997-2006, Destroyer Studios LLC. +*/ + +#include <starshatter/foundation/data.h> + +#include <fstream> +#include <memory> + +#include <starshatter/foundation/reader.h> + +#include "reader/file.h" + + + +namespace starshatter +{ +namespace foundation +{ +namespace data +{ + + +bool +toggle_filesystem(bool) +{ + return true; +} + + +Reader +open(const char* pathname) +{ + return {std::make_unique<FileReader>(std::fstream(pathname, std::ios::binary | std::ios::in))}; +} + + +} // namespace data +} // namespace foundation +} // namespace starshatter diff --git a/FoundationEx/src/reader.cpp b/FoundationEx/src/reader.cpp index 7bce34d..0a3a2ba 100644 --- a/FoundationEx/src/reader.cpp +++ b/FoundationEx/src/reader.cpp @@ -9,6 +9,8 @@ #include <memory> #include <utility> +#include <Text.h> + #include "reader/buffer.h" @@ -75,7 +77,7 @@ Count Reader::read(char* dest) { return actual->read(dest); } Count Reader::read(char* dest, Count bytes) { return actual->read(dest, bytes); } Count Reader::peek(char* dest) const { return actual->peek(dest); } Count Reader::peek(char* dest, Count bytes) const { return actual->peek(dest, bytes); } -const char* Reader::data() const { return actual->data(); } +Text Reader::more() { return actual->more(); } } // namespace foundation diff --git a/FoundationEx/src/reader/buffer.h b/FoundationEx/src/reader/buffer.h index c36310a..532a8f9 100644 --- a/FoundationEx/src/reader/buffer.h +++ b/FoundationEx/src/reader/buffer.h @@ -7,6 +7,7 @@ #pragma once #include <starshatter/foundation/reader.h> +#include <Text.h> namespace starshatter @@ -35,12 +36,12 @@ struct BufferReader : public BaseReader<char> Count read(char* dest, Count bytes) override; Count peek(char* dest) const override; Count peek(char* dest, Count bytes) const override; - const char* data() const override; + Text more() override; private: - Source buffer; - Count size; - Count position; + Source buffer = {}; + Count size = {}; + Count position = {}; }; diff --git a/FoundationEx/src/reader/buffer.inl.h b/FoundationEx/src/reader/buffer.inl.h index 3b739e4..c452878 100644 --- a/FoundationEx/src/reader/buffer.inl.h +++ b/FoundationEx/src/reader/buffer.inl.h @@ -8,8 +8,9 @@ #include <cstring> #include <memory> #include <utility> +#include <vector> -#include <starshatter/foundation/reader.h> +#include <Text.h> namespace starshatter @@ -124,16 +125,21 @@ Count BufferReader<Source>::peek(char* dest, Count bytes) const { bytes = std::min(bytes, available()); - std::copy(data(), data() + bytes, dest); + std::copy(at(buffer) + position, at(buffer) + position + bytes, dest); return bytes; } template <typename Source> -const char* -BufferReader<Source>::data() const +Text +BufferReader<Source>::more() { - return at(buffer) + position; + const auto size = available(); + if (size < 1) + return Text(); + std::vector<char> tmp(size); + read(tmp.data(), size); + return Text(tmp.data(), size); } diff --git a/FoundationEx/src/reader/file.cpp b/FoundationEx/src/reader/file.cpp new file mode 100644 index 0000000..f9e9ae2 --- /dev/null +++ b/FoundationEx/src/reader/file.cpp @@ -0,0 +1,129 @@ +/* Starshatter: The Open Source Project + Copyright (c) 2021-2024, Starshatter: The Open Source Project Contributors + Copyright (c) 2011-2012, Starshatter OpenSource Distribution Contributors + Copyright (c) 1997-2006, Destroyer Studios LLC. +*/ + +#include "file.h" + +#include <algorithm> +#include <fstream> +#include <ios> +#include <limits> +#include <utility> +#include <vector> + +#include <Text.h> + + +namespace starshatter +{ +namespace foundation +{ + + +FileReader::FileReader(std::fstream src) : + file {std::move(src)} +{ + file.seekg(0); + file.ignore(std::numeric_limits<std::streamsize>::max()); + size = file.gcount(); + file.clear(); + file.seekg(0); + position = 0; +} + + +bool +FileReader::valid() const +{ + return static_cast<bool>(file) && file.is_open(); +} + + +Count +FileReader::available() const +{ + return size - position; +} + + +Count +FileReader::seek(Count pos) +{ + position = pos; + if (position > size) + position = size; + file.seekg(position); + return position; +} + + +Count +FileReader::seek(Offset offset, Direction dir) +{ + switch (dir) { + case Direction::Start: + break; // no-op + case Direction::End: + offset = size + offset; + break; + case Direction::Current: + offset = position + offset; + break; + } + if (offset < 0) + offset = 0; + return seek(static_cast<Count>(offset)); +} + + +Count +FileReader::read(char* dest) +{ + return read(dest, available()); +} + + +Count +FileReader::read(char* dest, Count bytes) +{ + bytes = std::min(bytes, available()); + file.read(dest, bytes); + position += bytes; + return bytes; +} + + +Count +FileReader::peek(char* dest) const +{ + return peek(dest, available()); +} + + +Count +FileReader::peek(char* dest, Count bytes) const +{ + bytes = std::min(bytes, available()); + const auto before = file.tellg(); + file.read(dest, bytes); + file.seekg(before); + return bytes; +} + + +Text +FileReader::more() +{ + const auto size = available(); + if (size < 1) + return Text(); + std::vector<char> tmp(size); + read(tmp.data(), size); + return Text(tmp.data(), size); +} + + +} // namespace foundation +} // namespace starshatter diff --git a/FoundationEx/src/reader/file.h b/FoundationEx/src/reader/file.h new file mode 100644 index 0000000..22810b6 --- /dev/null +++ b/FoundationEx/src/reader/file.h @@ -0,0 +1,49 @@ +/* Starshatter: The Open Source Project + Copyright (c) 2021-2024, Starshatter: The Open Source Project Contributors + Copyright (c) 2011-2012, Starshatter OpenSource Distribution Contributors + Copyright (c) 1997-2006, Destroyer Studios LLC. +*/ + +#pragma once + +#include <fstream> + +#include <starshatter/foundation/reader.h> +#include <Text.h> + + +namespace starshatter +{ +namespace foundation +{ + + +struct FileReader : public BaseReader<char> +{ + FileReader() = default; + FileReader(std::fstream src); + FileReader(const FileReader& other) = delete; + FileReader& operator=(const FileReader& other) = delete; + FileReader(FileReader&& other) = default; + FileReader& operator=(FileReader&& other) = default; + ~FileReader() override = default; + + bool valid() const override; + Count available() const override; + Count seek(Count pos) override; + Count seek(Offset offset, Direction dir) override; + Count read(char* dest) override; + Count read(char* dest, Count bytes) override; + Count peek(char* dest) const override; + Count peek(char* dest, Count bytes) const override; + Text more() override; + +private: + mutable std::fstream file = {}; + Count size = {}; + Count position = {}; +}; + + +} // namespace foundation +} // namespace starshatter diff --git a/FoundationEx/test/data.cpp b/FoundationEx/test/data.cpp new file mode 100644 index 0000000..09ab49b --- /dev/null +++ b/FoundationEx/test/data.cpp @@ -0,0 +1,26 @@ +#include <filesystem> +#include <fstream> + +#include <gtest/gtest.h> + +#include <starshatter/foundation/data.h> + + +namespace data = starshatter::foundation::data; +namespace fs = std::filesystem; + + +TEST(FoundationEx, OpenRelativePathOnFilesystem) +{ + fs::current_path(fs::temp_directory_path()); + { + std::fstream tmp("sample", tmp.out | tmp.binary); + tmp << "Hello, there!\n"; + } + data::toggle_filesystem(true); + auto file = data::open("sample"); + ASSERT_TRUE(file.valid()); + ASSERT_LT(0, file.available()); + const auto text = file.more(); + ASSERT_STREQ("Hello, there!\n", text); +} diff --git a/FoundationEx/test/reader.cpp b/FoundationEx/test/reader.cpp index 395ad81..4bc4882 100644 --- a/FoundationEx/test/reader.cpp +++ b/FoundationEx/test/reader.cpp @@ -17,7 +17,8 @@ TEST(FoundationEx, ReadFromView) { Reader reader("Hello, World!"); ASSERT_TRUE(reader.valid()); - std::vector<char> buffer(reader.available()); + const auto s = reader.available(); + std::vector<char> buffer(s); ASSERT_EQ(14, buffer.size()); const auto bytes = reader.read(buffer.data()); ASSERT_EQ(14, bytes); @@ -54,12 +55,10 @@ TEST(FoundationEx, RelativeSeek) TEST(FoundationEx, CreateTextFromReader) { const char* ref = "Hello!"; - const auto size = 7; - auto ptr = std::make_unique<char[]>(size); - for (auto i = 0; i < size; ++i) - ptr[i] = ref[i]; + auto ptr = std::make_unique<char[]>(std::strlen(ref) + 1); + std::strcpy(ptr.get(), ref); Reader reader(std::move(ptr)); ASSERT_TRUE(reader.valid()); - Text text(reader.data()); - ASSERT_EQ("Hello!", text); + const auto text = reader.more(); + ASSERT_STREQ(ref, text); } |