Commit 0ed9bbe2 authored by Jan Koniarik's avatar Jan Koniarik
Browse files

added serialization of protocol error types

parent b50a52c2
Pipeline #99736 failed with stage
in 55 seconds
#include "emlabcpp/protocol/base.h"
#include "emlabcpp/protocol/error.h"
#include "emlabcpp/protocol/message.h"
#include "emlabcpp/quantity.h"
#include "emlabcpp/types.h"
......@@ -140,4 +141,19 @@ struct protocol_decl< D > : protocol_decl< typename D::def_type >
{
};
template <>
struct protocol_decl< protocol_mark >
{
using value_type = protocol_mark;
static constexpr std::size_t max_size = protocol_mark{}.max_size();
};
template <>
struct protocol_decl< protocol_error_record >
{
using value_type = protocol_error_record;
static constexpr std::size_t max_size = 18;
};
} // namespace emlabcpp
......@@ -69,7 +69,7 @@ struct protocol_def< D, Endianess >
}
static constexpr auto deserialize( const view< const uint8_t* >& buffer )
-> either< protocol_result< size_type, value_type >, protocol_error_record >
-> either< protocol_result< size_type, value_type >, protocol_error_record >
{
if ( buffer.size() < max_size ) {
return protocol_error_record{ PROTOCOL_NS, LOWSIZE_ERR, 0 };
......@@ -602,10 +602,12 @@ struct protocol_def< protocol_group< Ds... >, Endianess >
return *opt_res;
}
static constexpr auto deserialize( const view< const uint8_t* >& buffer )
-> either< protocol_result< size_type, value_type >, protocol_error_record >
using return_either =
either< protocol_result< size_type, value_type >, protocol_error_record >;
static constexpr auto deserialize( const view< const uint8_t* >& buffer ) -> return_either
{
std::optional< protocol_result< size_type, value_type > > opt_res;
std::optional< return_either > opt_res;
until_index< sizeof...( Ds ) >( [&]< std::size_t i >() {
using sub_def =
......@@ -613,10 +615,16 @@ struct protocol_def< protocol_group< Ds... >, Endianess >
sub_def::deserialize( buffer ).match(
[&]( auto sub_res ) {
opt_res = protocol_result< size_type, value_type >{
sub_res.used, value_type{ sub_res.val } };
opt_res =
return_either{ protocol_result< size_type, value_type >{
sub_res.used, value_type{ sub_res.val } } };
},
[&]( protocol_error_record ) {} );
[&]( protocol_error_record rec ) {
if ( rec.byte_index == 0 ) {
return;
}
opt_res = rec;
} );
return bool( opt_res );
} );
......@@ -639,4 +647,75 @@ struct protocol_def< D, Endianess > : protocol_def< typename D::def_type, Endian
{
};
template < protocol_endianess_enum Endianess >
struct protocol_def< protocol_mark, Endianess >
{
using value_type = typename protocol_decl< protocol_mark >::value_type;
static constexpr std::size_t max_size = protocol_decl< protocol_mark >::max_size;
using size_type = bounded< std::size_t, max_size, max_size >;
static constexpr size_type
serialize_at( std::span< uint8_t, max_size > buffer, value_type item )
{
std::copy( item.begin(), item.end(), buffer.begin() );
return size_type{};
}
static constexpr auto deserialize( const view< const uint8_t* >& buffer )
-> either< protocol_result< size_type, value_type >, protocol_error_record >
{
if ( buffer.size() < max_size ) {
return protocol_error_record{ PROTOCOL_NS, LOWSIZE_ERR, 0 };
}
value_type res{};
std::copy( buffer.begin(), buffer.begin() + max_size, res.begin() );
return protocol_result{ size_type{}, res };
}
};
template < protocol_endianess_enum Endianess >
struct protocol_def< protocol_error_record, Endianess >
{
using value_type = typename protocol_decl< protocol_error_record >::value_type;
static constexpr std::size_t max_size = protocol_decl< protocol_error_record >::max_size;
using size_type = bounded< std::size_t, max_size, max_size >;
using mark_def = protocol_def< protocol_mark, Endianess >;
using bi_def = protocol_def< uint16_t, Endianess >;
// TODO: figure out how to do this better
static constexpr size_type
serialize_at( std::span< uint8_t, max_size > buffer, value_type item )
{
mark_def::serialize_at( buffer.subspan< 0, 8 >(), item.ns );
mark_def::serialize_at( buffer.subspan< 8, 8 >(), item.err );
bi_def::serialize_at( buffer.subspan< 16, 2 >(), item.byte_index );
return size_type{};
}
static constexpr auto deserialize( const view< const uint8_t* >& buffer )
-> either< protocol_result< size_type, value_type >, protocol_error_record >
{
if ( buffer.size() < max_size ) {
return protocol_error_record{ PROTOCOL_NS, LOWSIZE_ERR, 0 };
}
protocol_error_record res;
return mark_def::deserialize( view_n( buffer.begin(), 8 ) )
.bind_left( [&]( auto ns_res ) {
res.ns = ns_res.val;
return mark_def::deserialize( view_n( buffer.begin() + 8, 8 ) );
} )
.bind_left( [&]( auto err_res ) {
res.err = err_res.val;
return bi_def::deserialize( view_n( buffer.begin() + 16, 2 ) );
} )
.convert_left( [&]( auto bi_res ) {
res.byte_index = bi_res.val;
return protocol_result{ size_type{}, res };
} );
}
};
} // namespace emlabcpp
......@@ -13,13 +13,14 @@ namespace emlabcpp
struct protocol_mark : std::array< char, 8 >
{
using base_type = std::array< char, 8 >;
};
struct protocol_error_record
{
protocol_mark ns;
protocol_mark err;
std::size_t byte_index;
uint16_t byte_index;
friend constexpr bool
operator==( const protocol_error_record&, const protocol_error_record& ) = default;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment