summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVittorio Romeo <vittorio.romeo@outlook.com>2020-07-30 23:20:40 +0100
committerVittorio Romeo <vittorio.romeo@outlook.com>2020-07-30 23:20:40 +0100
commit2f9f506b06be33269ec982370edef6ac870de610 (patch)
treeb5fd3e0ec1e2a7236f83e4a3f5da86c8ff8350fb
parenteefd6070a17f2f014de407c0d61774dcb01f88f1 (diff)
Add functions to [de]serialize replays to filesreplay_file_serialization
-rw-r--r--include/SSVOpenHexagon/Core/Replay.hpp4
-rw-r--r--src/SSVOpenHexagon/Core/Replay.cpp64
-rw-r--r--test/Replay.t.cpp33
3 files changed, 93 insertions, 8 deletions
diff --git a/include/SSVOpenHexagon/Core/Replay.hpp b/include/SSVOpenHexagon/Core/Replay.hpp
index 702392c8..e1f28717 100644
--- a/include/SSVOpenHexagon/Core/Replay.hpp
+++ b/include/SSVOpenHexagon/Core/Replay.hpp
@@ -12,6 +12,7 @@
#include <cstring>
#include <cstdint>
#include <string>
+#include <filesystem>
namespace hg
{
@@ -129,6 +130,9 @@ struct replay_file
[[nodiscard]] deserialization_result deserialize(
const std::byte* buffer, const std::byte* const buffer_end);
+
+ [[nodiscard]] bool serialize_to_file(const std::filesystem::path p);
+ [[nodiscard]] bool deserialize_from_file(const std::filesystem::path p);
};
} // namespace hg
diff --git a/src/SSVOpenHexagon/Core/Replay.cpp b/src/SSVOpenHexagon/Core/Replay.cpp
index ff25ba67..f3efefd0 100644
--- a/src/SSVOpenHexagon/Core/Replay.cpp
+++ b/src/SSVOpenHexagon/Core/Replay.cpp
@@ -5,18 +5,22 @@
#include "SSVOpenHexagon/Core/Replay.hpp"
#include <cassert>
+#include <fstream>
namespace hg
{
-#define SSVOH_TRY(...) \
- do \
- { \
- __VA_ARGS__; \
- if(!result._success) \
- { \
- return result; \
- } \
+#define SSVOH_TRY(...) \
+ do \
+ { \
+ __VA_ARGS__; \
+ if(!result._success) \
+ { \
+ ::std::cerr << "Failed [de]serialization operation'" #__VA_ARGS__ \
+ "'\n"; \
+ \
+ return result; \
+ } \
} while(false)
static auto make_write(serialization_result& result, std::byte*& buffer,
@@ -222,6 +226,7 @@ replay_player::get_current_and_move_forward() noexcept
}
buffer += data_result._written_bytes;
+ result._written_bytes += data_result._written_bytes;
SSVOH_TRY(write_str(_pack_id));
SSVOH_TRY(write_str(_level_id));
@@ -277,4 +282,47 @@ replay_player::get_current_and_move_forward() noexcept
return result;
}
+[[nodiscard]] bool replay_file::serialize_to_file(const std::filesystem::path p)
+{
+ constexpr std::size_t buf_size{2048};
+ std::byte buf[buf_size];
+
+ const serialization_result sr = serialize(buf, buf_size);
+ if(!sr)
+ {
+ return false;
+ }
+
+ const std::size_t written_bytes = sr.written_bytes();
+
+ std::ofstream os(p, std::ios::binary | std::ios::out);
+ os.write(reinterpret_cast<const char*>(buf), written_bytes);
+ os.flush();
+
+ return static_cast<bool>(os);
+}
+
+[[nodiscard]] bool replay_file::deserialize_from_file(
+ const std::filesystem::path p)
+{
+ constexpr std::size_t buf_size{2048};
+ std::byte buf[buf_size];
+
+ std::ifstream is(p, std::ios::binary | std::ios::in);
+
+ is.seekg(0, std::ios::end);
+ const std::size_t bytes_to_read = is.tellg();
+ is.seekg(0, std::ios::beg);
+
+ is.read(reinterpret_cast<char*>(buf), bytes_to_read);
+
+ if(!static_cast<bool>(is))
+ {
+ return false;
+ }
+
+ const deserialization_result dr = deserialize(buf, bytes_to_read);
+ return static_cast<bool>(dr);
+}
+
} // namespace hg
diff --git a/test/Replay.t.cpp b/test/Replay.t.cpp
index e1004317..3c588a45 100644
--- a/test/Replay.t.cpp
+++ b/test/Replay.t.cpp
@@ -157,6 +157,38 @@ static void test_replay_file_serialization_to_buffer()
TEST_ASSERT_NS_EQ(rf_out, rf);
}
+static void test_replay_file_serialization_to_file()
+{
+ hg::replay_data rd;
+
+ rd.record_input(false, false, false, false);
+ rd.record_input(false, true, false, false);
+ rd.record_input(true, false, true, false);
+ rd.record_input(false, false, false, false);
+ rd.record_input(false, true, false, false);
+ rd.record_input(true, false, false, true);
+
+ hg::replay_file rf{
+ //
+ ._version{59832},
+ ._player_name{"hello world"},
+ ._seed{12345},
+ ._data{rd},
+ ._pack_id{"totally real pack id"},
+ ._level_id{"legit level id"},
+ ._difficulty_mult{2.5f},
+ ._played_frametime{100.f}
+ //
+ };
+
+ TEST_ASSERT(rf.serialize_to_file("test.ohr"));
+
+ hg::replay_file rf_out;
+ TEST_ASSERT(rf_out.deserialize_from_file("test.ohr"));
+
+ TEST_ASSERT_NS_EQ(rf_out, rf);
+}
+
int main()
{
test_replay_data_basic();
@@ -166,4 +198,5 @@ int main()
test_replay_player_basic();
test_replay_file_serialization_to_buffer();
+ test_replay_file_serialization_to_file();
}