Browse Source

Refactored cbor tests, still need work

channel
Ludovic 'Archivist' Lagouardette 3 years ago
parent
commit
2ec7a62e09
2 changed files with 632 additions and 276 deletions
  1. +162
    -43
      include/gp/ipc/envelope/cbor.hpp
  2. +470
    -233
      tests/cbor_test.cpp

+ 162
- 43
include/gp/ipc/envelope/cbor.hpp View File

@ -7,6 +7,8 @@
#include <gp/functional/variant.hpp>
#include <gp/containers/vector.hpp>
#include <concepts>
// TODO: Rewrite in a more ORM-like way
// TODO: Implement some bignum for support
@ -113,12 +115,6 @@ namespace gp {
template<typename T>
vector<char>& push_as_cbor(vector<char>&, T);
template<typename T>
vector<char>& push_as_cbor(vector<char>&, T&);
inline vector<char>& push_integer_with_header_as_cbor(vector<char>& src, uint8_t header, uint64_t value) {
auto norm_v = (value<0) ? -value : value;
@ -156,8 +152,8 @@ namespace gp {
* @param value the value to push, can be signed
* @return vector<char>& the same reference that was received for the source
*/
template<>
inline vector<char>& push_as_cboro"><int64_t>(vector<char>& src, kt">int64_t& value) {
template<n">std::signed_integral T>
inline vector<char>& push_as_cbor(vector<char>& src, n">T value) {
uint8_t sign = (value<0) ? 0b00100000 : 0;
auto norm_v = (value<0) ? -value : value;
return push_integer_with_header_as_cbor(src, sign, norm_v);
@ -170,33 +166,29 @@ namespace gp {
* @param value the value to push, cannot be signed
* @return vector<char>& the same reference that was received for the source
*/
template<>
inline vector<char>& push_as_cboro"><uint64_t>(vector<char>& src, kt">uint64_t& value) {
template<n">std::unsigned_integral T>
inline vector<char>& push_as_cbor(vector<char>& src, n">T value) {
return push_integer_with_header_as_cbor(src, 0, value);
}
template<>
inline vector<char>& push_as_cbor<std::nullptr_t>(vector<char>& src, std::nullptr_t) {
inline vector<char>& push_as_cbor(vector<char>& src, std::nullptr_t) {
src.push_back(0b11110110);
return src;
}
struct cbor_undefined{};
template<>
inline vector<char>& push_as_cbor<cbor_undefined>(vector<char>& src, cbor_undefined) {
inline vector<char>& push_as_cbor(vector<char>& src, cbor_undefined) {
src.push_back(0b11110111);
return src;
}
template<>
inline vector<char>& push_as_cbor<bool>(vector<char>& src, bool value) {
inline vector<char>& push_as_cbor(vector<char>& src, bool value) {
src.push_back(0b11110100+(value ? 1 : 0));
return src;
}
template<>
inline vector<char>& push_as_cbor<gp::buffer<char>>(vector<char>& src, gp::buffer<char> value) {
inline vector<char>& push_as_cbor(vector<char>& src, gp::buffer<char> value) {
push_integer_with_header_as_cbor(src, (uint8_t)0b01000000, value.size());
for(auto byte : value) {
src.push_back(byte);
@ -212,20 +204,24 @@ namespace gp {
size_t size;
};
template<>
inline vector<char>& push_as_cbor<cbor_array_initiator>(vector<char>& src, cbor_array_initiator value) {
inline vector<char>& push_as_cbor(vector<char>& src, cbor_array_initiator value) {
return push_integer_with_header_as_cbor(src, (uint8_t)0b10000000, value.size);
}
template<>
inline vector<char>& push_as_cbor<cbor_associative_array_initiator>(vector<char>& src, cbor_associative_array_initiator value) {
inline vector<char>& push_as_cbor(vector<char>& src, cbor_associative_array_initiator value) {
return push_integer_with_header_as_cbor(src, (uint8_t)0b10100000, value.size);
}
template<typename First, typename Second>
inline vector<char>& push_as_cbor(vector<char>& src, gp::pair<First, Second> value) {
push_as_cbor(src,value.first);
return push_as_cbor(src,value.second);
}
template<typename First, typename Second>
inline vector<char>& push_as_cbor(vector<char>& src, gp::pair<First, Second>& value) {
push_as_cbor<First>(src,value.first);
return push_as_cbor<Second>(src,value.second);
push_as_cbor(src,value.first);
return f">push_as_cbor(src,value.second);
}
struct cbor_tag_initiator {
@ -235,15 +231,14 @@ namespace gp {
};
};
template<>
inline vector<char>& push_as_cbor<cbor_tag_initiator>(vector<char>& src, cbor_tag_initiator value) {
inline vector<char>& push_as_cbor(vector<char>& src, cbor_tag_initiator value) {
return push_integer_with_header_as_cbor(src, (uint8_t)0b11000000, value.as_integer);
}
using parsing_state = gp::buffer<char>;
template<typename T>
gp::pair<gp::optional<T>, parsing_state> read_cbor(parsing_state state);
gp::pair<gp::optional<T>, parsing_state> read_cbor(parsing_state state, gp::allocator&);
inline gp::pair<gp::optional<uint64_t>, parsing_state> pull_arbitrary_integer_from_cbor(parsing_state state) {
auto local = (uint8_t)0b00011111 & (uint8_t)*state.begin();
@ -258,21 +253,21 @@ namespace gp {
case cbor_oths::word: {
if(state.size() < 3) return {nullopt, state};
return {
uint16_t(*(state.slice_start(3).slice_end(2).cast<gp::endian_wrapper<uint16_t, endian::big>>().begin().data)),
uint16_t(*(state.slice_start(3).slice_end(2).cast<gp::endian_wrapper<uint16_t, endian::big>>().begin())),
{state.begin()+3, state.end()}
};
}
case cbor_oths::dword: {
if(state.size() < 5) return {nullopt, state};
return {
uint32_t(*(state.slice_start(5).slice_end(4).cast<gp::endian_wrapper<uint32_t, endian::big>>().begin().data)),
uint32_t(*(state.slice_start(5).slice_end(4).cast<gp::endian_wrapper<uint32_t, endian::big>>().begin())),
{state.begin()+5, state.end()}
};
}
case cbor_oths::qword: {
if(state.size() < 9) return {nullopt, state};
return {
uint64_t(*(state.slice_start(9).slice_end(8).cast<gp::endian_wrapper<uint64_t, endian::big>>().begin().data)),
uint64_t(*(state.slice_start(9).slice_end(8).cast<gp::endian_wrapper<uint64_t, endian::big>>().begin())),
{state.begin()+9, state.end()}
};
}
@ -283,8 +278,9 @@ namespace gp {
}
}
template<>
inline gp::pair<gp::optional<uint64_t>, parsing_state> read_cbor<uint64_t>(parsing_state state) {
template<std::integral T>
inline gp::pair<gp::optional<int64_t>, parsing_state> read_cbor(parsing_state state, gp::allocator&) {
// TODO: Handling of over and underflow
if(state.size()) return {nullopt, state};
auto type = cbor_type(((uint8_t)0b11100000 & (uint8_t)*state.begin()) >> 5);
@ -309,30 +305,153 @@ namespace gp {
template<>
inline gp::pair<gp::optional<kt">int64_t>, parsing_state> read_cbor<kt">int64_t>(parsing_state state) {
inline gp::pair<gp::optional<n">cbor_tag_initiator>, parsing_state> read_cbor<n">cbor_tag_initiator>(parsing_state state, gp::allocator&) {
if(state.size()) return {nullopt, state};
auto type = cbor_type(((uint8_t)0b11100000 & (uint8_t)*state.begin()) >> 5);
switch(type) {
case cbor_type::uint:
case cbor_type::tags:
{
auto[value, new_state] = pull_arbitrary_integer_from_cbor(state);
if(value.has_value()) return {value.value(), new_state};
if(value.has_value()) return {cbor_tag_initiator{.as_integer = value.value()}, new_state};
break;
}
case cbor_type::nint:
default: break;
}
return {nullopt, state};
}
template<>
inline gp::pair<gp::optional<gp::vector<char>>, parsing_state> read_cbor<gp::vector<char>>(parsing_state state, gp::allocator& alloc) {
if(state.size()) return {nullopt, state};
auto type = cbor_type(((uint8_t)0b11100000 & (uint8_t)*state.begin()) >> 5);
switch(type) {
case cbor_type::bstr:
{
auto[value, new_state] = pull_arbitrary_integer_from_cbor(state);
if(
value.has_value()
&& value.value() < (uint64_t)std::numeric_limits<int64_t>::max()
) {
return {-value.value(), new_state};
const auto[size, new_state] = pull_arbitrary_integer_from_cbor(state);
if(!size.has_value()) break;
if(new_state.size()<size.value()) break;
gp::vector<char> return_value{alloc};
if(!return_value.reserve(size.value())) break;
auto end_it = new_state.begin() + size.value();
for(auto it = new_state.begin(); it != end_it; it++) {
return_value.push_back(*it);
}
return {optional<gp::vector<char>>(gp::move(return_value)), parsing_state(new_state.begin() + size.value(), new_state.end())};
break;
}
default: break;
}
return {nullopt, state};
}
}
template<>
inline gp::pair<gp::optional<std::nullptr_t>, parsing_state> read_cbor<std::nullptr_t>(parsing_state state, gp::allocator& alloc) {
if(state.size()) return {nullopt, state};
auto type = cbor_type(((uint8_t)0b11100000 & (uint8_t)*state.begin()) >> 5);
switch(type) {
case cbor_type::oths:
{
const auto[value, new_state] = pull_arbitrary_integer_from_cbor(state);
if(!value.has_value()) break;
if(new_state.size()<value.value()) break;
gp::vector<char> return_value{alloc};
if(value.value() == 22)
{
return {optional(nullptr), parsing_state(new_state.begin()+1, new_state.end())};
}
break;
}
default: break;
}
return {nullopt, state};
}
template<>
inline gp::pair<gp::optional<cbor_undefined>, parsing_state> read_cbor<cbor_undefined>(parsing_state state, gp::allocator& alloc) {
if(state.size()) return {nullopt, state};
auto type = cbor_type(((uint8_t)0b11100000 & (uint8_t)*state.begin()) >> 5);
switch(type) {
case cbor_type::oths:
{
const auto[value, new_state] = pull_arbitrary_integer_from_cbor(state);
if(!value.has_value()) break;
if(new_state.size()<value.value()) break;
gp::vector<char> return_value{alloc};
if(value.value() == 23)
{
return {optional(cbor_undefined{}), parsing_state(new_state.begin()+1, new_state.end())};
}
break;
}
default: break;
}
return {nullopt, state};
}
/**
* @brief
*
* @param state
* @param callback a callback that returns a new parsing state for every element read. It should follow the heredescribed signature: parsing_state(parsing_state, gp::allocator&)
* @param count_callback a callback that is used to check if the process should proceed given a count of elements in the list. It should follow the heredescribed signature: bool(uint64_t)
* @param alloc
*/
template<typename applier_cb, typename counter_cb>
inline parsing_state read_cbor_array(parsing_state state, gp::allocator& alloc, applier_cb callback, counter_cb count_callback = [](uint64_t) -> bool {return true;}) {
if(state.size()) return state;
auto type = cbor_type(((uint8_t)0b11100000 & (uint8_t)*state.begin()) >> 5);
switch(type) {
case cbor_type::list:
{
const auto[size, new_state] = pull_arbitrary_integer_from_cbor(state);
if(!size.has_value()) return state;
if(new_state.size()<size.value()) return state;
if(!count_callback(size.value()))return state;
parsing_state forward = new_state;
for(auto idx = 0ull; idx != size.value(); idx++) {
if(forward.size() == 0) return state;
forward = callback(forward, alloc);
}
return forward;
}
default: return state;
}
}
/**
* @brief
*
* @param state
* @param callback a callback that returns a new parsing state for every element read. It should follow the heredescribed signature: parsing_state(parsing_state, gp::allocator&), it MUST read exactly 2 cbor value from the stream.
* @param count_callback a callback that is used to check if the process should proceed given a count of elements in the list. It should follow the heredescribed signature: bool(uint64_t)
* @param alloc
*/
template<typename applier_cb, typename counter_cb>
inline parsing_state read_cbor_kv_list(parsing_state state, gp::allocator& alloc, applier_cb callback, counter_cb count_callback = [](uint64_t) -> bool {return true;}) {
if(!state.size()) return state;
auto type = cbor_type(((uint8_t)0b11100000 & (uint8_t)*state.begin()) >> 5);
switch(type) {
case cbor_type::hmap:
{
const auto[size, new_state] = pull_arbitrary_integer_from_cbor(state);
if(!size.has_value()) return state;
if(!count_callback(size.value()))return state;
parsing_state forward = new_state;
for(auto idx = 0ull; idx != size.value(); idx++) {
if(forward.size() < 2ull) return state;
forward = callback(forward, alloc);
forward = callback(forward, alloc);
}
return forward;
}
default: return state;
}
}
}

+ 470
- 233
tests/cbor_test.cpp View File

@ -5,15 +5,20 @@
#include <gp/ipc/envelope/cbor.hpp>
#include "test_scaffold.h"
struct cbor_test : public test_scaffold {
cbor_test() {
name = __FILE__ ":1";
#include <bitset>
#include <sstream>
struct generic_cbor_test : public test_scaffold {
std::unique_ptr<gp::array<char, 4096*4>> store = std::make_unique<gp::array<char, 4096*4>>();
gp::arena alloc{&*store->begin(), store->size()};
};
struct cbor_test1 : public generic_cbor_test {
cbor_test1() {
name = __FILE__ ":" "##1";
}
virtual int run() {
auto store = std::make_unique<gp::array<char, 4096*4>>();
gp::arena alloc{&*store->begin(), store->size()};
using some_int = gp::fixed_variant<int, unsigned int, long long>;
{
some_int a{16};
@ -21,18 +26,51 @@ struct cbor_test : public test_scaffold {
b = a;
gp_config::assertion(b.is_a<int>(), "b got wrong type assigned");
}
return 0;
}
};
struct cbor_test2 : public generic_cbor_test {
cbor_test2() {
name = __FILE__ ":" "##2";
}
virtual int run() {
using some_int = gp::fixed_variant<int, unsigned int, long long>;
{
some_int a{16u};
some_int b = a;
gp_config::assertion(b.is_a<unsigned int>(), "b got wrong type assigned");
gp_config::assertion(b.value<unsigned int>() == 16, "b got wrong value assigned");
}
return 0;
}
};
struct cbor_test3 : public generic_cbor_test {
cbor_test3() {
name = __FILE__ ":" "##3";
}
virtual int run() {
using some_int = gp::fixed_variant<int, unsigned int, long long>;
{
some_int a{16u};
some_int b = gp::move(a);
gp_config::assertion(b.is_a<unsigned int>(), "b got wrong type assigned");
gp_config::assertion(b.value<unsigned int>() == 16, "b got wrong value assigned");
}
return 0;
}
};
struct cbor_test4 : public generic_cbor_test {
cbor_test4() {
name = __FILE__ ":" "##4";
}
virtual int run() {
using some_int = gp::fixed_variant<int, unsigned int, long long>;
{
some_int a{16u};
some_int b;
@ -40,6 +78,17 @@ struct cbor_test : public test_scaffold {
gp_config::assertion(b.is_a<unsigned int>(), "b got wrong type assigned");
gp_config::assertion(b.value<unsigned int>() == 16, "b got wrong value assigned");
}
return 0;
}
};
struct cbor_test5 : public generic_cbor_test {
cbor_test5() {
name = __FILE__ ":" "##5";
}
virtual int run() {
using some_int = gp::fixed_variant<int, unsigned int, long long>;
{
some_int a{16u};
some_int b;
@ -47,6 +96,17 @@ struct cbor_test : public test_scaffold {
gp_config::assertion(b.is_a<unsigned int>(), "b got wrong type assigned");
gp_config::assertion(b.value<unsigned int>() == 16, "b got wrong value assigned");
}
return 0;
}
};
struct cbor_test6 : public generic_cbor_test {
cbor_test6() {
name = __FILE__ ":" "##6";
}
virtual int run() {
using some_int = gp::fixed_variant<int, unsigned int, long long>;
{
gp::vector<some_int> vec{alloc};
vec.emplace_back(12u);
@ -54,292 +114,500 @@ struct cbor_test : public test_scaffold {
gp_config::assertion(vec[0].is_a<unsigned int>(), "vec0 got wrong type assigned");
gp_config::assertion(vec[1].is_a<int>(), "vec1 got wrong type assigned");
}
return 0;
}
};
append_test dummy_pg5zhr8bv(new cbor_test{});
struct cbor_test7 : public generic_cbor_test {
cbor_test7() {
name = __FILE__ ":" "##7";
}
virtual int run() {
using some_int = gp::fixed_variant<int, unsigned int, long long>;
{
gp::vector<char> serialized(alloc);
gp::push_as_cbor(serialized, gp::cbor_associative_array_initiator{2});
gp::push_as_cbor(serialized, gp::make_pair(uint64_t(12), int64_t(-98)));
gp::push_as_cbor(serialized, gp::make_pair(uint64_t(13), int64_t(98)));
log_segment("serialized[0]", std::to_string((unsigned char)serialized[0]).c_str());
log_segment("serialized[1]", std::to_string((unsigned char)serialized[1]).c_str());
log_segment("serialized[2]", std::to_string((unsigned char)serialized[2]).c_str());
log_segment("serialized[3]", std::to_string((unsigned char)serialized[3]).c_str());
log_segment("serialized[4]", std::to_string((unsigned char)serialized[4]).c_str());
log_segment("serialized[5]", std::to_string((unsigned char)serialized[5]).c_str());
log_segment("serialized[6]", std::to_string((unsigned char)serialized[6]).c_str());
gp::array<char, 7> serialized_manual{
char(0b10100010),
char(0b00001100),
char(0b00111000), char(98),
char(0b00001101),
char(0b00011000), char(98)
};
gp_config::assertion(serialized.size() == serialized_manual.size(), "could not encode: wrong output size");
for(size_t idx = 0; idx < serialized_manual.size(); idx++) {
gp_config::assertion(serialized[idx] == serialized_manual[idx], "data did not serialize correctly");
}
auto state = serialized_manual.as_buffer();
size_t count = 0;
auto count_handler = [](size_t size){
{
std::bitset<sizeof(size_t)*8> size_bits{size};
std::stringstream v;
v << size_bits;
log_segment("size bits", v.str().c_str());
}
{
std::bitset<sizeof(size_t)*8> size_bits{-size};
std::stringstream v;
v << size_bits;
log_segment("-size bits", v.str().c_str());
}
{
log_segment("-size value", std::to_string((size_t)-size).c_str());
}
gp_config::assertion(size == 2, "could not decode the correct size");
return true;
};
/*
TODO: REWRITE THOSE BAD BOIS
auto callback_handler = [&count](gp::parsing_state state, gp::allocator& alloc) {
count++;
switch(count-1) {
case 0: {
auto [value, new_state] = gp::read_cbor<int64_t>(state, alloc);
gp_config::assertion(value.has_value(), "could not encode value");
gp_config::assertion(value.value() == 12, "could not encode the correct size");
return new_state;
}
case 1:{
auto [value, new_state] = gp::read_cbor<int64_t>(state, alloc);
gp_config::assertion(value.has_value(), "could not encode value");
gp_config::assertion(value.value() == -98, "could not encode the correct size");
return new_state;
}
case 2:{
auto [value, new_state] = gp::read_cbor<int64_t>(state, alloc);
gp_config::assertion(value.has_value(), "could not encode value");
gp_config::assertion(value.value() == 13, "could not encode the correct size");
return new_state;
}
case 3:{
auto [value, new_state] = gp::read_cbor<int64_t>(state, alloc);
gp_config::assertion(value.has_value(), "could not encode value");
gp_config::assertion(value.value() == 98, "could not encode the correct size");
return new_state;
}
default: return state;
}
};
auto new_state = read_cbor_kv_list(
state,
alloc,
callback_handler,
count_handler
);
gp_config::assertion(state.size() > new_state.size(), "reading succeeded");
gp_config::assertion(new_state.size() == 0, "something is left in the string");
}
return 0;
}
};
struct cbor_test8 : public generic_cbor_test {
cbor_test8() {
name = __FILE__ ":" "##8";
}
virtual int run() {
using some_int = gp::fixed_variant<int, unsigned int, long long>;
{
gp::cbor_value data{alloc};
auto gen = data.new_object();
gen.push_back(gp::make_pair(gp::cbor_value{uint8_t(12), alloc}, gp::cbor_value{int32_t(-98), alloc}));
gen.push_back(gp::make_pair(gp::cbor_value{uint8_t(13), alloc}, gp::cbor_value{uint32_t(98), alloc}));
data = gen;
gp::array<std::byte, 7> serialized;
gp::array<std::byte, 7> serialized_manual{
std::byte(0b10100010),
std::byte(0b00001100),
std::byte(0b00111000), std::byte(98),
std::byte(0b00001101),
std::byte(0b00011000), std::byte(98)
gp::vector<char> serialized(alloc);
gp::array<char, 1> serialized_manual{
char(1)
};
auto ret_it = data.encode(serialized.as_buffer());
gp::push_as_cbor(serialized, 1);
gp_config::assertion(serialized.begin() != ret_it, "could not encode");
gp_config::assertion(serialized == serialized_manual, "data did not serialize correctly");
gp_config::assertion(serialized.size() == serialized_manual.size(), "could not encode (wrong size)");
gp_config::assertion(serialized[0] == serialized_manual[0], "data did not encode correctly");
gp::fill(serialized,(std::byte)0);
auto [value, new_state] = gp::read_cbor<int>(serialized.as_buffer(), alloc);
auto decoded = gp::cbor_value::decode(alloc, serialized_manual.as_buffer());
ret_it = decoded.first.encode(serialized.as_buffer());
gp_config::assertion(serialized.begin() != ret_it, "could not encode");
gp_config::assertion(serialized == serialized_manual, "data did not serialize correctly");
gp_config::assertion(value.has_value(), "could not redecode");
gp_config::assertion(value.value() == 1, "data did not serialize correctly: wrong value decoded");
}
{
gp::cbor_value data{alloc};
data = gp::cbor_number(1);
return 0;
}
};
struct cbor_test9 : public generic_cbor_test {
cbor_test9() {
name = __FILE__ ":" "##9";
}
gp::array<std::byte, 1> serialized;
gp::array<std::byte, 1> serialized_manual{
std::byte(1)
virtual int run() {
using some_int = gp::fixed_variant<int, unsigned int, long long>;
{
gp::vector<char> serialized(alloc);
gp::array<char, 3> serialized_manual{
char(0b00011001),
char(0b00000100),
char(0b00000000)
};
auto ret_it = data.encode(serialized.as_buffer());
n">gp::push_as_cbor(serialized, 1024);
gp_config::assertion(serialized.begin() != ret_it, "could not encode");
gp_config::assertion(serialized == serialized_manual, "data did not serialize correctly");
gp_config::assertion(serialized_manual.size() == serialized.size(), "could not encode");
for(size_t idx = 0; idx < serialized_manual.size(); idx++) {
gp_config::assertion(serialized[idx] == serialized_manual[idx], "data did not serialize correctly");
}
gp::fill(serialized,(std::byte)0);
auto [value, state] = gp::read_cbor<int>(serialized.as_buffer(), alloc);
gp_config::assertion(value.has_value(), "could not decode");
gp_config::assertion(value.value() == 1024, "data did not decode correctly");
}
auto decoded = gp::cbor_value::decode(alloc, serialized_manual.as_buffer());
ret_it = decoded.first.encode(serialized.as_buffer());
return 0;
}
};
gp_config::assertion(serialized.begin() != ret_it, "could not encode");
gp_config::assertion(serialized == serialized_manual, "data did not serialize correctly");
}
{
gp::cbor_value data{alloc};
data = bool(false);
struct cbor_test10 : public generic_cbor_test {
cbor_test10() {
name = __FILE__ ":" "##10";
}
gp::array<std::byte, 1> serialized;
gp::array<std::byte, 1> serialized_manual{
std::byte(0b11100000+20)
virtual int run() {
using some_int = gp::fixed_variant<int, unsigned int, long long>;
{
gp::vector<char> serialized(alloc);
gp::array<char, 5> serialized_manual{
char(0b00011010),
char(0xAA),
char(0xBB),
char(0xCC),
char(0xDD)
};
auto ret_it = data.encode(serialized.as_buffer());
n">gp::push_as_cbor(serialized, 0xAABBCCDD);
gp_config::assertion(serialized.begin() != ret_it, "could not encode");
gp_config::assertion(serialized == serialized_manual, "data did not serialize correctly");
gp_config::assertion(serialized_manual.size() == serialized.size(), "could not encode");
for(size_t idx = 0; idx < serialized_manual.size(); idx++) {
gp_config::assertion(serialized[idx] == serialized_manual[idx], "data did not serialize correctly");
}
gp::fill(serialized,(std::byte)0);
auto [value, state] = gp::read_cbor<uint64_t>(serialized.as_buffer(), alloc);
gp_config::assertion(value.has_value(), "could not decode");
gp_config::assertion(value.value() == 0xAABBCCDD, "data did not decode correctly");
}
auto decoded = gp::cbor_value::decode(alloc, serialized_manual.as_buffer());
ret_it = decoded.first.encode(serialized.as_buffer());
return 0;
}
};
gp_config::assertion(serialized.begin() != ret_it, "could not encode");
gp_config::assertion(serialized == serialized_manual, "data did not serialize correctly");
}
{
gp::cbor_value data{alloc};
data = bool(true);
struct cbor_test11 : public generic_cbor_test {
cbor_test11() {
name = __FILE__ ":" "##11";
}
gp::array<std::byte, 1> serialized;
gp::array<std::byte, 1> serialized_manual{
std::byte(0b11100000+21)
virtual int run() {
using some_int = gp::fixed_variant<int, unsigned int, long long>;
{
gp::vector<char> serialized(alloc);
gp::array<char, 9> serialized_manual{
char(0b00011011),
char(0xAA),
char(0xBB),
char(0xCC),
char(0xDD),
char(0xEE),
char(0xFF),
char(0x00),
char(0x11)
};
auto ret_it = data.encode(serialized.as_buffer());
n">gp::push_as_cbor(serialized, 0xAABBCCDDEEFF0011ull);
gp_config::assertion(serialized.begin() != ret_it, "could not encode");
gp_config::assertion(serialized == serialized_manual, "data did not serialize correctly");
gp_config::assertion(serialized_manual.size() == serialized.size(), "could not encode");
for(size_t idx = 0; idx < serialized_manual.size(); idx++) {
gp_config::assertion(serialized[idx] == serialized_manual[idx], "data did not serialize correctly");
}
gp::fill(serialized,(std::byte)0);
auto [value, state] = gp::read_cbor<uint64_t>(serialized.as_buffer(), alloc);
gp_config::assertion(value.has_value(), "could not decode");
gp_config::assertion(value.value() == 0xAABBCCDDEEFF0011ull, "data did not decode correctly");
}
auto decoded = gp::cbor_value::decode(alloc, serialized_manual.as_buffer());
ret_it = decoded.first.encode(serialized.as_buffer());
return 0;
}
};
gp_config::assertion(serialized.begin() != ret_it, "could not encode");
gp_config::assertion(serialized == serialized_manual, "data did not serialize correctly");
}
{
gp::cbor_value data{gp::nullopt, alloc};
struct cbor_test12 : public generic_cbor_test {
cbor_test12() {
name = __FILE__ ":" "##12";
}
gp::array<std::byte, 1> serialized;
gp::array<std::byte, 1> serialized_manual{
std::byte(0b11100000+22)
virtual int run() {
using some_int = gp::fixed_variant<int, unsigned int, long long>;
{
gp::vector<char> serialized(alloc);
gp::array<char, 1> serialized_manual{
char(0b11100000+22)
};
auto ret_it = data.encode(serialized.as_buffer());
n">gp::push_as_cbor(serialized, nullptr);
gp_config::assertion(serialized.begin() != ret_it, "could not encode");
gp_config::assertion(serialized == serialized_manual, "data did not serialize correctly");
gp_config::assertion(serialized.size() == serialized_manual.size(), "could not encode");
gp_config::assertion(serialized[0] == serialized_manual[0], "data did not serialize correctly");
gp::fill(serialized,(std::byte)0);
k">auto [value, state] = gp::read_cbor<std::nullptr_t>(serialized.as_buffer(), alloc);
auto decoded = gp::cbor_value::decode(alloc, serialized_manual.as_buffer());
ret_it = decoded.first.encode(serialized.as_buffer());
gp_config::assertion(serialized.begin() != ret_it, "could not encode");
gp_config::assertion(serialized == serialized_manual, "data did not serialize correctly");
gp_config::assertion(value.has_value(), "could not encode");
gp_config::assertion(value.value() == nullptr, "data did not decode correctly");
}
{
gp::cbor_value data{alloc};
gp::array<std::byte, 1> serialized;
gp::array<std::byte, 1> serialized_manual{
std::byte(0b11100000+23)
};
return 0;
}
};
auto ret_it = data.encode(serialized.as_buffer());
struct cbor_test13 : public generic_cbor_test {
cbor_test13() {
name = __FILE__ ":" "##13";
}
gp_config::assertion(serialized.begin() != ret_it, "could not encode");
gp_config::assertion(serialized == serialized_manual, "data did not serialize correctly");
virtual int run() {
using some_int = gp::fixed_variant<int, unsigned int, long long>;
{
gp::vector<char> serialized(alloc);
gp::array<char, 1> serialized_manual{
char(0b11100000+21)
};
gp::fill(serialized,(std::byte)0);
gp::push_as_cbor(serialized, true);
auto decoded = gp::cbor_value::decode(alloc, serialized_manual.as_buffer());
ret_it = decoded.first.encode(serialized.as_buffer());
n">gp_config::assertion(serialized.size() == serialized_manual.size(), "could not encode");
gp_config::assertion(serialized[0] == serialized_manual[0], "data did not serialize correctly");
gp_config::assertion(serialized.begin() != ret_it, "could not encode");
gp_config::assertion(serialized == serialized_manual, "data did not serialize correctly");
auto [value, state] = gp::read_cbor<bool>(serialized.as_buffer(), alloc);
gp_config::assertion(value.has_value(), "could not encode");
gp_config::assertion(value.value() == true, "data did not decode correctly");
}
{
gp::cbor_value data{alloc};
data = gp::cbor_number(128);
gp::array<std::byte, 2> serialized;
gp::array<std::byte, 2> serialized_manual{
std::byte(0b00011000),
std::byte(0b10000000)
};
return 0;
}
};
auto ret_it = data.encode(serialized.as_buffer());
struct cbor_test14 : public generic_cbor_test {
cbor_test14() {
name = __FILE__ ":" "##14";
}
gp_config::assertion(serialized.begin() != ret_it, "could not encode");
gp_config::assertion(serialized == serialized_manual, "data did not serialize correctly");
virtual int run() {
using some_int = gp::fixed_variant<int, unsigned int, long long>;
{
gp::vector<char> serialized(alloc);
gp::array<char, 1> serialized_manual{
char(0b11100000+20)
};
gp::fill(serialized,(std::byte)0);
gp::push_as_cbor(serialized, false);
auto decoded = gp::cbor_value::decode(alloc, serialized_manual.as_buffer());
ret_it = decoded.first.encode(serialized.as_buffer());
n">gp_config::assertion(serialized.size() == serialized_manual.size(), "could not encode");
gp_config::assertion(serialized[0] == serialized_manual[0], "data did not serialize correctly");
gp_config::assertion(serialized.begin() != ret_it, "could not encode");
gp_config::assertion(serialized == serialized_manual, "data did not serialize correctly");
auto [value, state] = gp::read_cbor<bool>(serialized.as_buffer(), alloc);
gp_config::assertion(value.has_value(), "could not encode");
gp_config::assertion(value.value() == false, "data did not decode correctly");
}
{
gp::cbor_value data{alloc};
data = gp::cbor_number(1024);
gp::array<std::byte, 3> serialized;
gp::array<std::byte, 3> serialized_manual{
std::byte(0b00011001),
std::byte(0b00000100),
std::byte(0b00000000)
};
return 0;
}
};
auto ret_it = data.encode(serialized.as_buffer());
struct cbor_test15 : public generic_cbor_test {
cbor_test15() {
name = __FILE__ ":" "##15";
}
gp_config::assertion(serialized.begin() != ret_it, "could not encode");
gp_config::assertion(serialized == serialized_manual, "data did not serialize correctly");
virtual int run() {
using some_int = gp::fixed_variant<int, unsigned int, long long>;
{
gp::vector<char> serialized(alloc);
gp::array<char, 1> serialized_manual{
char(0b11100000+24)
};
gp::fill(serialized,(std::byte)0);
gp::push_as_cbor(serialized, gp::cbor_undefined{});
auto decoded = gp::cbor_value::decode(alloc, serialized_manual.as_buffer());
ret_it = decoded.first.encode(serialized.as_buffer());
n">gp_config::assertion(serialized.size() == serialized_manual.size(), "could not encode");
gp_config::assertion(serialized[0] == serialized_manual[0], "data did not serialize correctly");
gp_config::assertion(serialized.begin() != ret_it, "could not encode");
gp_config::assertion(serialized == serialized_manual, "data did not serialize correctly");
auto [value, state] = gp::read_cbor<gp::cbor_undefined>(serialized.as_buffer(), alloc);
gp_config::assertion(value.has_value(), "could not encode");
}
return 0;
}
};
struct cbor_test16 : public generic_cbor_test {
cbor_test16() {
name = __FILE__ ":" "##16";
}
virtual int run() {
using some_int = gp::fixed_variant<int, unsigned int, long long>;
{
gp::cbor_value data{alloc};
data = gp::cbor_number(0xAABBCCDDu);
gp::vector<char> str{alloc};
str.reserve(5);
for(auto a : {'h', 'e', 'l', 'l', 'o'})
str.push_back((char)a);
gp::array<std::byte, 5> serialized;
gp::array<std::byte, 5> serialized_manual{
std::byte(0b00011010),
std::byte(0xAA),
std::byte(0xBB),
std::byte(0xCC),
std::byte(0xDD)
gp::vector<char> serialized(alloc);
gp::array<char, 6> serialized_manual{
char(0b01000101),
char('h'),
char('e'),
char('l'),
char('l'),
char('o')
};
k">auto ret_it = data.encode(serialized.as_buffer());
n">gp::push_as_cbor(serialized, str.as_buffer());
gp_config::assertion(serialized.begin() != ret_it, "could not encode");
gp_config::assertion(serialized == serialized_manual, "data did not serialize correctly");
gp_config::assertion(serialized.size() != serialized_manual.size(), "could not encode");
for(size_t idx = 0; idx < serialized_manual.size(); idx++) {
gp_config::assertion(serialized[idx] == serialized_manual[idx], "data did not serialize correctly");
}
gp::fill(serialized,(std::byte)0);
auto [value, state] = gp::read_cbor<gp::vector<char>>(serialized.as_buffer(), alloc);
gp_config::assertion(value.has_value(), "could not decode");
gp_config::assertion(value.value() == str, "data did not decode correctly");
}
auto decoded = gp::cbor_value::decode(alloc, serialized_manual.as_buffer());
ret_it = decoded.first.encode(serialized.as_buffer());
return 0;
}
gp_config::assertion(serialized.begin() != ret_it, "could not encode");
gp_config::assertion(serialized == serialized_manual, "data did not serialize correctly");
}
{
gp::cbor_value data{alloc};
data = gp::cbor_number(false, 0xAABBCCDDEEFF0011ull);
};
gp::array<std::byte, 9> serialized;
gp::array<std::byte, 9> serialized_manual{
std::byte(0b00011011),
std::byte(0xAA),
std::byte(0xBB),
std::byte(0xCC),
std::byte(0xDD),
std::byte(0xEE),
std::byte(0xFF),
std::byte(0x00),
std::byte(0x11)
struct cbor_test17 : public generic_cbor_test {
cbor_test17() {
name = __FILE__ ":" "##17";
}
virtual int run() {
using some_int = gp::fixed_variant<int, unsigned int, long long>;
{
gp::vector<char> str{alloc};
str.reserve(5);
for(auto a : {'h', 'e', 'l', 'l', 'o'})
str.push_back((char)a);
gp::vector<char> serialized(alloc);
gp::array<char, 31> serialized_manual{
char(0b10000101),
char(0b01000101),
char('h'),
char('e'),
char('l'),
char('l'),
char('o'),
char(0b01000101),
char('h'),
char('e'),
char('l'),
char('l'),
char('o'),
char(0b01000101),
char('h'),
char('e'),
char('l'),
char('l'),
char('o'),
char(0b01000101),
char('h'),
char('e'),
char('l'),
char('l'),
char('o'),
char(0b01000101),
char('h'),
char('e'),
char('l'),
char('l'),
char('o')
};
auto ret_it = data.encode(serialized.as_buffer());
gp::push_as_cbor(serialized, gp::cbor_array_initiator{5});
gp::repeat(5,
[&](){
gp::push_as_cbor(serialized, str.as_buffer());
}
);
gp_config::assertion(serialized.size() == serialized_manual.size(), "could not encode");
for(size_t idx = 0; idx < serialized_manual.size(); idx++) {
gp_config::assertion(serialized[idx] == serialized_manual[idx], "data did not serialize correctly");
}
}
gp_config::assertion(serialized.begin() != ret_it, "could not encode");
gp_config::assertion(serialized == serialized_manual, "data did not serialize correctly");
return 0;
}
};
gp::fill(serialized,(std::byte)0);
append_test dummy_pg5zhr84bv(new cbor_test1{});
append_test dummy_pg5zdhr8bv(new cbor_test2{});
append_test dummy_pg5zhrf8bv(new cbor_test3{});
append_test dummy_pg5zhdr8bv(new cbor_test4{});
append_test dummy_pg5zghr8bv(new cbor_test5{});
append_test dummy_pg5zhfr8bv(new cbor_test6{});
append_test dummy_pg5zhrs8bv(new cbor_test7{});
append_test dummy_pg5zhrj8bv(new cbor_test8{});
append_test dummy_pg5zhrh8bv(new cbor_test9{});
append_test dummy_pg5zhrz8bv(new cbor_test10{});
append_test dummy_pg5zhrg8bv(new cbor_test11{});
append_test dummy_pg5zher8bv(new cbor_test12{});
append_test dummy_pg5zhr8rbv(new cbor_test13{});
append_test dummy_pg5zzhr8bv(new cbor_test14{});
append_test dummy_p78shrg8bv(new cbor_test15{});
append_test dummy_p4sddr8rbv(new cbor_test16{});
append_test dummy_pg5zzdjobv(new cbor_test17{});
auto decoded = gp::cbor_value::decode(alloc, serialized_manual.as_buffer());
ret_it = decoded.first.encode(serialized.as_buffer());
gp_config::assertion(serialized.begin() != ret_it, "could not encode");
gp_config::assertion(serialized == serialized_manual, "data did not serialize correctly");
}
{
gp::cbor_value data{alloc};
data = gp::cbor_number(true, 0xAABBCCDDEEFF0011ull);
/*
TODO: REWRITE THOSE BAD BOIS
gp::array<std::byte, 9> serialized;
gp::array<std::byte, 9> serialized_manual{
std::byte(0b00111011),
std::byte(0xAA),
std::byte(0xBB),
std::byte(0xCC),
std::byte(0xDD),
std::byte(0xEE),
std::byte(0xFF),
std::byte(0x00),
std::byte(0x11)
};
auto ret_it = data.encode(serialized.as_buffer());
gp_config::assertion(serialized.begin() != ret_it, "could not encode");
gp_config::assertion(serialized == serialized_manual, "data did not serialize correctly");
gp::fill(serialized,(std::byte)0);
auto decoded = gp::cbor_value::decode(alloc, serialized_manual.as_buffer());
ret_it = decoded.first.encode(serialized.as_buffer());
gp_config::assertion(serialized.begin() != ret_it, "could not encode");
gp_config::assertion(serialized == serialized_manual, "data did not serialize correctly");
}
{
gp::cbor_value data{alloc};
data = gp::cbor_floating_point(128.5f);
@ -396,37 +664,6 @@ append_test dummy_pg5zhr8bv(new cbor_test{});
gp_config::assertion(serialized.begin() != ret_it, "could not encode");
gp_config::assertion(serialized == serialized_manual, "data did not serialize correctly");
}
{
gp::vector<std::byte> str{alloc};
str.reserve(5);
for(auto a : {'h', 'e', 'l', 'l', 'o'})
str.push_back((std::byte)a);
gp::cbor_value data{alloc};
data = str;
gp::array<std::byte, 6> serialized;
gp::array<std::byte, 6> serialized_manual{
std::byte(0b01000101),
std::byte('h'),
std::byte('e'),
std::byte('l'),
std::byte('l'),
std::byte('o')
};
auto ret_it = data.encode(serialized.as_buffer());
gp_config::assertion(serialized.begin() != ret_it, "could not encode");
gp_config::assertion(serialized == serialized_manual, "data did not serialize correctly");
gp::fill(serialized,(std::byte)0);
auto decoded = gp::cbor_value::decode(alloc, serialized_manual.as_buffer());
ret_it = decoded.first.encode(serialized.as_buffer());
gp_config::assertion(serialized.begin() != ret_it, "could not encode");
gp_config::assertion(serialized == serialized_manual, "data did not serialize correctly");
}
{
gp::vector<std::byte> str{alloc};
str.reserve(5);

Loading…
Cancel
Save