Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
Actor Framework
Commits
73bd12e6
Commit
73bd12e6
authored
Feb 28, 2020
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add parse function for node_id
parent
ab7b9114
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
146 additions
and
4 deletions
+146
-4
libcaf_core/CMakeLists.txt
libcaf_core/CMakeLists.txt
+1
-0
libcaf_core/caf/node_id.hpp
libcaf_core/caf/node_id.hpp
+10
-2
libcaf_core/caf/parser_state.hpp
libcaf_core/caf/parser_state.hpp
+32
-0
libcaf_core/src/node_id.cpp
libcaf_core/src/node_id.cpp
+50
-2
libcaf_core/test/node_id.cpp
libcaf_core/test/node_id.cpp
+53
-0
No files found.
libcaf_core/CMakeLists.txt
View file @
73bd12e6
...
...
@@ -249,6 +249,7 @@ set(CAF_CORE_TEST_SOURCES
test/mixin/sender.cpp
test/mock_streaming_classes.cpp
test/native_streaming_classes.cpp
test/node_id.cpp
test/optional.cpp
test/or_else.cpp
test/pipeline_streaming.cpp
...
...
libcaf_core/caf/node_id.hpp
View file @
73bd12e6
...
...
@@ -103,6 +103,8 @@ public:
static
bool
valid
(
const
host_id_type
&
x
)
noexcept
;
static
bool
can_parse
(
string_view
str
)
noexcept
;
// -- interface implementation ---------------------------------------------
bool
valid
()
const
noexcept
override
;
...
...
@@ -230,6 +232,9 @@ public:
/// @endcond
/// Returns whether `parse` would produce a valid node ID.
static
bool
can_parse
(
string_view
str
)
noexcept
;
/// @relates node_id
friend
CAF_CORE_EXPORT
error
inspect
(
serializer
&
sink
,
node_id
&
x
);
...
...
@@ -327,8 +332,11 @@ CAF_CORE_EXPORT node_id make_node_id(
/// @param process_id System-wide unique process identifier.
/// @param host_hash Unique node ID as hexadecimal string representation.
/// @relates node_id
CAF_CORE_EXPORT
optional
<
node_id
>
make_node_id
(
uint32_t
process_id
,
const
std
::
string
&
host_hash
);
CAF_CORE_EXPORT
optional
<
node_id
>
make_node_id
(
uint32_t
process_id
,
string_view
host_hash
);
/// @relates node_id
CAF_CORE_EXPORT
error
parse
(
string_view
str
,
node_id
&
dest
);
}
// namespace caf
...
...
libcaf_core/caf/parser_state.hpp
View file @
73bd12e6
...
...
@@ -100,6 +100,38 @@ struct parser_state {
}
return
false
;
}
/// Consumes the next character if it satisfies given predicate (skips any
/// whitespaces).
template
<
class
Predicate
>
bool
consume_if
(
Predicate
predicate
)
noexcept
{
skip_whitespaces
();
if
(
predicate
(
current
()))
{
next
();
return
true
;
}
return
false
;
}
/// Tries to read `x` as the next character, not allowing any whitespaces.
bool
consume_strict
(
char
x
)
noexcept
{
if
(
current
()
==
x
)
{
next
();
return
true
;
}
return
false
;
}
/// Consumes the next character if it satisfies given predicate, not allowing
/// any whitespaces.
template
<
class
Predicate
>
bool
consume_strict_if
(
Predicate
predicate
)
noexcept
{
if
(
predicate
(
current
()))
{
next
();
return
true
;
}
return
false
;
}
};
/// Returns an error object from the current code in `ps` as well as its
...
...
libcaf_core/src/node_id.cpp
View file @
73bd12e6
...
...
@@ -20,6 +20,7 @@
#include <cstdio>
#include <cstring>
#include <ctype.h>
#include <iterator>
#include <random>
#include <sstream>
...
...
@@ -31,10 +32,13 @@
#include "caf/detail/get_mac_addresses.hpp"
#include "caf/detail/get_process_id.hpp"
#include "caf/detail/get_root_uuid.hpp"
#include "caf/detail/parse.hpp"
#include "caf/detail/parser/ascii_to_int.hpp"
#include "caf/detail/ripemd_160.hpp"
#include "caf/expected.hpp"
#include "caf/logger.hpp"
#include "caf/make_counted.hpp"
#include "caf/parser_state.hpp"
#include "caf/sec.hpp"
#include "caf/serializer.hpp"
#include "caf/string_algorithms.hpp"
...
...
@@ -93,6 +97,24 @@ bool node_id::default_data::valid(const host_id_type& x) noexcept {
return
!
std
::
all_of
(
x
.
begin
(),
x
.
end
(),
is_zero
);
}
bool
node_id
::
default_data
::
can_parse
(
string_view
str
)
noexcept
{
// Our format is "<20-byte-hex>#<pid>". With 2 characters per byte, this means
// a valid node ID has at least 42 characters.
if
(
str
.
size
()
<
42
)
return
false
;
string_parser_state
ps
{
str
.
begin
(),
str
.
end
()};
for
(
size_t
i
=
0
;
i
<
40
;
++
i
)
if
(
!
ps
.
consume_strict_if
(
isxdigit
))
return
false
;
if
(
!
ps
.
consume_strict
(
'#'
))
return
false
;
// We don't care for the value, but we invoke the actual number parser to make
// sure the value is in bounds.
uint32_t
dummy
;
detail
::
parse
(
ps
,
dummy
);
return
ps
.
code
==
pec
::
success
;
}
bool
node_id
::
default_data
::
valid
()
const
noexcept
{
return
pid_
!=
0
&&
valid
(
host_
);
}
...
...
@@ -228,6 +250,10 @@ void node_id::swap(node_id& x) {
data_
.
swap
(
x
.
data_
);
}
bool
node_id
::
can_parse
(
string_view
str
)
noexcept
{
return
default_data
::
can_parse
(
str
)
||
uri
::
can_parse
(
str
);
}
namespace
{
template
<
class
Serializer
>
...
...
@@ -307,8 +333,7 @@ node_id make_node_id(uint32_t process_id,
return
node_id
{
std
::
move
(
ptr
)};
}
optional
<
node_id
>
make_node_id
(
uint32_t
process_id
,
const
std
::
string
&
host_hash
)
{
optional
<
node_id
>
make_node_id
(
uint32_t
process_id
,
string_view
host_hash
)
{
using
node_data
=
node_id
::
default_data
;
if
(
host_hash
.
size
()
!=
node_data
::
host_id_size
*
2
)
return
none
;
...
...
@@ -328,4 +353,27 @@ optional<node_id> make_node_id(uint32_t process_id,
return
make_node_id
(
process_id
,
host_id
);
}
error
parse
(
string_view
str
,
node_id
&
dest
)
{
if
(
node_id
::
default_data
::
can_parse
(
str
))
{
CAF_ASSERT
(
str
.
size
()
>=
42
);
auto
host_hash
=
str
.
substr
(
0
,
40
);
auto
pid_str
=
str
.
substr
(
41
);
uint32_t
pid_val
=
0
;
if
(
auto
err
=
detail
::
parse
(
pid_str
,
pid_val
))
return
err
;
if
(
auto
nid
=
make_node_id
(
pid_val
,
host_hash
))
{
dest
=
std
::
move
(
*
nid
);
return
none
;
}
CAF_LOG_ERROR
(
"make_node_id failed after can_parse returned true"
);
return
sec
::
invalid_argument
;
}
if
(
auto
nid_uri
=
make_uri
(
str
))
{
dest
=
make_node_id
(
std
::
move
(
*
nid_uri
));
return
none
;
}
else
{
return
std
::
move
(
nid_uri
.
error
());
}
}
}
// namespace caf
libcaf_core/test/node_id.cpp
0 → 100644
View file @
73bd12e6
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2020 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#define CAF_SUITE node_id
#include "caf/node_id.hpp"
#include "caf/test/dsl.hpp"
using
namespace
caf
;
#define CHECK_PARSE_OK(str, ...) \
do { \
CAF_CHECK(node_id::can_parse(str)); \
node_id nid; \
CAF_CHECK_EQUAL(parse(str, nid), none); \
CAF_CHECK_EQUAL(nid, make_node_id(__VA_ARGS__)); \
} while (false)
CAF_TEST
(
node
IDs
are
convertible
from
string
)
{
node_id
::
default_data
::
host_id_type
hash
{{
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
15
,
16
,
17
,
18
,
19
,
20
,
}};
auto
uri_id
=
unbox
(
make_uri
(
"ip://foo:8080"
));
CHECK_PARSE_OK
(
"0102030405060708090A0B0C0D0E0F1011121314#1"
,
1
,
hash
);
CHECK_PARSE_OK
(
"0102030405060708090A0B0C0D0E0F1011121314#123"
,
123
,
hash
);
CHECK_PARSE_OK
(
"ip://foo:8080"
,
uri_id
);
}
#define CHECK_PARSE_FAIL(str) CAF_CHECK(!node_id::can_parse(str))
CAF_TEST
(
node
IDs
are
not
convertible
from
malformed
strings
)
{
// not URIs
CHECK_PARSE_FAIL
(
"foobar"
);
CHECK_PARSE_FAIL
(
"CAF#1"
);
// uint32_t overflow on the process ID
CHECK_PARSE_FAIL
(
"0102030405060708090A0B0C0D0E0F1011121314#42949672950"
);
}
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