Skip to content

Commit

Permalink
fix to_pb break condition; add test
Browse files Browse the repository at this point in the history
  • Loading branch information
bbbgan committed May 5, 2024
1 parent 9af6367 commit d316358
Show file tree
Hide file tree
Showing 5 changed files with 212 additions and 36 deletions.
14 changes: 3 additions & 11 deletions iguana/pb_reader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,15 @@ inline void from_pb_impl(T& val, std::string_view& pb_str, uint32_t field_no) {
if (size == 0) {
return;
}

from_pb(val, pb_str);
from_pb(val, pb_str.substr(0, size));
pb_str = pb_str.substr(size);
}
else if constexpr (is_sequence_container<value_type>::value) {
using item_type = typename value_type::value_type;
if constexpr (is_lenprefix_v<item_type>) {
// item_type non-packed
while (!pb_str.empty()) {
item_type item;
item_type item{}; // init the default value
from_pb_impl<item_type>(item, pb_str);
val.push_back(std::move(item));
if (pb_str.empty()) {
Expand Down Expand Up @@ -187,9 +186,6 @@ inline constexpr size_t get_member_count_impl() {

template <typename T>
inline void from_pb(T& t, std::string_view pb_str) {
using U = std::remove_const_t<std::remove_reference_t<T>>;
constexpr size_t Count = get_member_count_impl<U>();

size_t pos = 0;
while (!pb_str.empty()) {
uint32_t key = detail::decode_varint(pb_str, pos);
Expand All @@ -208,7 +204,7 @@ inline void from_pb(T& t, std::string_view pb_str) {
[&t, &pb_str, wire_type](auto& val) {
using value_type = typename std::decay_t<decltype(val)>::value_type;
if (wire_type != detail::get_wire_type<value_type>()) {
return;
throw std::runtime_error("unmatched wire_type");
}
if constexpr (detail::is_signed_varint_v<value_type> ||
detail::is_fixed_v<value_type>) {
Expand All @@ -220,10 +216,6 @@ inline void from_pb(T& t, std::string_view pb_str) {
}
},
member);

if (field_number == Count) {
break;
}
}
}
} // namespace iguana
37 changes: 21 additions & 16 deletions test/proto/unittest_proto3.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,23 +72,28 @@ REFLECTION(RepeatBaseTypeMsg, repeated_uint32, repeated_uint64, repeated_int32,
repeated_int64, repeated_float, repeated_double, repeated_string,
repeated_enum);

// struct RepeatIguanaTypeMSg {
// std::vector<iguana::sfixed32_t> repeated_sint32;
// std::vector<iguana::sfixed64_t> repeated_sint64;
// std::vector<iguana::fixed32_t> repeated_fixed32;
// std::vector<iguana::fixed64_t> repeated_fixed64;
// std::vector<iguana::sfixed32_t> repeated_sfixed32;
// std::vector<iguana::sfixed64_t> repeated_sfixed64;
// };
struct RepeatIguanaTypeMsg {
std::vector<iguana::sfixed32_t> repeated_sint32;
std::vector<iguana::sfixed64_t> repeated_sint64;
std::vector<iguana::fixed32_t> repeated_fixed32;
std::vector<iguana::fixed64_t> repeated_fixed64;
std::vector<iguana::sfixed32_t> repeated_sfixed32;
std::vector<iguana::sfixed64_t> repeated_sfixed64;
};

// struct NestedMsg {
// BaseTypeMsg base_msg;
// std::vector<BaseTypeMsg> repeat_base_msg;
// std::vector<RepeatBaseTypeMsg> repeat_repeat_base_msg;
// std::vector<IguanaTypeMsg> repeat_iguna_msg;
// std::vector<RepeatIguanaTypeMSg> repeat_repeat_iguana_msg;
// iguana::one_of_t<BaseTypeMsg, std::vector<std::string>> nest_oneof;
// };
REFLECTION(RepeatIguanaTypeMsg, repeated_sint32, repeated_sint64,
repeated_fixed32, repeated_fixed64, repeated_sfixed32,
repeated_sfixed64);

struct NestedMsg {
BaseTypeMsg base_msg;
std::vector<BaseTypeMsg> repeat_base_msg;
IguanaTypeMsg iguana_type_msg;
std::vector<IguanaTypeMsg> repeat_iguna_msg;
std::vector<RepeatBaseTypeMsg> repeat_repeat_base_msg;
};
REFLECTION(NestedMsg, base_msg, repeat_base_msg, iguana_type_msg,
repeat_iguna_msg, repeat_repeat_base_msg);

// struct MapMsg {
// std::unordered_map<iguana::sfixed64_t, std::string> sfix64_str_map;
Expand Down
8 changes: 2 additions & 6 deletions test/proto/unittest_proto3.proto
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,9 @@ message RepeatIguanaTypeMsg {
message NestedMsg {
BaseTypeMsg base_msg = 1;
repeated BaseTypeMsg repeat_base_msg = 2;
repeated RepeatBaseTypeMsg repeat_repeat_base_msg = 3;
IguanaTypeMsg iguana_type_msg = 3;
repeated IguanaTypeMsg repeat_iguna_msg = 4;
repeated RepeatIguanaTypeMsg repeat_repeat_iguana_msg = 5;
oneof nest_oneof {
BaseTypeMsg nest_oneof_base_msg = 6;
string nest_oneof_string = 7;
}
repeated RepeatBaseTypeMsg repeat_repeat_base_msg = 5;
}

message MapMsg {
Expand Down
8 changes: 5 additions & 3 deletions test/test_pb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ REFLECTION(person, name, age);

struct my_struct {
int x;
int y;
int z;
bool y;
iguana::fixed64_t z;
};
REFLECTION(my_struct, x, y, z);

Expand Down Expand Up @@ -265,11 +265,13 @@ TEST_CASE("test struct_pb") {
}
{
// sub nested objects
nest1 v{"Hi", {1, 2, 3}, 5}, v2;
nest1 v{"Hi", {1, false, {3}}, 5}, v2{};
std::string s;
iguana::to_pb(v, s);
iguana::from_pb(v2, s);
CHECK(v.var == v2.var);
CHECK(v.value.y == v2.value.y);
CHECK(v.value.z == v2.value.z);

test_pb_st8 st1{1, {3, 4}, {5, {7, 8}}};
std::string str;
Expand Down
181 changes: 181 additions & 0 deletions test/test_proto3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,187 @@ TEST_CASE("test RepeatBaseTypeMsg") {
}
}

void SetRepeatIguanaTypeMsg(const stpb::RepeatIguanaTypeMsg& st,
pb::RepeatIguanaTypeMsg& msg) {
for (auto v : st.repeated_sint32) {
msg.add_repeated_sint32(v.val);
}
for (auto v : st.repeated_sint64) {
msg.add_repeated_sint64(v.val);
}
for (auto v : st.repeated_fixed32) {
msg.add_repeated_fixed32(v.val);
}
for (auto v : st.repeated_fixed64) {
msg.add_repeated_fixed64(v.val);
}
for (auto v : st.repeated_sfixed32) {
msg.add_repeated_sfixed32(v.val);
}
for (auto v : st.repeated_sfixed64) {
msg.add_repeated_sfixed64(v.val);
}
}

void CheckRepeatIguanaTypeMsg(const stpb::RepeatIguanaTypeMsg& st,
const pb::RepeatIguanaTypeMsg& msg) {
for (int i = 0; i < st.repeated_sint32.size(); ++i) {
CHECK(st.repeated_sint32[i].val == msg.repeated_sint32(i));
}
for (int i = 0; i < st.repeated_sint64.size(); ++i) {
CHECK(st.repeated_sint64[i].val == msg.repeated_sint64(i));
}
for (int i = 0; i < st.repeated_fixed32.size(); ++i) {
CHECK(st.repeated_fixed32[i].val == msg.repeated_fixed32(i));
}
for (int i = 0; i < st.repeated_fixed64.size(); ++i) {
CHECK(st.repeated_fixed64[i].val == msg.repeated_fixed64(i));
}
for (int i = 0; i < st.repeated_sfixed32.size(); ++i) {
CHECK(st.repeated_sfixed32[i].val == msg.repeated_sfixed32(i));
}
for (int i = 0; i < st.repeated_sfixed64.size(); ++i) {
CHECK(st.repeated_sfixed64[i].val == msg.repeated_sfixed64(i));
}
}

TEST_CASE("test RepeatIguanaTypeMsg") {
{
stpb::RepeatIguanaTypeMsg se_st{
{{1}, {2}, {3}}, {{4}, {5}, {6}}, {{7}, {8}, {9}},
{{10}, {11}, {12}}, {{13}, {14}, {15}}, {{16}, {17}, {18}},
};
std::string st_ss;
iguana::to_pb(se_st, st_ss);

pb::RepeatIguanaTypeMsg se_msg;
SetRepeatIguanaTypeMsg(se_st, se_msg);
std::string pb_ss;
se_msg.SerializeToString(&pb_ss);
CHECK(st_ss == pb_ss);

stpb::RepeatIguanaTypeMsg dese_st;
iguana::from_pb(dese_st, st_ss);
pb::RepeatIguanaTypeMsg dese_msg;
dese_msg.ParseFromString(pb_ss);
CheckRepeatIguanaTypeMsg(dese_st, dese_msg);
}
}

void SetNestedMsg(const stpb::NestedMsg& st, pb::NestedMsg& msg) {
SetBaseTypeMsg(st.base_msg, *msg.mutable_base_msg());

for (const auto& base_msg : st.repeat_base_msg) {
auto* base_msg_ptr = msg.add_repeat_base_msg();
SetBaseTypeMsg(base_msg, *base_msg_ptr);
}

SetIguanaTypeMsg(st.iguana_type_msg, *msg.mutable_iguana_type_msg());

for (const auto& iguana_type_msg : st.repeat_iguna_msg) {
auto* iguana_type_msg_ptr = msg.add_repeat_iguna_msg();
SetIguanaTypeMsg(iguana_type_msg, *iguana_type_msg_ptr);
}

for (const auto& repeat_base_msg : st.repeat_repeat_base_msg) {
auto* repeat_base_msg_ptr = msg.add_repeat_repeat_base_msg();
SetRepeatBaseTypeMsg(repeat_base_msg, *repeat_base_msg_ptr);
}
}

void CheckNestedMsg(const stpb::NestedMsg& st, const pb::NestedMsg& msg) {
CheckBaseTypeMsg(st.base_msg, msg.base_msg());

CHECK(st.repeat_base_msg.size() == msg.repeat_base_msg_size());
for (int i = 0; i < st.repeat_base_msg.size(); ++i) {
CheckBaseTypeMsg(st.repeat_base_msg[i], msg.repeat_base_msg(i));
}

CheckIguanaTypeMsg(st.iguana_type_msg, msg.iguana_type_msg());

CHECK(st.repeat_iguna_msg.size() == msg.repeat_iguna_msg_size());
for (int i = 0; i < st.repeat_iguna_msg.size(); ++i) {
CheckIguanaTypeMsg(st.repeat_iguna_msg[i], msg.repeat_iguna_msg(i));
}

CHECK(st.repeat_repeat_base_msg.size() == msg.repeat_repeat_base_msg_size());
for (int i = 0; i < st.repeat_repeat_base_msg.size(); ++i) {
CheckRepeatBaseTypeMsg(st.repeat_repeat_base_msg[i],
msg.repeat_repeat_base_msg(i));
}
}

TEST_CASE("test RepeatIguanaTypeMsg") {
{
stpb::RepeatIguanaTypeMsg se_st{
{{1}, {2}, {3}}, {{4}, {5}, {6}}, {{7}, {8}, {9}},
{{10}, {11}, {12}}, {{13}, {14}, {15}}, {{16}, {17}, {18}},
};
std::string st_ss;
iguana::to_pb(se_st, st_ss);

pb::RepeatIguanaTypeMsg se_msg;
SetRepeatIguanaTypeMsg(se_st, se_msg);
std::string pb_ss;
se_msg.SerializeToString(&pb_ss);
CHECK(st_ss == pb_ss);

stpb::RepeatIguanaTypeMsg dese_st;
iguana::from_pb(dese_st, st_ss);
pb::RepeatIguanaTypeMsg dese_msg;
dese_msg.ParseFromString(pb_ss);
CheckRepeatIguanaTypeMsg(dese_st, dese_msg);
}
}

TEST_CASE("test NestedMsg") {
stpb::NestedMsg se_st{
/* base_msg */ {100, 200, 300, 400, 31.4f, 62.8, false, "World",
stpb::Enum::BAZ},
/* repeat_base_msg */
{{1, 2, 3, 4, 5.5f, 6.6, true, "Hello", stpb::Enum::FOO},
{7, 8, 9, 10, 11.11f, 12.12, false, "Hi", stpb::Enum::BAR}},
/* iguana_type_msg */ {{100}, {200}, {300}, {400}, {31}, {32}},
/* repeat_iguna_msg */
{{{1}, {2}, {3}}, {{4}, {5}, {6}}, {{7}, {8}, {9}}},
/* repeat_repeat_base_msg */
{{{1, 2, 3},
{4, 5, 6},
{7, 8, 9},
{10, 11, 12},
{13.1, 14.2, 15.3},
{16.4, 17.5, 18.6},
{"a", "b", "c"},
{stpb::Enum::FOO, stpb::Enum::BAR, stpb::Enum::BAZ}},
{{19, 20, 21},
{22, 23, 24},
{25, 26, 27},
{28, 29, 30},
{31.1, 32.2, 33.3},
{34.4, 35.5, 36.6},
{"x", "y", "z"},
{stpb::Enum::ZERO, stpb::Enum::NEG, stpb::Enum::FOO}}}};

std::string st_ss;
iguana::to_pb(se_st, st_ss);

pb::NestedMsg se_msg;
SetNestedMsg(se_st, se_msg);

std::string pb_ss;
se_msg.SerializeToString(&pb_ss);

CHECK(st_ss == pb_ss);

stpb::NestedMsg dese_st;
iguana::from_pb(dese_st, st_ss);

pb::NestedMsg dese_msg;
dese_msg.ParseFromString(pb_ss);

CheckNestedMsg(dese_st, dese_msg);
}

DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4007)
int main(int argc, char** argv) { return doctest::Context(argc, argv).run(); }
DOCTEST_MSVC_SUPPRESS_WARNING_POP

0 comments on commit d316358

Please sign in to comment.