Skip to content

Commit

Permalink
fix little endian
Browse files Browse the repository at this point in the history
  • Loading branch information
poor-circle committed Nov 23, 2023
1 parent ea76535 commit 1f6b5dc
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 27 deletions.
19 changes: 8 additions & 11 deletions include/ylt/struct_pack/packer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,11 @@ class packer {

template <uint64_t parent_tag, std::size_t sz, typename Arg>
static constexpr void STRUCT_PACK_INLINE
get_fast_varint_width_impl(std::bitset<sz> &vec, int &i, const Arg &item,
get_fast_varint_width_impl(char (&vec)[sz], unsigned int &i, const Arg &item,
uint64_t &unsigned_max, int64_t &signed_max) {
if constexpr (varint_t<Arg, parent_tag>) {
if (get_varint_value(item) != 0) {
vec[i] = 1;
vec[i / 8] |= (0b1 << (i % 8));
if constexpr (std::is_unsigned_v<std::remove_reference_t<
decltype(get_varint_value(item))>>) {
unsigned_max =
Expand All @@ -167,19 +167,16 @@ class packer {
: -(get_varint_value(item) + 1));
}
}
else {
vec[i] = 0;
}
++i;
}
}

template <uint64_t parent_tag, std::size_t sz, typename... Args>
static constexpr int STRUCT_PACK_INLINE
get_fast_varint_width(std::bitset<sz> &vec, const Args &...items) {
get_fast_varint_width(char (&vec)[sz], const Args &...items) {
uint64_t unsigned_max = 0;
int64_t signed_max = 0;
int i = 0;
unsigned int i = 0;
(get_fast_varint_width_impl<parent_tag>(vec, i, items, unsigned_max,
signed_max),
...);
Expand All @@ -205,11 +202,11 @@ class packer {
return;
}
else {
std::bitset<cnt + 2> vec;
char vec[bitset_size]{};
auto width = get_fast_varint_width<parent_tag>(vec, items...);
vec[cnt] = width & 0b1;
vec[cnt + 1] = width & 0b10;
write_bytes_array(writer_, (char *)&vec, bitset_size);
vec[cnt / 8] |= (width & 0b1) << (cnt % 8);
vec[(cnt + 1) / 8] |= (!!(width & 0b10)) << ((cnt + 1) % 8);
write_bytes_array(writer_, vec, bitset_size);
switch (width) {
case 0:
(serialize_one_fast_varint<parent_tag, 1>(items), ...);
Expand Down
16 changes: 9 additions & 7 deletions include/ylt/struct_pack/unpacker.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -651,10 +651,11 @@ class unpacker {
template <uint64_t parent_tag, bool no_skip, std::size_t width,
std::size_t bitset_width, typename Arg>
constexpr struct_pack::errc STRUCT_PACK_INLINE deserialize_one_fast_varint(
std::bitset<bitset_width> &vec, int &i, Arg &item) {
char (&vec)[bitset_width], unsigned int &i, Arg &item) {
if constexpr (varint_t<Arg, parent_tag>) {
constexpr auto real_width = (std::min)(width, sizeof(Arg));
if (!vec[i++])
auto index = i++;
if (!(vec[index / 8] & (0b1 << (index % 8))))
return {};
if constexpr (!no_skip) {
reader_.ignore(real_width) ? errc{} : errc::no_buffer_space;
Expand Down Expand Up @@ -688,7 +689,7 @@ class unpacker {
template <uint64_t parent_tag, bool no_skip, std::size_t width,
std::size_t bitset_width, typename Arg, typename... Args>
constexpr struct_pack::errc STRUCT_PACK_INLINE deserialize_fast_varint_helper(
std::bitset<bitset_width> &vec, int &i, Arg &item, Args &...items) {
char (&vec)[bitset_width], unsigned int &i, Arg &item, Args &...items) {
auto ec =
deserialize_one_fast_varint<parent_tag, no_skip, width>(vec, i, item);
if constexpr (sizeof...(items) > 0) {
Expand All @@ -715,12 +716,13 @@ class unpacker {
return {};
}
else {
std::bitset<cnt + 2> vec;
if (auto ec = read_bytes_array(reader_, (char *)&vec, bitset_size); !ec) {
char vec[bitset_size];
if (auto ec = read_bytes_array(reader_, vec, bitset_size); !ec) {
return errc::no_buffer_space;
}
std::size_t width = vec[cnt] + vec[cnt + 1] * 2;
int i = 0;
int width = !!(vec[cnt / 8] & (0b1 << (cnt % 8))) +
!!(vec[(cnt + 1) / 8] & (0b1 << ((cnt + 1) % 8))) * 2;
unsigned int i = 0;
struct_pack::errc ec{};
switch (width) {
case 0:
Expand Down
69 changes: 60 additions & 9 deletions src/struct_pack/tests/test_fast_varint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,16 +155,8 @@ TEST_CASE("fast varint test 1") {
auto result = struct_pack::deserialize<struct_pack::DISABLE_ALL_META_INFO,
fast_varint_example_1>(buffer);
REQUIRE(result.has_value());
CHECK(result == o);
CHECK(buffer.size() == 4);
CHECK(buffer[0] != '\0');
CHECK(buffer[1] != '\0');
CHECK(buffer[2] != '\0');
CHECK(buffer[3] != '\0');
printf("bin: %d,%d,%d,%d\n", buffer[0], buffer[1], buffer[2], buffer[3]);
CHECK(result->a.get() == o.a.get());
CHECK(result->b.get() == o.b.get());
CHECK(result->c.get() == o.c.get());
CHECK(result->d.get() == o.d.get());
return;
}

Expand Down Expand Up @@ -1077,4 +1069,63 @@ TEST_CASE("fast varmixedint2 test 16") {
CHECK(result == o);
CHECK(buffer.size() == 25);
return;
}

struct six_int {
int a, b, c, d, e, f;
bool operator==(const six_int& o) const {
return a == o.a && b == o.b && c == o.c && d == o.d && e == o.e && f == o.f;
}
static constexpr auto struct_pack_config =
struct_pack::sp_config::USE_FAST_VARINT |
struct_pack::sp_config::ENCODING_WITH_VARINT;
};

TEST_CASE("six int test") {
six_int o{INT32_MIN, 2435, INT32_MAX, 0, 0, INT32_MIN};
auto buffer = struct_pack::serialize(o);
auto result = struct_pack::deserialize<six_int>(buffer);
REQUIRE(result.has_value());
CHECK(result == o);
return;
}

struct seven_int {
int a, b, c, d, e, f, g;
bool operator==(const seven_int& o) const {
return a == o.a && b == o.b && c == o.c && d == o.d && e == o.e &&
f == o.f && g == o.g;
}
static constexpr auto struct_pack_config =
struct_pack::sp_config::USE_FAST_VARINT |
struct_pack::sp_config::ENCODING_WITH_VARINT;
};

TEST_CASE("seven int test") {
seven_int o{INT32_MIN, 21314, INT32_MAX, 0, 0, INT32_MIN, 0};
auto buffer = struct_pack::serialize(o);
auto result = struct_pack::deserialize<seven_int>(buffer);
REQUIRE(result.has_value());
CHECK(result == o);
return;
}

struct eight_int {
int a, b, c, d, e, f, g, h;
bool operator==(const eight_int& o) const {
return a == o.a && b == o.b && c == o.c && d == o.d && e == o.e &&
f == o.f && g == o.g && h == o.h;
}
static constexpr auto struct_pack_config =
struct_pack::sp_config::USE_FAST_VARINT |
struct_pack::sp_config::ENCODING_WITH_VARINT;
};

TEST_CASE("seven int test") {
eight_int o{INT32_MIN, 521, INT32_MAX, 0, 0, INT32_MIN, 0, 2123};
auto buffer = struct_pack::serialize(o);
auto result = struct_pack::deserialize<eight_int>(buffer);
REQUIRE(result.has_value());
CHECK(result == o);
return;
}

0 comments on commit 1f6b5dc

Please sign in to comment.