From ae4278ad339835f98f15412e4d2fc3ced4f741e9 Mon Sep 17 00:00:00 2001 From: "Zezheng.Li" Date: Thu, 21 Dec 2023 15:28:04 +0800 Subject: [PATCH] [struct_pack][fix] fix bug of struct_pack::write --- include/ylt/struct_pack/endian_wrapper.hpp | 10 ++-- .../tests/test_user_defined_type.cpp | 53 +++++++++++++++++-- 2 files changed, 54 insertions(+), 9 deletions(-) diff --git a/include/ylt/struct_pack/endian_wrapper.hpp b/include/ylt/struct_pack/endian_wrapper.hpp index 578df95e55..8eee2d7d4e 100644 --- a/include/ylt/struct_pack/endian_wrapper.hpp +++ b/include/ylt/struct_pack/endian_wrapper.hpp @@ -278,7 +278,7 @@ STRUCT_PACK_INLINE void write(Writer& writer, const T& t) { else if constexpr (detail::array) { if constexpr (detail::is_little_endian_copyable && std::is_fundamental_v) { - writer_bytes_array(writer, (const char*)&t.data(), sizeof(T)); + write_bytes_array(writer, (const char*)t.data(), sizeof(T)); } else { for (auto& e : t) write(writer, e); @@ -288,8 +288,9 @@ STRUCT_PACK_INLINE void write(Writer& writer, const T& t) { std::uint64_t len = t.size(); detail::write_wrapper(writer, (char*)&len); if constexpr (detail::continuous_container && - detail::is_little_endian_copyable) { - writer_bytes_array(writer, (const char*)&t.data(), len * sizeof(t[0])); + detail::is_little_endian_copyable && + std::is_fundamental_v) { + write_bytes_array(writer, (const char*)t.data(), len * sizeof(t[0])); } else { for (auto& e : t) write(writer, e); @@ -395,8 +396,9 @@ STRUCT_PACK_INLINE struct_pack::errc read(Reader& reader, T& t) { return read_bytes_array(reader, (char*)&t.data(), mem_size); } else { + t.clear(); for (std::size_t i = 0; i < sz; ++i) { - t.emplace_back(); + t.push_back(typename T::value_type{}); ec = read(reader, t.back()); if SP_UNLIKELY (ec != struct_pack::errc{}) { return ec; diff --git a/src/struct_pack/tests/test_user_defined_type.cpp b/src/struct_pack/tests/test_user_defined_type.cpp index 51e1effcb5..3f1bc00668 100644 --- a/src/struct_pack/tests/test_user_defined_type.cpp +++ b/src/struct_pack/tests/test_user_defined_type.cpp @@ -3,11 +3,15 @@ #include "doctest.h" #include "ylt/struct_pack.hpp" +#include "ylt/struct_pack/endian_wrapper.hpp" #include "ylt/struct_pack/error_code.hpp" #include "ylt/struct_pack/type_id.hpp" namespace my_name_space { struct array2D { + std::string name = "Hello"; + std::vector> values = {{-1, 2, 3}}; + std::array values2 = {1.1, 2.3, 4.5}; unsigned int x; unsigned int y; float* p; @@ -15,30 +19,46 @@ struct array2D { p = (float*)calloc(1ull * x * y, sizeof(float)); } array2D(const array2D&) = delete; - array2D(array2D&& o) : x(o.x), y(o.y), p(o.p) { o.p = nullptr; }; + array2D(array2D&& o) + : x(o.x), + y(o.y), + p(o.p), + values(std::move(o.values)), + values2(o.values2) { + o.p = nullptr; + }; array2D& operator=(const array2D&) = delete; array2D& operator=(array2D&& o) { x = o.x; y = o.y; p = o.p; + values = o.values; + values2 = o.values2; o.p = nullptr; return *this; } float& operator()(std::size_t i, std::size_t j) { return p[i * y + j]; } bool operator==(const array2D& o) const { return x == o.x && y == o.y && - memcmp(p, o.p, 1ull * x * y * sizeof(float)) == 0; + memcmp(p, o.p, 1ull * x * y * sizeof(float)) == 0 && + values == o.values && values2 == o.values2; } array2D() : x(0), y(0), p(nullptr) {} ~array2D() { free(p); } }; std::size_t sp_get_needed_size(const array2D& ar) { - return 2 * struct_pack::get_write_size(ar.x) + + return struct_pack::get_write_size(ar.name) + + struct_pack::get_write_size(ar.values) + + struct_pack::get_write_size(ar.values2) + + 2 * struct_pack::get_write_size(ar.x) + struct_pack::get_write_size(ar.p, 1ull * ar.x * ar.y); } template void sp_serialize_to(Writer& writer, const array2D& ar) { + struct_pack::write(writer, ar.name); + struct_pack::write(writer, ar.values); + struct_pack::write(writer, ar.values2); struct_pack::write(writer, ar.x); struct_pack::write(writer, ar.y); struct_pack::write(writer, ar.p, 1ull * ar.x * ar.y); @@ -46,6 +66,17 @@ void sp_serialize_to(Writer& writer, const array2D& ar) { template struct_pack::errc sp_deserialize_to(Reader& reader, array2D& ar) { + if (auto ec = struct_pack::read(reader, ar.name); ec != struct_pack::errc{}) { + return ec; + } + if (auto ec = struct_pack::read(reader, ar.values); + ec != struct_pack::errc{}) { + return ec; + } + if (auto ec = struct_pack::read(reader, ar.values2); + ec != struct_pack::errc{}) { + return ec; + } if (auto ec = struct_pack::read(reader, ar.x); ec != struct_pack::errc{}) { return ec; } @@ -69,6 +100,17 @@ struct_pack::errc sp_deserialize_to(Reader& reader, array2D& ar) { template struct_pack::errc sp_deserialize_to_with_skip(Reader& reader, array2D& ar) { + if (auto ec = struct_pack::read(reader, ar.name); ec != struct_pack::errc{}) { + return ec; + } + if (auto ec = struct_pack::read(reader, ar.values); + ec != struct_pack::errc{}) { + return ec; + } + if (auto ec = struct_pack::read(reader, ar.values2); + ec != struct_pack::errc{}) { + return ec; + } if (auto ec = struct_pack::read(reader, ar.x); ec != struct_pack::errc{}) { return ec; } @@ -92,7 +134,7 @@ TEST_CASE("test user-defined_type") { auto result = struct_pack::deserialize(buffer); CHECK(result.has_value()); auto& ar2 = result.value(); - CHECK(ar == result.value()); + CHECK(ar == ar2); } TEST_CASE("test user-defined_type nested") { @@ -104,7 +146,8 @@ TEST_CASE("test user-defined_type nested") { auto buffer = struct_pack::serialize(ar); auto result = struct_pack::deserialize(buffer); CHECK(result.has_value()); - CHECK(ar == result); + auto& ar2 = result.value(); + CHECK(ar == ar2); } TEST_CASE("test user-defined_type get_field") {