Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve [struct_pb] #257

Merged
merged 24 commits into from
May 14, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions iguana/pb_util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@

namespace iguana {
namespace detail {
template <typename T, typename = void>
struct get_inner_type {
using v_type = T;
};

template <typename T>
struct get_inner_type<T, std::void_t<typename T::value_type>> {
using v_type = typename T::value_type;
};
[[nodiscard]] inline uint32_t encode_zigzag(int32_t v) {
return (static_cast<uint32_t>(v) << 1U) ^
static_cast<uint32_t>(
Expand Down
37 changes: 19 additions & 18 deletions iguana/struct_pb.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,17 @@ constexpr bool is_one_of_v = is_one_of_t<T>::value;
template <typename T>
constexpr inline WireType get_wire_type() {
if constexpr (std::is_integral_v<T> || is_signed_varint_v<T> ||
std::is_enum_v<T>) {
std::is_enum_v<T> || std::is_same_v<T, bool>) {
return WireType::Varint;
}
else if constexpr (std::is_same_v<T, fixed32_t> ||
std::is_same_v<T, sfixed32_t>) {
std::is_same_v<T, sfixed32_t> ||
std::is_same_v<T, float>) {
return WireType::Fixed32;
}
else if constexpr (std::is_same_v<T, fixed64_t> ||
std::is_same_v<T, sfixed64_t>) {
std::is_same_v<T, sfixed64_t> ||
std::is_same_v<T, double>) {
return WireType::Fixed64;
}
else if constexpr (std::is_same_v<T, std::string> ||
Expand Down Expand Up @@ -221,10 +223,10 @@ inline void from_pb_impl(T& val, std::string_view& pb_str, uint32_t field_no) {
if constexpr (is_reflection_v<value_type>) {
size_t pos;
uint32_t size = detail::decode_varint(pb_str, pos);
pb_str = pb_str.substr(pos);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bug,应该先移动再判断,判断剩余的字符串的大小和size之间的关系。剩下有几处也类似

if (pb_str.size() < size) {
throw std::invalid_argument("Invalid fixed int value: too few bytes.");
}
pb_str = pb_str.substr(pos);
if (size == 0) {
return;
}
Expand Down Expand Up @@ -257,11 +259,10 @@ inline void from_pb_impl(T& val, std::string_view& pb_str, uint32_t field_no) {
// non-message has size
size_t pos;
uint32_t size = detail::decode_varint(pb_str, pos);
pb_str = pb_str.substr(pos);
if (pb_str.size() < size) {
throw std::invalid_argument("Invalid fixed int value: too few bytes.");
}
pb_str = pb_str.substr(pos);

using item_type = typename value_type::value_type;
size_t start = pb_str.size();

Expand All @@ -281,10 +282,10 @@ inline void from_pb_impl(T& val, std::string_view& pb_str, uint32_t field_no) {
while (!pb_str.empty()) {
size_t pos;
uint32_t size = detail::decode_varint(pb_str, pos);
pb_str = pb_str.substr(pos);
if (pb_str.size() < size) {
throw std::invalid_argument("Invalid fixed int value: too few bytes.");
}
pb_str = pb_str.substr(pos);

item_type item = {};
decode_pair_value(item.first, pb_str);
Expand All @@ -305,7 +306,7 @@ inline void from_pb_impl(T& val, std::string_view& pb_str, uint32_t field_no) {
}
}
else if constexpr (std::is_integral_v<value_type>) {
val = detail::decode_varint(pb_str, pos);
val = static_cast<value_type>(detail::decode_varint(pb_str, pos));
pb_str = pb_str.substr(pos);
}
else if constexpr (detail::is_signed_varint_v<value_type>) {
Expand All @@ -320,8 +321,11 @@ inline void from_pb_impl(T& val, std::string_view& pb_str, uint32_t field_no) {
}
pb_str = pb_str.substr(pos);
}
else if constexpr (detail::is_fixed_v<value_type>) {
constexpr size_t size = sizeof(typename value_type::value_type);
else if constexpr (detail::is_fixed_v<value_type> ||
std::is_same_v<value_type, double> ||
std::is_same_v<value_type, float>) {
constexpr size_t size =
sizeof(typename detail::get_inner_type<value_type>::v_type);
if (pb_str.size() < size) {
throw std::invalid_argument("Invalid fixed int value: too few bytes.");
}
Expand Down Expand Up @@ -405,7 +409,6 @@ inline void to_pb_impl(T& val, size_t field_no, std::string& out) {
std::string temp = encode_pair_value<first_type>(k, 1);
std::string second_temp = encode_pair_value<second_type>(v, 2);
encode_key(field_no, WireType::LengthDelimeted, out);

serialize_varint(temp.size() + second_temp.size(), out);
out.append(temp).append(second_temp);
}
Expand All @@ -416,14 +419,14 @@ inline void to_pb_impl(T& val, size_t field_no, std::string& out) {
else if constexpr (detail::is_signed_varint_v<value_type>) {
detail::encode_signed_varint_field(field_no, WireType::Varint, val, out);
}
else if constexpr (detail::is_fixed_v<value_type>) {
else if constexpr (detail::is_fixed_v<value_type> ||
std::is_same_v<value_type, double> ||
std::is_same_v<value_type, float>) {
if constexpr (sizeof(value_type) == 8) {
detail::encode_fixed_field(field_no, WireType::Fixed64, (uint64_t)(val),
out);
detail::encode_fixed_field(field_no, WireType::Fixed64, val, out);
}
else {
detail::encode_fixed_field(field_no, WireType::Fixed32, (uint32_t)(val),
out);
detail::encode_fixed_field(field_no, WireType::Fixed32, val, out);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里应该不需要强制转换吧,在处理double类型会出现问题,我认为没有强制转换的必要,所以我删除了。

}
}
else if constexpr (std::is_same_v<value_type, std::string> ||
Expand All @@ -439,7 +442,6 @@ inline void to_pb_impl(T& val, size_t field_no, std::string& out) {
if (!val.has_value()) {
return;
}

to_pb_impl<typename value_type::value_type>(*val, field_no, out);
}
else if constexpr (is_one_of_v<value_type>) {
Expand Down Expand Up @@ -486,7 +488,6 @@ inline void from_pb(T& t, std::string_view pb_str) {
if (wire_type != detail::get_wire_type<value_type>()) {
return;
}

if constexpr (detail::is_signed_varint_v<value_type> ||
detail::is_fixed_v<value_type>) {
detail::from_pb_impl<value_type>(val.value(t).val, pb_str);
Expand Down
18 changes: 18 additions & 0 deletions test/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,13 @@ struct nest1 {

REFLECTION(nest1, name, value, var);

struct numer_st {
bool a;
double b;
float c;
};
REFLECTION(numer_st, a, b, c);

TEST_CASE("test struct_pb") {
{
my_space::inner_struct inner{41, 42, 43};
Expand Down Expand Up @@ -564,6 +571,17 @@ TEST_CASE("test struct_pb") {
iguana::from_pb(st2, str);
CHECK(st1.z == st2.z);
}
{
// bool float double
numer_st n{true, 10.25, 4.578}, n1;
std::string str;
iguana::to_pb(n, str);

iguana::from_pb(n1, str);
CHECK(n1.a == n.a);
CHECK(n1.b == n.b);
CHECK(n1.c == n.c);
}
}

TEST_CASE("test members") {
Expand Down
Loading