Add builtin_packer for array_desc / map_desc

This commit is contained in:
Kurt Sassenrath 2023-12-28 15:35:40 -08:00
parent 0e00edc378
commit a027d6b946
2 changed files with 126 additions and 5 deletions

View File

@ -194,7 +194,7 @@ struct builtin_packer<std::string_view> : builtin_packer_base {
static constexpr std::size_t len_size(std::string_view value) noexcept {
auto const len = std::size(value);
if (len <= std::uint32_t(format::fixstr::mask)) return 0;
if (len <= static_cast<std::uint32_t>(format::fixstr::mask)) return 0;
return std::min(max_payload_length,
std::bit_ceil(std::uint32_t((std::bit_width(len) + 7) >> 3)));
}
@ -226,12 +226,66 @@ struct builtin_packer<std::string_view> : builtin_packer_base {
template <std::convertible_to<std::string_view> T>
struct builtin_packer<T> : builtin_packer<std::string_view> {};
/* template <> */
/* struct builtin_packer<msgpack::array_desc> */
/* : builtin_packer_base<format::type::array> {}; */
template <>
struct builtin_packer<array_desc> : builtin_packer_base {
static constexpr std::size_t rep_size(array_desc value) noexcept {
auto const len = value.count;
if (len <= static_cast<std::size_t>(format::fixarray::mask)) {
return 0;
}
if (len < 0x10000) return 2;
return 4;
}
static constexpr auto marker(array_desc value) noexcept {
switch (rep_size(value)) {
case 0:
return format::fixarray::marker
| static_cast<std::byte>(value.count);
case 2: return format::array16::marker;
case 4:
default: return format::array32::marker;
}
}
static constexpr auto pack(array_desc value, auto out) noexcept {
*out++ = marker(value);
return detail::pack_integral(value.count, out, rep_size(value));
}
};
template <>
struct builtin_packer<map_desc> : builtin_packer_base {
static constexpr std::size_t rep_size(map_desc value) noexcept {
auto const len = value.count;
if (len <= static_cast<std::size_t>(format::fixmap::mask)) {
return 0;
}
if (len < 0x10000) return 2;
return 4;
}
static constexpr auto marker(map_desc value) noexcept {
switch (rep_size(value)) {
case 0:
return format::fixmap::marker
| static_cast<std::byte>(value.count);
case 2: return format::map16::marker;
case 4:
default: return format::map32::marker;
}
}
static constexpr auto pack(map_desc value, auto out) noexcept {
*out++ = marker(value);
return detail::pack_integral(value.count, out, rep_size(value));
}
};
/* template <> */
/* struct builtin_packer<msgpack::map_desc> */
/* struct builtin_packer<map_desc> */
/* : builtin_packer_base<format::type::map> {}; */
// Requirements for builtin_packable types.

View File

@ -44,6 +44,24 @@ struct fmt::formatter<msgpack::nil> : fmt::formatter<std::string_view> {
}
};
template <>
struct fmt::formatter<msgpack::map_desc> : fmt::formatter<std::string_view> {
template <typename FormatContext>
auto format(msgpack::map_desc const& value, FormatContext& ctx) const {
return fmt::format_to(
ctx.out(), "{{msgpack::map_desc: {}}}", value.count);
}
};
template <>
struct fmt::formatter<msgpack::array_desc> : fmt::formatter<std::string_view> {
template <typename FormatContext>
auto format(msgpack::array_desc const& value, FormatContext& ctx) const {
return fmt::format_to(
ctx.out(), "{{msgpack::array_desc: {}}}", value.count);
}
};
namespace {
template <typename... Bytes>
@ -164,6 +182,42 @@ struct test_data<std::int64_t> {
}
};
template <>
struct test_data<msgpack::array_desc> {
static constexpr auto values = std::to_array<msgpack::array_desc>({
1, // fixarray
15, // fixarray
16, // array16
65535, // array16
65536 // array32
});
static constexpr auto payload = make_bytes(0x91, // fixarray
0x9f, // fixarray
0xdc, 0x00, 0x10, // array16
0xdc, 0xff, 0xff, // array16
0xdd, 0x00, 0x01, 0x00, 0x00 // array32
);
};
template <>
struct test_data<msgpack::map_desc> {
static constexpr auto values = std::to_array<msgpack::map_desc>({
1, // fixmap
15, // fixmap
16, // map16
65535, // map16
65536 // map32
});
static constexpr auto payload = make_bytes(0x81, // fixmap
0x8f, // fixmap
0xde, 0x00, 0x10, // map16
0xde, 0xff, 0xff, // map16
0xdf, 0x00, 0x01, 0x00, 0x00 // map32
);
};
template <std::convertible_to<std::string_view> T>
struct test_data<T> {
static constexpr auto values = std::to_array<T>({
@ -282,6 +336,9 @@ suite packer = [] {
expect(test_deduced<char const*>());
};
#endif
// Byte ranges -> Binary
"packer::pack<std::span<std::byte>>"_test = [] {
expect(test_deduced<std::span<std::byte const>>());
};
@ -319,4 +376,14 @@ suite packer = [] {
expect(std::ranges::equal(payload, expected));
}
};
// array_desc - Just the header of the array.
"packer::pack<msgpack::array_desc>"_test = [] {
expect(test_deduced<msgpack::array_desc>());
};
// map_desc - Just the header of the map.
"packer::pack<msgpack::map_desc>"_test = [] {
expect(test_deduced<msgpack::map_desc>());
};
};