diff options
author | Vittorio Romeo <vittorio.romeo@outlook.com> | 2020-07-30 23:20:40 +0100 |
---|---|---|
committer | Vittorio Romeo <vittorio.romeo@outlook.com> | 2020-07-30 23:20:40 +0100 |
commit | 2f9f506b06be33269ec982370edef6ac870de610 (patch) | |
tree | b5fd3e0ec1e2a7236f83e4a3f5da86c8ff8350fb | |
parent | eefd6070a17f2f014de407c0d61774dcb01f88f1 (diff) |
Add functions to [de]serialize replays to filesreplay_file_serialization
-rw-r--r-- | include/SSVOpenHexagon/Core/Replay.hpp | 4 | ||||
-rw-r--r-- | src/SSVOpenHexagon/Core/Replay.cpp | 64 | ||||
-rw-r--r-- | test/Replay.t.cpp | 33 |
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(); } |