Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Jan Koniarik
emlabcpp
Commits
4d512fcd
Commit
4d512fcd
authored
Oct 23, 2021
by
Jan Koniarik
Browse files
added example for protocol lib and generic include header
parent
0063541c
Pipeline
#100437
passed with stage
in 1 minute and 6 seconds
Changes
2
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
examples/protocol.cpp
0 → 100644
View file @
4d512fcd
#include "emlabcpp/protocol.h"
#include "emlabcpp/protocol/handler.h"
#include "emlabcpp/protocol/streams.h"
#include <iostream>
namespace
em
=
emlabcpp
;
int
main
(
int
,
char
*
[]
)
{
// ---------------------------------------------------------------------------------------
// protocol library allows serialization and deserialization of C++ native types into binary
// messages. The protocol is defined with types from the library and the library provides
// handler that does the conversion based on the definition. The definition is done using
// types and templates and is separated from the actuall serialization and deserialization.
//
// There are two top level types that shall be used: protocol_tuple and
// protocol_command_group. The user should use these as top level type and define the
// protocol in these. They can be nested.
//
// For the examples we define the protocol by definining structures that inherit from the
// protocol definition, this is not necessary and simple aliases to types can be used, these
// however produce lengthy error messages.
//
// For both types we also use syntax sugar in form of type alias members such as
// 'with_items' that make the definition more readable.
// ---------------------------------------------------------------------------------------
// The protocol tuple is defined by endianess of subsequent types and with items that are
// stored in the tuple. The protocol_tuple works with std::tuple as the type that actually
// holds the value. The example definition below defines protocol for converting
// `std::tuple<uint32_t, in16_t, int16_t>` into binary message `protocol_message<8>` of
// size 8.
//
// The structure contains ::value_type and ::message_type aliases.
struct
example_tuple
:
em
::
protocol_tuple
<
em
::
PROTOCOL_BIG_ENDIAN
>::
with_items
<
uint32_t
,
int16_t
,
int16_t
>
{
};
// Once protocol is defined, it can be used with protocol_handler to do the serialization
// and deserialization.
using
example_tuple_handler
=
em
::
protocol_handler
<
example_tuple
>
;
std
::
tuple
<
uint32_t
,
int16_t
,
int16_t
>
tuple_val
=
{
666
,
-
2
,
2
};
em
::
protocol_message
<
8
>
tuple_msg
=
example_tuple_handler
::
serialize
(
tuple_val
);
// The library has support for streams, these however are stored in separate included file
// and has to be enable by defining EMLABCPP_USE_STREAMS
std
::
cout
<<
"Message from example_tuple looks like: "
<<
tuple_msg
<<
"
\n
"
;
// Deserialization produces either the value on successfull serialization or
// protocol_error_record with information about what failed and on which byte. Note: the
// protocol_error_record is serializable by the library, so you can simply send it in
// report.
em
::
either
<
std
::
tuple
<
uint32_t
,
int16_t
,
int16_t
>
,
em
::
protocol_error_record
>
tuple_either
=
example_tuple_handler
::
extract
(
tuple_msg
);
tuple_either
.
match
(
[](
std
::
tuple
<
uint32_t
,
int16_t
,
int16_t
>
)
{
std
::
cout
<<
"Yaaay, protocol deserialized what it serialized
\\
o/
\n
"
;
},
[](
em
::
protocol_error_record
rec
)
{
std
::
cout
<<
"Hupsie, error happend in deserialization: "
<<
rec
<<
"
\n
"
;
}
);
// ---------------------------------------------------------------------------------------
// command_group models situation of "message contains one out of many commands", where
// command is just specific tuple of types. This produces std::variant of possible commands
// on deserialization and convert said variant to byte message. The first item of each
// command is constant (em::tag) with id of the command. The library decides which command
// is in the message solely based on this id. These however does not have to be ordered as
// seen in the example.
enum
protocol_id
:
uint16_t
{
EXAMPLE_CMD_A
=
1
,
EXAMPLE_CMD_B
=
42
,
EXAMPLE_CMD_C
=
66
,
};
struct
example_group
:
em
::
protocol_command_group
<
em
::
PROTOCOL_BIG_ENDIAN
>::
with_commands
<
em
::
protocol_command
<
EXAMPLE_CMD_A
>::
with_args
<
uint32_t
>
,
em
::
protocol_command
<
EXAMPLE_CMD_B
>
,
em
::
protocol_command
<
EXAMPLE_CMD_C
>::
with_args
<
std
::
array
<
uint32_t
,
4
>
,
std
::
tuple
<
uint8_t
,
uint8_t
,
em
::
bounded
<
int16_t
,
-
666
,
666
>
>
>
>
{
};
// This command group produces value defined below:
using
example_group_value
=
std
::
variant
<
std
::
tuple
<
em
::
tag
<
EXAMPLE_CMD_A
>
,
uint32_t
>
,
std
::
tuple
<
em
::
tag
<
EXAMPLE_CMD_B
>
>
,
std
::
tuple
<
em
::
tag
<
EXAMPLE_CMD_C
>
,
std
::
array
<
uint32_t
,
4
>
,
std
::
tuple
<
uint8_t
,
uint8_t
,
em
::
bounded
<
int16_t
,
-
666
,
666
>
>
>
>
;
// To simplify the process of handling the value, the command_group provides make_val static
// method for creating a value of said group, that can be processed.
example_group_value
group_val
=
example_group
::
make_val
<
EXAMPLE_CMD_A
>
(
42u
);
// serialization and deserialization works same way as in case of tuple
using
example_group_handler
=
em
::
protocol_handler
<
example_group
>
;
em
::
protocol_message
<
22
>
group_msg
=
example_group_handler
::
serialize
(
group_val
);
std
::
cout
<<
"Message from example group looks like: "
<<
group_msg
<<
"
\n
"
;
example_group_handler
::
extract
(
group_msg
)
.
match
(
[
&
](
example_group_value
)
{
std
::
cout
<<
"yayyy, group deserialize :)
\n
"
;
},
[
&
](
em
::
protocol_error_record
rec
)
{
std
::
cout
<<
"something went wrong with the group: "
<<
rec
<<
"
\n
"
;
}
);
}
include/emlabcpp/protocol.h
0 → 100644
View file @
4d512fcd
#include "emlabcpp/protocol/command_group.h"
#include "emlabcpp/protocol/decl.h"
#include "emlabcpp/protocol/tuple.h"
#pragma once
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment