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
95f22c6e
Commit
95f22c6e
authored
Oct 18, 2021
by
Jan Koniarik
Browse files
refactored internals of rptocool lib for speed improvements
parent
97242970
Pipeline
#100034
failed with stage
in 1 minute and 1 second
Changes
9
Pipelines
1
Expand all
Hide whitespace changes
Inline
Side-by-side
include/emlabcpp/protocol/base.h
View file @
95f22c6e
...
...
@@ -13,15 +13,29 @@ namespace emlabcpp
// Strucutre used as result of deserialization in the internal mechanisms of protocol handling.
// Contains parsed value and bounded value of how much bytes were used.
template
<
bounded_derived
size_type
,
typename
T
>
template
<
typename
T
>
struct
protocol_result
{
size_type
used
;
T
val
;
};
std
::
size_t
used
=
0
;
std
::
variant
<
T
,
const
protocol_mark
*
>
res
;
template
<
bounded_derived
size_type
,
typename
T
>
protocol_result
(
size_type
,
T
)
->
protocol_result
<
size_type
,
T
>
;
protocol_result
()
=
default
;
protocol_result
(
std
::
size_t
u
,
std
::
variant
<
T
,
const
protocol_mark
*
>
v
)
:
used
(
u
)
,
res
(
v
)
{
}
protocol_result
(
std
::
size_t
u
,
T
v
)
:
used
(
u
)
,
res
(
v
)
{
}
protocol_result
(
std
::
size_t
u
,
const
protocol_mark
*
m
)
:
used
(
u
)
,
res
(
m
)
{
}
};
// Concept that matches types considered base - serialized directly by using byte shifting.
template
<
typename
T
>
...
...
include/emlabcpp/protocol/decl.h
View file @
95f22c6e
...
...
@@ -152,8 +152,8 @@ template <>
struct
protocol_decl
<
protocol_error_record
>
{
using
value_type
=
protocol_error_record
;
static
constexpr
std
::
size_t
max_size
=
18
;
static
constexpr
std
::
size_t
max_size
=
protocol_decl
<
protocol_mark
>::
max_size
+
protocol_decl
<
std
::
size_t
>::
max_size
;
};
}
// namespace emlabcpp
include/emlabcpp/protocol/def.h
View file @
95f22c6e
This diff is collapsed.
Click to expand it.
include/emlabcpp/protocol/error.h
View file @
95f22c6e
...
...
@@ -18,14 +18,8 @@ struct protocol_mark : std::array< char, 16 >
struct
protocol_error_record
{
const
protocol_mark
*
err
;
uint16_t
byte_index
;
friend
constexpr
bool
operator
==
(
const
protocol_error_record
&
lh
,
const
protocol_error_record
&
rh
)
{
return
lh
.
byte_index
==
rh
.
byte_index
&&
lh
.
err
==
rh
.
err
;
}
protocol_mark
mark
;
std
::
size_t
offset
;
};
// Creates protocol_mark from simple string literal.
...
...
@@ -37,6 +31,7 @@ inline constexpr protocol_mark make_protocol_mark( const char ( &msg )[17] )
return
res
;
}
static
constexpr
auto
SIZE_ERR
=
make_protocol_mark
(
"EMLABCPPSIZE "
);
// not enough bytes left in the message for the item
static
constexpr
auto
LOWSIZE_ERR
=
make_protocol_mark
(
"EMLABCPPLOWSIZE "
);
// too much bytes left in the message for the item
...
...
include/emlabcpp/protocol/handler.h
View file @
95f22c6e
...
...
@@ -13,24 +13,31 @@ namespace emlabcpp
template
<
typename
T
>
struct
protocol_handler
{
using
de
cl
=
protocol_def
<
T
,
PROTOCOL_BIG_ENDIAN
>
;
using
value_type
=
typename
de
cl
::
value_type
;
using
message_type
=
protocol_message
<
de
cl
::
max_size
>
;
using
de
f
=
protocol_def
<
T
,
PROTOCOL_BIG_ENDIAN
>
;
using
value_type
=
typename
de
f
::
value_type
;
using
message_type
=
protocol_message
<
de
f
::
max_size
>
;
static
message_type
serialize
(
value_type
val
)
{
std
::
array
<
uint8_t
,
de
cl
::
max_size
>
buffer
{};
std
::
array
<
uint8_t
,
de
f
::
max_size
>
buffer
{};
bounded
used
=
de
cl
::
serialize_at
(
buffer
,
val
);
EMLABCPP_ASSERT
(
*
used
<=
de
cl
::
max_size
);
bounded
used
=
de
f
::
serialize_at
(
buffer
,
val
);
EMLABCPP_ASSERT
(
*
used
<=
de
f
::
max_size
);
return
*
message_type
::
make
(
view_n
(
buffer
.
begin
(),
*
used
)
);
};
static
either
<
value_type
,
protocol_error_record
>
extract
(
const
message_type
&
msg
)
{
return
decl
::
deserialize
(
msg
).
convert_left
(
[
&
](
auto
sub_res
)
{
return
sub_res
.
val
;
}
);
auto
opt_view
=
bounded_view
<
const
uint8_t
*
,
typename
def
::
size_type
>::
make
(
view_n
(
msg
.
begin
(),
min
(
def
::
max_size
,
msg
.
size
()
)
)
);
if
(
!
opt_view
)
{
return
protocol_error_record
{
SIZE_ERR
,
0
};
}
auto
[
used
,
res
]
=
def
::
deserialize
(
*
opt_view
);
if
(
std
::
holds_alternative
<
const
protocol_mark
*
>
(
res
)
)
{
return
protocol_error_record
{
*
std
::
get
<
1
>
(
res
),
used
};
}
return
std
::
get
<
0
>
(
res
);
}
};
...
...
include/emlabcpp/protocol/register_handler.h
View file @
95f22c6e
...
...
@@ -49,9 +49,16 @@ struct protocol_register_handler
using
def
=
protocol_def
<
typename
map_type
::
reg_def_type
<
Key
>
,
PROTOCOL_BIG_ENDIAN
>
;
return
def
::
deserialize
(
msg
).
convert_left
(
[
&
](
auto
sub_res
)
{
return
sub_res
.
val
;
}
);
auto
opt_view
=
bounded_view
<
const
uint8_t
*
,
typename
def
::
size_type
>::
make
(
view_n
(
msg
.
begin
(),
min
(
def
::
max_size
,
msg
.
size
()
)
)
);
if
(
!
opt_view
)
{
return
protocol_error_record
{
SIZE_ERR
,
0
};
}
auto
[
used
,
res
]
=
def
::
deserialize
(
*
opt_view
);
if
(
std
::
holds_alternative
<
const
protocol_mark
*
>
(
res
)
)
{
return
protocol_error_record
{
*
std
::
get
<
1
>
(
res
),
used
};
}
return
std
::
get
<
0
>
(
res
);
}
template
<
typename
Buffer
>
...
...
include/emlabcpp/protocol/streams.h
View file @
95f22c6e
...
...
@@ -36,7 +36,7 @@ inline std::ostream& operator<<( std::ostream& os, const protocol_mark& m )
inline
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
protocol_error_record
&
rec
)
{
return
os
<<
rec
.
err
<<
"
("
<<
rec
.
byte_index
<<
")"
;
return
os
<<
rec
.
mark
<<
"("
<<
rec
.
offset
<<
")"
;
}
inline
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
protocol_endianess_enum
&
val
)
...
...
tests/protocol_def_test.cpp
View file @
95f22c6e
...
...
@@ -29,25 +29,26 @@ struct valid_test_case : protocol_test_fixture
std
::
array
<
uint8_t
,
pitem
::
max_size
>
buffer
{};
std
::
span
bspan
{
buffer
};
std
::
size_t
used
=
*
pitem
::
serialize_at
(
bspan
.
template
first
<
pitem
::
max_size
>(),
val
);
bounded
used
=
pitem
::
serialize_at
(
bspan
.
template
first
<
pitem
::
max_size
>(),
val
);
EXPECT_EQ
(
used
,
expected_buffer
.
size
()
);
auto
serialized
=
convert_view_n
<
int
>
(
buffer
.
begin
(),
used
);
EXPECT_EQ
(
*
used
,
expected_buffer
.
size
()
);
auto
serialized
=
convert_view_n
<
int
>
(
buffer
.
begin
(),
*
used
);
EXPECT_EQ
(
serialized
,
view
{
expected_buffer
}
)
<<
std
::
hex
//
<<
"serialized : "
<<
serialized
<<
"
\n
"
<<
"expected : "
<<
convert_view
<
int
>
(
expected_buffer
)
<<
"
\n
"
;
pitem
::
deserialize
(
view_n
(
buffer
.
begin
(),
used
)
)
.
match
(
[
&
](
auto
res
)
{
EXPECT_EQ
(
*
res
.
used
,
expected_buffer
.
size
()
);
EXPECT_EQ
(
res
.
val
,
val
);
},
[
&
](
protocol_error_record
)
{
FAIL
();
}
);
auto
[
pused
,
res
]
=
pitem
::
deserialize
(
*
bounded_view
<
const
uint8_t
*
,
typename
pitem
::
size_type
>::
make
(
view_n
(
buffer
.
begin
(),
*
used
)
)
);
EXPECT_EQ
(
pused
,
expected_buffer
.
size
()
);
if
(
std
::
holds_alternative
<
const
protocol_mark
*
>
(
res
)
)
{
FAIL
()
<<
std
::
get
<
1
>
(
res
);
}
else
{
auto
rval
=
std
::
get
<
0
>
(
res
);
EXPECT_EQ
(
rval
,
val
);
}
}
void
generate_name
(
std
::
ostream
&
os
)
const
final
...
...
@@ -98,14 +99,17 @@ struct invalid_test_case : protocol_test_fixture
ASSERT_LE
(
inpt
.
size
(),
tmp
.
size
()
);
std
::
copy
(
inpt
.
begin
(),
inpt
.
end
(),
tmp
.
begin
()
);
pitem
::
deserialize
(
view_n
(
tmp
.
begin
(),
inpt
.
size
()
)
)
.
match
(
[
&
](
auto
)
{
FAIL
();
},
[
&
](
protocol_error_record
rec
)
{
EXPECT_EQ
(
rec
,
expected_rec
);
}
);
auto
opt_view
=
bounded_view
<
const
uint8_t
*
,
typename
pitem
::
size_type
>::
make
(
view_n
(
tmp
.
begin
(),
inpt
.
size
()
)
);
EXPECT_TRUE
(
opt_view
);
auto
[
used
,
res
]
=
pitem
::
deserialize
(
*
opt_view
);
if
(
std
::
holds_alternative
<
const
protocol_mark
*
>
(
res
)
)
{
EXPECT_EQ
(
expected_rec
.
mark
,
*
std
::
get
<
1
>
(
res
)
);
EXPECT_EQ
(
expected_rec
.
offset
,
used
);
}
else
{
FAIL
()
<<
"deserialization passed"
;
}
}
void
generate_name
(
std
::
ostream
&
os
)
const
final
...
...
@@ -138,29 +142,16 @@ int main( int argc, char** argv )
make_valid_test_case
<
PROTOCOL_LITTLE_ENDIAN
>
(
uint16_t
{
666
},
{
154
,
2
}
),
make_valid_test_case
<
PROTOCOL_BIG_ENDIAN
>
(
uint16_t
{
666
},
{
2
,
154
}
),
make_valid_test_case
<
PROTOCOL_LITTLE_ENDIAN
>
(
int32_t
{
-
1
},
{
255
,
255
,
255
,
255
}
),
make_invalid_test_case
<
int16_t
>
(
{
255
},
protocol_error_record
{
&
LOWSIZE_ERR
,
0
}
),
make_invalid_test_case
<
uint32_t
>
(
{
255
,
255
,
255
},
protocol_error_record
{
&
LOWSIZE_ERR
,
0
}
),
// std::array
make_valid_test_case
<
PROTOCOL_LITTLE_ENDIAN
>
(
std
::
array
<
int16_t
,
3
>
{
-
1
,
1
,
666
},
{
255
,
255
,
1
,
0
,
154
,
2
}
),
make_valid_test_case
<
PROTOCOL_BIG_ENDIAN
>
(
std
::
array
<
int16_t
,
3
>
{
-
1
,
1
,
666
},
{
255
,
255
,
0
,
1
,
2
,
154
}
),
make_invalid_test_case
<
std
::
array
<
uint32_t
,
2
>
>
(
{
12
,
12
,
12
},
protocol_error_record
{
&
LOWSIZE_ERR
,
0
}
),
make_invalid_test_case
<
std
::
array
<
uint32_t
,
2
>
>
(
{
12
,
12
,
12
,
12
},
protocol_error_record
{
&
LOWSIZE_ERR
,
4
}
),
make_invalid_test_case
<
std
::
array
<
uint32_t
,
2
>
>
(
{
12
,
12
,
12
,
12
,
12
,
12
},
protocol_error_record
{
&
LOWSIZE_ERR
,
4
}
),
// std::tuple
make_valid_test_case
<
PROTOCOL_LITTLE_ENDIAN
>
(
std
::
tuple
<
uint8_t
,
int16_t
,
int8_t
>
{
1u
,
666u
,
-
3u
},
{
1
,
154
,
2
,
253
}
),
make_valid_test_case
<
PROTOCOL_BIG_ENDIAN
>
(
std
::
tuple
<
uint8_t
,
int16_t
,
int8_t
>
{
1u
,
666u
,
-
3u
},
{
1
,
2
,
154
,
253
}
),
make_invalid_test_case
<
std
::
tuple
<
uint32_t
>
>
(
{
0
,
0
,
12
},
protocol_error_record
{
&
LOWSIZE_ERR
,
0
}
),
make_invalid_test_case
<
std
::
tuple
<
int8_t
,
uint16_t
,
int8_t
,
int8_t
>
>
(
{
0
,
0
,
12
,
0
},
protocol_error_record
{
&
LOWSIZE_ERR
,
4
}
),
// std::variant
make_valid_test_case
<
PROTOCOL_LITTLE_ENDIAN
>
(
std
::
variant
<
uint8_t
,
int16_t
,
uint16_t
>
{
int16_t
{
-
3
}
},
{
1
,
253
,
255
}
),
...
...
@@ -169,11 +160,9 @@ int main( int argc, char** argv )
make_valid_test_case
<
PROTOCOL_LITTLE_ENDIAN
>
(
std
::
variant
<
uint8_t
,
int16_t
,
uint16_t
>
{
uint8_t
{
42
}
},
{
0
,
42
}
),
make_invalid_test_case
<
std
::
variant
<
uint8_t
,
int16_t
,
uint16_t
>
>
(
{
3
,
0
,
0
},
protocol_error_record
{
&
UNDEFVAR_ERR
,
0
}
),
{
3
,
0
,
0
},
protocol_error_record
{
UNDEFVAR_ERR
,
0
}
),
make_invalid_test_case
<
std
::
variant
<
uint8_t
,
int16_t
,
uint16_t
>
>
(
{
0
},
protocol_error_record
{
&
LOWSIZE_ERR
,
1
}
),
make_invalid_test_case
<
std
::
variant
<
uint8_t
,
int16_t
,
uint16_t
>
>
(
{
1
,
0
},
protocol_error_record
{
&
LOWSIZE_ERR
,
1
}
),
{
1
,
0
},
protocol_error_record
{
SIZE_ERR
,
0
}
),
// std::bitset
make_valid_test_case
<
PROTOCOL_LITTLE_ENDIAN
>
(
std
::
bitset
<
3
>
{
0b00000111
},
{
0b00000111
}
),
...
...
@@ -185,10 +174,6 @@ int main( int argc, char** argv )
std
::
bitset
<
15
>
{
0xFF55
},
{
0x55
,
0b01111111
}
),
make_valid_test_case
<
PROTOCOL_LITTLE_ENDIAN
>
(
std
::
bitset
<
16
>
{
0xFFFF
},
{
0xFF
,
0xFF
}
),
make_invalid_test_case
<
std
::
bitset
<
7
>
>
(
{},
protocol_error_record
{
&
LOWSIZE_ERR
,
0
}
),
make_invalid_test_case
<
std
::
bitset
<
9
>
>
(
{
0x0
},
protocol_error_record
{
&
LOWSIZE_ERR
,
0
}
),
// protocol_sizeless_message
make_valid_test_case
<
PROTOCOL_LITTLE_ENDIAN
>
(
*
protocol_sizeless_message
<
8
>::
make
(
std
::
vector
{
1
,
2
,
3
,
4
,
5
}
),
...
...
@@ -196,8 +181,6 @@ int main( int argc, char** argv )
make_valid_test_case
<
PROTOCOL_BIG_ENDIAN
>
(
*
protocol_sizeless_message
<
8
>::
make
(
std
::
vector
{
1
,
2
,
3
,
4
,
5
}
),
{
1
,
2
,
3
,
4
,
5
}
),
make_invalid_test_case
<
protocol_sizeless_message
<
4
>
>
(
{
0
,
0
,
0
,
0
,
0
},
protocol_error_record
{
&
BIGSIZE_ERR
,
0
}
),
// protocol_offset
make_specific_valid_test_case
<
PROTOCOL_LITTLE_ENDIAN
,
protocol_offset
<
uint16_t
,
0
>
>
(
666u
,
{
154
,
2
}
),
...
...
@@ -207,15 +190,11 @@ int main( int argc, char** argv )
666u
,
{
158
,
2
}
),
make_specific_valid_test_case
<
PROTOCOL_BIG_ENDIAN
,
protocol_offset
<
uint16_t
,
4
>
>
(
666u
,
{
2
,
158
}
),
make_invalid_test_case
<
protocol_offset
<
uint16_t
,
4
>
>
(
{
255
},
protocol_error_record
{
&
LOWSIZE_ERR
,
0
}
),
// quantity
make_valid_test_case
<
PROTOCOL_LITTLE_ENDIAN
>
(
tagged_quantity
<
struct
offtag
,
uint16_t
>
{
666u
},
{
154
,
2
}
),
make_valid_test_case
<
PROTOCOL_BIG_ENDIAN
>
(
tagged_quantity
<
struct
offtag
,
uint16_t
>
{
666u
},
{
2
,
154
}
),
make_invalid_test_case
<
tagged_quantity
<
struct
offtag
,
uint16_t
>
>
(
{
255
},
protocol_error_record
{
&
LOWSIZE_ERR
,
0
}
),
// bounded
make_valid_test_case
<
PROTOCOL_LITTLE_ENDIAN
>
(
bounded
<
uint16_t
,
0
,
1024u
>::
get
<
666u
>
(),
{
154
,
2
}
),
...
...
@@ -224,9 +203,7 @@ int main( int argc, char** argv )
make_valid_test_case
<
PROTOCOL_BIG_ENDIAN
>
(
bounded
<
int16_t
,
-
1
,
1
>::
get
<
-
1
>
(),
{
255
,
255
}
),
make_invalid_test_case
<
bounded
<
int16_t
,
-
1
,
1
>
>
(
{
128
},
protocol_error_record
{
&
LOWSIZE_ERR
,
0
}
),
make_invalid_test_case
<
bounded
<
int16_t
,
-
1
,
1
>
>
(
{
0
,
128
},
protocol_error_record
{
&
BOUNDS_ERR
,
0
}
),
{
0
,
128
},
protocol_error_record
{
BOUNDS_ERR
,
0
}
),
// sized_buffer
make_specific_valid_test_case
<
PROTOCOL_LITTLE_ENDIAN
,
...
...
@@ -249,14 +226,12 @@ int main( int argc, char** argv )
protocol_sized_buffer
<
protocol_offset
<
uint16_t
,
2
>
,
uint16_t
>
>
(
666u
,
{
0
,
4
,
2
,
154
}
),
make_invalid_test_case
<
protocol_sized_buffer
<
uint16_t
,
uint16_t
>
>
(
{
0
,
2
,
2
},
protocol_error_record
{
&
LOWSIZE_ERR
,
0
}
),
make_invalid_test_case
<
protocol_sized_buffer
<
uint16_t
,
uint16_t
>
>
(
{
0
,
1
,
2
,
2
},
protocol_error_record
{
&
LOWSIZE_ERR
,
2
}
),
{
0
,
1
,
2
,
2
},
protocol_error_record
{
SIZE_ERR
,
2
}
),
// tag
make_valid_test_case
<
PROTOCOL_LITTLE_ENDIAN
>
(
tag
<
666u
>
{},
{
154
,
2
,
0
,
0
}
),
make_valid_test_case
<
PROTOCOL_BIG_ENDIAN
>
(
tag
<
666u
>
{},
{
0
,
0
,
2
,
154
}
),
make_invalid_test_case
<
tag
<
666u
>
>
(
{
0
,
0
,
2
,
152
},
protocol_error_record
{
&
BADVAL_ERR
,
0
}
),
{
0
,
0
,
2
,
152
},
protocol_error_record
{
BADVAL_ERR
,
0
}
),
// group is tested as part of command group
// endianess change
make_specific_valid_test_case
<
...
...
tests/protocol_sophisticated_test.cpp
View file @
95f22c6e
#include "emlabcpp/iterators/convert.h"
#include "emlabcpp/protocol/command_group.h"
#include "emlabcpp/protocol/handler.h"
#include "emlabcpp/protocol/streams.h"
#include "emlabcpp/protocol/tuple.h"
#include "util.h"
...
...
@@ -86,8 +87,8 @@ struct valid_test_case : protocol_test_fixture
[
&
](
auto
var
)
{
EXPECT_EQ
(
var
,
val
);
},
[
&
](
auto
)
{
FAIL
();
[
&
](
auto
rec
)
{
FAIL
()
<<
rec
;
}
);
}
...
...
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