131 lines
3.7 KiB
C++
131 lines
3.7 KiB
C++
#include <msgpack/core/reader.h>
|
|
|
|
#include <boost/ut.hpp>
|
|
|
|
#include <string>
|
|
|
|
namespace {
|
|
|
|
using namespace boost::ut;
|
|
namespace format = msgpack::format;
|
|
|
|
template <typename... Bytes>
|
|
constexpr std::array<std::byte, sizeof...(Bytes)> make_bytes(Bytes &&...bytes) {
|
|
return {std::byte(std::forward<Bytes>(bytes))...};
|
|
}
|
|
|
|
template <typename T, std::size_t C = 1024> struct oversized_array {
|
|
std::array<T, C> data;
|
|
std::size_t size;
|
|
};
|
|
|
|
constexpr auto to_bytes_array_oversized(auto const &container) {
|
|
oversized_array<std::byte> arr;
|
|
std::copy(std::begin(container), std::end(container), std::begin(arr.data));
|
|
arr.size = std::distance(std::begin(container), std::end(container));
|
|
return arr;
|
|
}
|
|
|
|
consteval auto generate_bytes(auto callable) {
|
|
constexpr auto oversized = to_bytes_array_oversized(callable());
|
|
std::array<std::byte, oversized.size> out;
|
|
std::copy(std::begin(oversized.data),
|
|
std::next(std::begin(oversized.data), oversized.size),
|
|
std::begin(out));
|
|
return out;
|
|
}
|
|
|
|
template <std::size_t A, std::size_t B>
|
|
consteval auto cat(std::array<std::byte, A> const &a,
|
|
std::array<std::byte, B> const &b) {
|
|
std::array<std::byte, A + B> out;
|
|
std::copy(std::begin(a), std::next(std::begin(a), std::size(a)),
|
|
std::begin(out));
|
|
std::copy(std::begin(b), std::next(std::begin(b), std::size(b)),
|
|
std::next(std::begin(out), std::size(a)));
|
|
return out;
|
|
}
|
|
|
|
template <typename T, typename Itr>
|
|
constexpr auto zip(T val, Itr begin, Itr end) {
|
|
std::vector<T> output;
|
|
for (auto itr = begin; itr != end; ++itr) {
|
|
output.emplace_back(val);
|
|
output.emplace_back(*itr);
|
|
}
|
|
return output;
|
|
}
|
|
|
|
template <typename T, typename Iterable>
|
|
constexpr auto zip(T val, Iterable const &itr) {
|
|
return zip(val, std::begin(itr), std::end(itr));
|
|
}
|
|
|
|
using relaxed_reader = msgpack::reader<msgpack::reader_policy::relaxed>;
|
|
|
|
} // namespace
|
|
|
|
suite relaxed = [] {
|
|
"empty span"_test = [] {
|
|
using error = msgpack::reader_error;
|
|
std::span<std::byte> bytes;
|
|
relaxed_reader reader(bytes);
|
|
auto v = reader.read<msgpack::format::uint8>();
|
|
expect(v.error() == error::end_of_message);
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Unsigned integers
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
"reader<reader_policy::relaxed>::read<format::uint8>"_test = [] {
|
|
using fmt = format::uint8;
|
|
using error = msgpack::reader_error;
|
|
/**
|
|
* All bytes 0x00->0x79 are effectively literal uint8s.
|
|
*/
|
|
{
|
|
constexpr auto payload = make_bytes(0x52, 0xcc, 0x84);
|
|
relaxed_reader reader(payload);
|
|
{
|
|
auto result = reader.read<fmt>();
|
|
expect(result == std::uint8_t(0x52));
|
|
}
|
|
{
|
|
auto result = reader.read<fmt>();
|
|
expect(result == std::uint8_t(0x84));
|
|
}
|
|
|
|
auto result = reader.read<fmt>();
|
|
expect(result == tl::make_unexpected(error::end_of_message));
|
|
}
|
|
};
|
|
|
|
"reader<reader_policy::relaxed>::read<formats::uint16>"_test = [] {
|
|
using fmt = msgpack::format::uint16;
|
|
using error = msgpack::reader_error;
|
|
/**
|
|
* All bytes 0x00->0x79 are effectively literal uint8s.
|
|
*/
|
|
{
|
|
constexpr auto payload = make_bytes(0x52, 0xcc, 0x84, 0xcd, 0xaa, 0xcc);
|
|
relaxed_reader reader(payload);
|
|
{
|
|
auto result = reader.read<fmt>();
|
|
expect(result == std::uint16_t(0x52));
|
|
}
|
|
{
|
|
auto result = reader.read<fmt>();
|
|
expect(result == std::uint16_t(0x84));
|
|
}
|
|
{
|
|
auto result = reader.read<fmt>();
|
|
expect(result == std::uint16_t(0xaacc));
|
|
}
|
|
|
|
auto result = reader.read<fmt>();
|
|
expect(result == tl::make_unexpected(error::end_of_message));
|
|
}
|
|
};
|
|
};
|
|
|