Skip to content

Commit

Permalink
Added Serialise and Deserialise in binary for std::vector + tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
MStachowicz committed Apr 3, 2024
1 parent ccff976 commit 4623e6e
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 0 deletions.
28 changes: 28 additions & 0 deletions source/Test/Tests/ComponentSerialiseTester.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,34 @@ namespace Test
if (test_serialisation_utility(out_string, in_string))
CHECK_EQUAL(out_string, in_string, "String equality");
}
{SCOPE_SECTION("Vector<int>"); // vector of integers (POD type).
std::vector<int> out_vector = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
std::vector<int> in_vector = {};
if (test_serialisation_utility(out_vector, in_vector))
{
CHECK_EQUAL(out_vector.size(), in_vector.size(), "Vector<int> size");

if (out_vector.size() == in_vector.size())
{
for (size_t i = 0; i < out_vector.size(); ++i)
CHECK_EQUAL(out_vector[i], in_vector[i], "Vector<int> element");
}
}
}
{SCOPE_SECTION("Vector<glm::vec3>"); // vector of glm::vec3 (POD type).
std::vector<glm::vec3> out_vector = { glm::vec3(1.0f, 2.0f, 3.0f), glm::vec3(4.0f, 5.0f, 6.0f), glm::vec3(7.0f, 8.0f, 9.0f) };
std::vector<glm::vec3> in_vector = {};
if (test_serialisation_utility(out_vector, in_vector))
{
CHECK_EQUAL(out_vector.size(), in_vector.size(), "Vector<glm::vec3> size");

if (out_vector.size() == in_vector.size())
{
for (size_t i = 0; i < out_vector.size(); ++i)
CHECK_EQUAL(out_vector[i], in_vector[i], "Vector<glm::vec3> element");
}
}
}
}

SCOPE_SECTION("Component serialise");
Expand Down
51 changes: 51 additions & 0 deletions source/Utility/Serialise.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

#include <fstream>
#include <type_traits>
#include <vector>
#include <string>

// Helpers for serialising and deserialising objects.
namespace Utility
Expand Down Expand Up @@ -55,4 +57,53 @@ namespace Utility
p_value.resize(size);
p_in.read(p_value.data(), size);
}
// Write a vector to p_out in binary.
template <typename T>
void write_binary(std::ofstream& p_out, const std::vector<T>& p_vector)
{
static_assert(sizeof(T) > 0, "Cannot write a type of size 0");
static_assert(!std::is_pointer_v<T> && !std::is_reference_v<T>, "Cannot write a reference or pointer");
static_assert(Serializable_Type<T>, "Type is not in serializable list");

// Write the size of the vector first
size_t size = p_vector.size();
p_out.write(reinterpret_cast<const char*>(&size), sizeof(size));

// If the type is trivially copyable, we can write the entire vector in one go.
if constexpr (std::is_trivially_copyable_v<T>)
{
if (!p_vector.empty())
p_out.write(reinterpret_cast<const char*>(p_vector.data()), sizeof(T) * p_vector.size());
}
else // Otherwise, write each element individually
{
for (const T& element : p_vector)
write_binary(p_out, element);
}
}
// Read into a vector from p_in in binary.
template <typename T>
void read_binary(std::ifstream& p_in, std::vector<T>& p_vector)
{
static_assert(sizeof(T) > 0, "Cannot read into a type of size 0");
static_assert(!std::is_pointer_v<T> && !std::is_reference_v<T>, "Cannot read into a reference or pointer");
static_assert(Serializable_Type<T>, "Type is not in serializable list");

// Read the size of the vector first
size_t size;
p_in.read(reinterpret_cast<char*>(&size), sizeof(size));
p_vector.resize(size);

// If the type is trivially copyable, we can read the entire vector in one go.
if constexpr (std::is_trivially_copyable_v<T>)
{
if (size > 0)
p_in.read(reinterpret_cast<char*>(p_vector.data()), sizeof(T) * size);
}
else // Otherwise, read each element individually
{
for (T& element : p_vector)
read_binary(p_in, element);
}
}
} // namespace Utility

0 comments on commit 4623e6e

Please sign in to comment.