General Purpose library for Freestanding C++ and POSIX systems
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

793 lines
22 KiB

#include <gp/algorithms/foreach.hpp>
#include <gp/utils/allocators/arena.hpp>
#include <gp/containers/array.hpp>
#include <gp/ipc/envelope/cbor.hpp>
#include "test_scaffold.h"
#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() {
using some_int = gp::fixed_variant<int, unsigned int, long long>;
{
some_int a{16};
some_int b = 12u;
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;
new(&b) some_int(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_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;
new(&b) some_int(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_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);
vec.emplace_back(-16);
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;
}
};
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;
};
auto callback_handler = [&count](gp::parsing_state state, gp::allocator& alloc) {
log_segment("state remaining", std::to_string(state.size()).c_str());
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 decode value 0");
log_segment("value 0", std::to_string(value.value()).c_str());
gp_config::assertion(value.value() == 12, "could not decode 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 decode value 1");
log_segment("value 1", std::to_string(value.value()).c_str());
gp_config::assertion(value.value() == -98, "could not decode 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 2");
log_segment("value 2", std::to_string(value.value()).c_str());
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 3");
log_segment("value 3", std::to_string(value.value()).c_str());
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::vector<char> serialized(alloc);
gp::array<char, 1> serialized_manual{
char(1)
};
gp::push_as_cbor(serialized, 1);
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");
auto [value, new_state] = gp::read_cbor<int>(serialized.as_buffer(), alloc);
gp_config::assertion(value.has_value(), "could not redecode");
gp_config::assertion(value.value() == 1, "data did not serialize correctly: wrong value decoded");
}
return 0;
}
};
struct cbor_test9 : public generic_cbor_test {
cbor_test9() {
name = __FILE__ ":" "##9";
}
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)
};
gp::push_as_cbor(serialized, 1024);
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");
}
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");
}
return 0;
}
};
struct cbor_test10 : public generic_cbor_test {
cbor_test10() {
name = __FILE__ ":" "##10";
}
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)
};
gp::push_as_cbor(serialized, 0xAABBCCDD);
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");
}
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");
}
return 0;
}
};
struct cbor_test11 : public generic_cbor_test {
cbor_test11() {
name = __FILE__ ":" "##11";
}
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)
};
gp::push_as_cbor(serialized, 0xAABBCCDDEEFF0011ull);
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");
}
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");
}
return 0;
}
};
struct cbor_test12 : public generic_cbor_test {
cbor_test12() {
name = __FILE__ ":" "##12";
}
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)
};
gp::push_as_cbor(serialized, nullptr);
gp_config::assertion(serialized.size() == serialized_manual.size(), "could not encode");
gp_config::assertion(serialized[0] == serialized_manual[0], "data did not serialize correctly");
auto [value, state] = gp::read_cbor<std::nullptr_t>(serialized.as_buffer(), alloc);
gp_config::assertion(value.has_value(), "could not decode");
gp_config::assertion(value.value() == nullptr, "data did not decode correctly");
}
return 0;
}
};
struct cbor_test13 : public generic_cbor_test {
cbor_test13() {
name = __FILE__ ":" "##13";
}
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::push_as_cbor(serialized, true);
gp_config::assertion(serialized.size() == serialized_manual.size(), "could not encode");
gp_config::assertion(serialized[0] == serialized_manual[0], "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");
}
return 0;
}
};
struct cbor_test14 : public generic_cbor_test {
cbor_test14() {
name = __FILE__ ":" "##14";
}
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::push_as_cbor(serialized, false);
gp_config::assertion(serialized.size() == serialized_manual.size(), "could not encode");
gp_config::assertion(serialized[0] == serialized_manual[0], "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");
}
return 0;
}
};
struct cbor_test15 : public generic_cbor_test {
cbor_test15() {
name = __FILE__ ":" "##15";
}
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+23)
};
gp::push_as_cbor(serialized, gp::cbor_undefined{});
gp_config::assertion(serialized.size() == serialized_manual.size(), "could not encode");
log_segment("value", std::to_string((uint8_t)serialized[0]).c_str());
gp_config::assertion(serialized[0] == serialized_manual[0], "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::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, 6> serialized_manual{
char(0b01000101),
char('h'),
char('e'),
char('l'),
char('l'),
char('o')
};
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");
}
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");
}
return 0;
}
};
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')
};
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");
}
}
return 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{});
/*
TODO: REWRITE THOSE BAD BOIS
{
gp::cbor_value data{alloc};
data = gp::cbor_floating_point(128.5f);
gp::array<std::byte, 5> serialized;
gp::array<std::byte, 5> serialized_manual{
std::byte(0b11111010),
std::byte(0b01000011),
std::byte(0b00000000),
std::byte(0b10000000),
std::byte(0b00000000)
};
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((double)128.5);
gp::array<std::byte, 9> serialized;
gp::array<std::byte, 9> serialized_manual{
std::byte(0b11111011),
std::byte(0b01000000),
std::byte(0b01100000),
std::byte(0b00010000),
std::byte(0b00000000),
std::byte(0b00000000),
std::byte(0b00000000),
std::byte(0b00000000),
std::byte(0b00000000)
};
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);
for(auto a : {'h', 'e', 'l', 'l', 'o'})
str.push_back((std::byte)a);
gp::cbor_value data{alloc};
data = str;
gp::vector<gp::cbor_value> meta{alloc};
gp::repeat(5, [&](){
meta.push_back(data);
});
data = meta;
gp::array<std::byte, 31> serialized;
gp::array<std::byte, 31> serialized_manual{
std::byte(0b10000101),
std::byte(0b01000101),
std::byte('h'),
std::byte('e'),
std::byte('l'),
std::byte('l'),
std::byte('o'),
std::byte(0b01000101),
std::byte('h'),
std::byte('e'),
std::byte('l'),
std::byte('l'),
std::byte('o'),
std::byte(0b01000101),
std::byte('h'),
std::byte('e'),
std::byte('l'),
std::byte('l'),
std::byte('o'),
std::byte(0b01000101),
std::byte('h'),
std::byte('e'),
std::byte('l'),
std::byte('l'),
std::byte('o'),
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);
for(auto a : {'h', 'e', 'l', 'l', 'o'})
str.push_back((std::byte)a);
gp::cbor_value data{alloc};
data = str;
gp::vector<gp::pair<gp::cbor_value, gp::cbor_value>> meta{alloc};
gp::repeat(2, [&](){
meta.push_back(gp::make_pair(data, data));
});
data = meta;
gp::array<std::byte, 25> serialized;
gp::array<std::byte, 25> serialized_manual{
std::byte(0b10100010),
std::byte(0b01000101),
std::byte('h'),
std::byte('e'),
std::byte('l'),
std::byte('l'),
std::byte('o'),
std::byte(0b01000101),
std::byte('h'),
std::byte('e'),
std::byte('l'),
std::byte('l'),
std::byte('o'),
std::byte(0b01000101),
std::byte('h'),
std::byte('e'),
std::byte('l'),
std::byte('l'),
std::byte('o'),
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");
}
*/