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
660cc9bd
Commit
660cc9bd
authored
Aug 22, 2019
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add overloads to detail::parse for all IP types
parent
5ebeb85c
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
234 additions
and
61 deletions
+234
-61
libcaf_core/caf/detail/parse.hpp
libcaf_core/caf/detail/parse.hpp
+12
-0
libcaf_core/caf/detail/parser/read_ipv4_address.hpp
libcaf_core/caf/detail/parser/read_ipv4_address.hpp
+7
-5
libcaf_core/caf/detail/parser/read_ipv6_address.hpp
libcaf_core/caf/detail/parser/read_ipv6_address.hpp
+2
-2
libcaf_core/caf/ipv4_endpoint.hpp
libcaf_core/caf/ipv4_endpoint.hpp
+3
-0
libcaf_core/caf/ipv6_endpoint.hpp
libcaf_core/caf/ipv6_endpoint.hpp
+13
-1
libcaf_core/src/ipv6_endpoint.cpp
libcaf_core/src/ipv6_endpoint.cpp
+12
-0
libcaf_core/src/parse.cpp
libcaf_core/src/parse.cpp
+112
-0
libcaf_core/test/ipv4_endpoint.cpp
libcaf_core/test/ipv4_endpoint.cpp
+6
-12
libcaf_core/test/ipv6_endpoint.cpp
libcaf_core/test/ipv6_endpoint.cpp
+13
-41
libcaf_core/test/parse.cpp
libcaf_core/test/parse.cpp
+54
-0
No files found.
libcaf_core/caf/detail/parse.hpp
View file @
660cc9bd
...
@@ -82,6 +82,18 @@ void parse(parse_state& ps, timespan& x);
...
@@ -82,6 +82,18 @@ void parse(parse_state& ps, timespan& x);
void
parse
(
parse_state
&
ps
,
atom_value
&
x
);
void
parse
(
parse_state
&
ps
,
atom_value
&
x
);
void
parse
(
parse_state
&
ps
,
ipv4_address
&
x
);
void
parse
(
parse_state
&
ps
,
ipv4_subnet
&
x
);
void
parse
(
parse_state
&
ps
,
ipv4_endpoint
&
x
);
void
parse
(
parse_state
&
ps
,
ipv6_address
&
x
);
void
parse
(
parse_state
&
ps
,
ipv6_subnet
&
x
);
void
parse
(
parse_state
&
ps
,
ipv6_endpoint
&
x
);
void
parse
(
parse_state
&
ps
,
uri
&
x
);
void
parse
(
parse_state
&
ps
,
uri
&
x
);
// -- STL types ----------------------------------------------------------------
// -- STL types ----------------------------------------------------------------
...
...
libcaf_core/caf/detail/parser/read_ipv4_address.hpp
View file @
660cc9bd
...
@@ -41,10 +41,10 @@ namespace parser {
...
@@ -41,10 +41,10 @@ namespace parser {
struct
read_ipv4_octet_consumer
{
struct
read_ipv4_octet_consumer
{
std
::
array
<
uint8_t
,
4
>
bytes
;
std
::
array
<
uint8_t
,
4
>
bytes
;
in
t
octets
=
0
;
size_
t
octets
=
0
;
void
value
(
uint8_t
octet
)
{
void
value
(
uint8_t
octet
)
{
bytes
[
static_cast
<
size_t
>
(
octets
++
)
]
=
octet
;
bytes
[
octets
++
]
=
octet
;
}
}
};
};
...
@@ -73,14 +73,15 @@ void read_ipv4_octet(state<Iterator, Sentinel>& ps, Consumer& consumer) {
...
@@ -73,14 +73,15 @@ void read_ipv4_octet(state<Iterator, Sentinel>& ps, Consumer& consumer) {
/// Reads a number, i.e., on success produces either an `int64_t` or a
/// Reads a number, i.e., on success produces either an `int64_t` or a
/// `double`.
/// `double`.
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
void
read_ipv4_address
(
state
<
Iterator
,
Sentinel
>&
ps
,
Consumer
&
consumer
)
{
void
read_ipv4_address
(
state
<
Iterator
,
Sentinel
>&
ps
,
Consumer
&
&
consumer
)
{
read_ipv4_octet_consumer
f
;
read_ipv4_octet_consumer
f
;
auto
g
=
make_scope_guard
([
&
]
{
auto
g
=
make_scope_guard
([
&
]
{
if
(
ps
.
code
<=
pec
::
trailing_character
)
{
if
(
ps
.
code
<=
pec
::
trailing_character
)
{
ipv4_address
result
{
f
.
bytes
};
ipv4_address
result
{
f
.
bytes
};
consumer
.
value
(
result
);
consumer
.
value
(
std
::
move
(
result
)
);
}
}
});
});
// clang-format off
start
();
start
();
state
(
init
)
{
state
(
init
)
{
fsm_epsilon
(
read_ipv4_octet
(
ps
,
f
),
rd_dot
,
decimal_chars
)
fsm_epsilon
(
read_ipv4_octet
(
ps
,
f
),
rd_dot
,
decimal_chars
)
...
@@ -90,12 +91,13 @@ void read_ipv4_address(state<Iterator, Sentinel>& ps, Consumer& consumer) {
...
@@ -90,12 +91,13 @@ void read_ipv4_address(state<Iterator, Sentinel>& ps, Consumer& consumer) {
}
}
state
(
rd_oct
)
{
state
(
rd_oct
)
{
fsm_epsilon_if
(
f
.
octets
<
3
,
read_ipv4_octet
(
ps
,
f
),
rd_dot
,
decimal_chars
)
fsm_epsilon_if
(
f
.
octets
<
3
,
read_ipv4_octet
(
ps
,
f
),
rd_dot
,
decimal_chars
)
fsm_epsilon_if
(
f
.
octets
==
3
,
read_ipv4_octet
(
ps
,
f
),
done
)
fsm_epsilon_if
(
f
.
octets
==
3
,
read_ipv4_octet
(
ps
,
f
),
done
,
decimal_chars
)
}
}
term_state
(
done
)
{
term_state
(
done
)
{
// nop
// nop
}
}
fin
();
fin
();
// clang-format on
}
}
}
// namespace parser
}
// namespace parser
...
...
libcaf_core/caf/detail/parser/read_ipv6_address.hpp
View file @
660cc9bd
...
@@ -174,7 +174,7 @@ read_ipv6_address_piece_consumer<F> make_read_ipv6_address_piece_consumer(F f) {
...
@@ -174,7 +174,7 @@ read_ipv6_address_piece_consumer<F> make_read_ipv6_address_piece_consumer(F f) {
/// Reads a number, i.e., on success produces either an `int64_t` or a
/// Reads a number, i.e., on success produces either an `int64_t` or a
/// `double`.
/// `double`.
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
void
read_ipv6_address
(
state
<
Iterator
,
Sentinel
>&
ps
,
Consumer
&
consumer
)
{
void
read_ipv6_address
(
state
<
Iterator
,
Sentinel
>&
ps
,
Consumer
&
&
consumer
)
{
// IPv6 allows omitting blocks of zeros, splitting the string into a part
// IPv6 allows omitting blocks of zeros, splitting the string into a part
// before the zeros (prefix) and a part after the zeros (suffix). For example,
// before the zeros (prefix) and a part after the zeros (suffix). For example,
// ff::1 is 00FF0000000000000000000000000001
// ff::1 is 00FF0000000000000000000000000001
...
@@ -194,7 +194,7 @@ void read_ipv6_address(state<Iterator, Sentinel>& ps, Consumer& consumer) {
...
@@ -194,7 +194,7 @@ void read_ipv6_address(state<Iterator, Sentinel>& ps, Consumer& consumer) {
for
(
size_t
i
=
0
;
i
<
ipv6_address
::
num_bytes
;
++
i
)
for
(
size_t
i
=
0
;
i
<
ipv6_address
::
num_bytes
;
++
i
)
bytes
[
i
]
=
prefix
[
i
]
|
suffix
[
i
];
bytes
[
i
]
=
prefix
[
i
]
|
suffix
[
i
];
ipv6_address
result
{
bytes
};
ipv6_address
result
{
bytes
};
consumer
.
value
(
result
);
consumer
.
value
(
std
::
move
(
result
)
);
}
}
});
});
// We need to parse 2-byte hexadecimal numbers (x) and also keep track of
// We need to parse 2-byte hexadecimal numbers (x) and also keep track of
...
...
libcaf_core/caf/ipv4_endpoint.hpp
View file @
660cc9bd
...
@@ -18,6 +18,9 @@
...
@@ -18,6 +18,9 @@
#pragma once
#pragma once
#include <cstdint>
#include <functional>
#include "caf/detail/comparable.hpp"
#include "caf/detail/comparable.hpp"
#include "caf/ipv4_address.hpp"
#include "caf/ipv4_address.hpp"
#include "caf/meta/type_name.hpp"
#include "caf/meta/type_name.hpp"
...
...
libcaf_core/caf/ipv6_endpoint.hpp
View file @
660cc9bd
...
@@ -18,19 +18,26 @@
...
@@ -18,19 +18,26 @@
#pragma once
#pragma once
#include <cstdint>
#include <functional>
#include "caf/detail/comparable.hpp"
#include "caf/detail/comparable.hpp"
#include "caf/fwd.hpp"
#include "caf/ipv6_address.hpp"
#include "caf/ipv6_address.hpp"
#include "caf/meta/type_name.hpp"
#include "caf/meta/type_name.hpp"
namespace
caf
{
namespace
caf
{
/// An IP endpoint that contains an ::ipv6_address and a port.
/// An IP endpoint that contains an ::ipv6_address and a port.
class
ipv6_endpoint
:
detail
::
comparable
<
ipv6_endpoint
>
{
class
ipv6_endpoint
:
detail
::
comparable
<
ipv6_endpoint
>
,
detail
::
comparable
<
ipv6_endpoint
,
ipv4_endpoint
>
{
public:
public:
// -- constructors -----------------------------------------------------------
// -- constructors -----------------------------------------------------------
ipv6_endpoint
(
ipv6_address
address
,
uint16_t
port
);
ipv6_endpoint
(
ipv6_address
address
,
uint16_t
port
);
ipv6_endpoint
(
ipv4_address
address
,
uint16_t
port
);
ipv6_endpoint
()
=
default
;
ipv6_endpoint
()
=
default
;
ipv6_endpoint
(
const
ipv6_endpoint
&
)
=
default
;
ipv6_endpoint
(
const
ipv6_endpoint
&
)
=
default
;
...
@@ -67,6 +74,11 @@ public:
...
@@ -67,6 +74,11 @@ public:
/// value otherwise.
/// value otherwise.
long
compare
(
ipv6_endpoint
x
)
const
noexcept
;
long
compare
(
ipv6_endpoint
x
)
const
noexcept
;
/// Compares this endpoint to `x`.
/// @returns 0 if `*this == x`, a positive value if `*this > x` and a negative
/// value otherwise.
long
compare
(
ipv4_endpoint
x
)
const
noexcept
;
template
<
class
Inspector
>
template
<
class
Inspector
>
friend
typename
Inspector
::
result_type
inspect
(
Inspector
&
f
,
friend
typename
Inspector
::
result_type
inspect
(
Inspector
&
f
,
ipv6_endpoint
&
x
)
{
ipv6_endpoint
&
x
)
{
...
...
libcaf_core/src/ipv6_endpoint.cpp
View file @
660cc9bd
...
@@ -19,6 +19,8 @@
...
@@ -19,6 +19,8 @@
#include "caf/ipv6_endpoint.hpp"
#include "caf/ipv6_endpoint.hpp"
#include "caf/detail/fnv_hash.hpp"
#include "caf/detail/fnv_hash.hpp"
#include "caf/ipv4_address.hpp"
#include "caf/ipv4_endpoint.hpp"
namespace
caf
{
namespace
caf
{
...
@@ -27,6 +29,11 @@ ipv6_endpoint::ipv6_endpoint(ipv6_address address, uint16_t port)
...
@@ -27,6 +29,11 @@ ipv6_endpoint::ipv6_endpoint(ipv6_address address, uint16_t port)
// nop
// nop
}
}
ipv6_endpoint
::
ipv6_endpoint
(
ipv4_address
address
,
uint16_t
port
)
:
address_
(
address
),
port_
(
port
)
{
// nop
}
size_t
ipv6_endpoint
::
hash_code
()
const
noexcept
{
size_t
ipv6_endpoint
::
hash_code
()
const
noexcept
{
auto
result
=
detail
::
fnv_hash
(
address_
.
data
());
auto
result
=
detail
::
fnv_hash
(
address_
.
data
());
return
detail
::
fnv_hash_append
(
result
,
port_
);
return
detail
::
fnv_hash_append
(
result
,
port_
);
...
@@ -37,6 +44,11 @@ long ipv6_endpoint::compare(ipv6_endpoint x) const noexcept {
...
@@ -37,6 +44,11 @@ long ipv6_endpoint::compare(ipv6_endpoint x) const noexcept {
return
res
==
0
?
port_
-
x
.
port
()
:
res
;
return
res
==
0
?
port_
-
x
.
port
()
:
res
;
}
}
long
ipv6_endpoint
::
compare
(
ipv4_endpoint
x
)
const
noexcept
{
ipv6_endpoint
y
{
x
.
address
(),
x
.
port
()};
return
compare
(
y
);
}
std
::
string
to_string
(
const
ipv6_endpoint
&
x
)
{
std
::
string
to_string
(
const
ipv6_endpoint
&
x
)
{
std
::
string
result
;
std
::
string
result
;
auto
addr
=
x
.
address
();
auto
addr
=
x
.
address
();
...
...
libcaf_core/src/parse.cpp
View file @
660cc9bd
...
@@ -23,11 +23,19 @@
...
@@ -23,11 +23,19 @@
#include "caf/detail/parser/read_atom.hpp"
#include "caf/detail/parser/read_atom.hpp"
#include "caf/detail/parser/read_bool.hpp"
#include "caf/detail/parser/read_bool.hpp"
#include "caf/detail/parser/read_floating_point.hpp"
#include "caf/detail/parser/read_floating_point.hpp"
#include "caf/detail/parser/read_ipv4_address.hpp"
#include "caf/detail/parser/read_ipv6_address.hpp"
#include "caf/detail/parser/read_signed_integer.hpp"
#include "caf/detail/parser/read_signed_integer.hpp"
#include "caf/detail/parser/read_string.hpp"
#include "caf/detail/parser/read_string.hpp"
#include "caf/detail/parser/read_timespan.hpp"
#include "caf/detail/parser/read_timespan.hpp"
#include "caf/detail/parser/read_unsigned_integer.hpp"
#include "caf/detail/parser/read_unsigned_integer.hpp"
#include "caf/detail/parser/read_uri.hpp"
#include "caf/detail/parser/read_uri.hpp"
#include "caf/ipv4_address.hpp"
#include "caf/ipv4_endpoint.hpp"
#include "caf/ipv4_subnet.hpp"
#include "caf/ipv6_address.hpp"
#include "caf/ipv6_endpoint.hpp"
#include "caf/ipv6_subnet.hpp"
#include "caf/uri_builder.hpp"
#include "caf/uri_builder.hpp"
#define PARSE_IMPL(type, parser_name) \
#define PARSE_IMPL(type, parser_name) \
...
@@ -38,6 +46,42 @@
...
@@ -38,6 +46,42 @@
namespace
caf
{
namespace
caf
{
namespace
detail
{
namespace
detail
{
struct
literal
{
string_view
str
;
};
void
parse
(
parse_state
&
ps
,
literal
&
x
)
{
CAF_ASSERT
(
x
.
str
.
size
()
>
0
);
if
(
ps
.
current
()
!=
x
.
str
[
0
])
{
ps
.
code
=
pec
::
unexpected_character
;
return
;
}
auto
c
=
ps
.
next
();
for
(
auto
i
=
x
.
str
.
begin
()
+
1
;
i
!=
x
.
str
.
end
();
++
i
)
{
if
(
c
!=
*
i
)
{
ps
.
code
=
pec
::
unexpected_character
;
return
;
}
c
=
ps
.
next
();
}
ps
.
code
=
ps
.
at_end
()
?
pec
::
success
:
pec
::
trailing_character
;
}
void
parse_sequence
(
parse_state
&
)
{
// End of recursion.
}
template
<
class
T
,
class
...
Ts
>
void
parse_sequence
(
parse_state
&
ps
,
T
&&
x
,
Ts
&&
...
xs
)
{
parse
(
ps
,
x
);
// TODO: use `if constexpr` when switching to C++17
if
(
sizeof
...(
Ts
)
>
0
)
{
CAF_ASSERT
(
ps
.
code
!=
pec
::
success
);
if
(
ps
.
code
==
pec
::
trailing_character
)
parse_sequence
(
ps
,
std
::
forward
<
Ts
>
(
xs
)...);
}
}
PARSE_IMPL
(
bool
,
bool
)
PARSE_IMPL
(
bool
,
bool
)
PARSE_IMPL
(
int8_t
,
signed_integer
)
PARSE_IMPL
(
int8_t
,
signed_integer
)
...
@@ -83,6 +127,74 @@ void parse(parse_state& ps, uri& x) {
...
@@ -83,6 +127,74 @@ void parse(parse_state& ps, uri& x) {
x
=
builder
.
make
();
x
=
builder
.
make
();
}
}
PARSE_IMPL
(
ipv4_address
,
ipv4_address
)
void
parse
(
parse_state
&
ps
,
ipv4_subnet
&
x
)
{
ipv4_address
addr
;
uint8_t
prefix_length
;
parse_sequence
(
ps
,
addr
,
literal
{
"/"
},
prefix_length
);
if
(
ps
.
code
<=
pec
::
trailing_character
)
{
if
(
prefix_length
>
32
)
{
ps
.
code
=
pec
::
integer_overflow
;
return
;
}
x
=
ipv4_subnet
{
addr
,
prefix_length
};
}
}
void
parse
(
parse_state
&
ps
,
ipv4_endpoint
&
x
)
{
ipv4_address
addr
;
uint16_t
port
;
parse_sequence
(
ps
,
addr
,
literal
{
":"
},
port
);
if
(
ps
.
code
<=
pec
::
trailing_character
)
x
=
ipv4_endpoint
{
addr
,
port
};
}
PARSE_IMPL
(
ipv6_address
,
ipv6_address
)
void
parse
(
parse_state
&
ps
,
ipv6_subnet
&
x
)
{
// TODO: this algorithm is currently not one-pass. The reason we need to
// check whether the input is a valid ipv4_subnet first is that "1.2.3.0" is
// a valid IPv6 address, but "1.2.3.0/16" results in the wrong subnet when
// blindly reading the address as an IPv6 address.
auto
nested
=
ps
;
ipv4_subnet
v4_subnet
;
parse
(
nested
,
v4_subnet
);
if
(
nested
.
code
<=
pec
::
trailing_character
)
{
ps
.
i
=
nested
.
i
;
ps
.
code
=
nested
.
code
;
ps
.
line
=
nested
.
line
;
ps
.
column
=
nested
.
column
;
x
=
ipv6_subnet
{
v4_subnet
};
return
;
}
ipv6_address
addr
;
uint8_t
prefix_length
;
parse_sequence
(
ps
,
addr
,
literal
{
"/"
},
prefix_length
);
if
(
ps
.
code
<=
pec
::
trailing_character
)
{
if
(
prefix_length
>
128
)
{
ps
.
code
=
pec
::
integer_overflow
;
return
;
}
x
=
ipv6_subnet
{
addr
,
prefix_length
};
}
}
void
parse
(
parse_state
&
ps
,
ipv6_endpoint
&
x
)
{
ipv6_address
addr
;
uint16_t
port
;
if
(
ps
.
consume
(
'['
))
{
parse_sequence
(
ps
,
addr
,
literal
{
"]:"
},
port
);
}
else
{
ipv4_address
v4_addr
;
parse_sequence
(
ps
,
v4_addr
,
literal
{
":"
},
port
);
if
(
ps
.
code
<=
pec
::
trailing_character
)
addr
=
ipv6_address
{
v4_addr
};
}
if
(
ps
.
code
<=
pec
::
trailing_character
)
x
=
ipv6_endpoint
{
addr
,
port
};
}
void
parse
(
parse_state
&
ps
,
std
::
string
&
x
)
{
void
parse
(
parse_state
&
ps
,
std
::
string
&
x
)
{
ps
.
skip_whitespaces
();
ps
.
skip_whitespaces
();
if
(
ps
.
current
()
==
'"'
)
{
if
(
ps
.
current
()
==
'"'
)
{
...
...
libcaf_core/test/ipv4_endpoint.cpp
View file @
660cc9bd
...
@@ -30,6 +30,7 @@
...
@@ -30,6 +30,7 @@
#include "caf/actor_system_config.hpp"
#include "caf/actor_system_config.hpp"
#include "caf/binary_deserializer.hpp"
#include "caf/binary_deserializer.hpp"
#include "caf/byte.hpp"
#include "caf/byte.hpp"
#include "caf/detail/parse.hpp"
#include "caf/ipv4_address.hpp"
#include "caf/ipv4_address.hpp"
#include "caf/serializer_impl.hpp"
#include "caf/serializer_impl.hpp"
#include "caf/span.hpp"
#include "caf/span.hpp"
...
@@ -38,18 +39,11 @@ using namespace caf;
...
@@ -38,18 +39,11 @@ using namespace caf;
namespace
{
namespace
{
ipv4_endpoint
operator
""
_ep
(
const
char
*
str
,
size_t
)
{
ipv4_endpoint
operator
""
_ep
(
const
char
*
str
,
size_t
size
)
{
std
::
array
<
uint8_t
,
4
>
bytes
;
ipv4_endpoint
result
;
char
*
next
=
nullptr
;
if
(
auto
err
=
detail
::
parse
(
string_view
{
str
,
size
},
result
))
bytes
[
0
]
=
static_cast
<
uint8_t
>
(
strtol
(
str
,
&
next
,
10
));
CAF_FAIL
(
"unable to parse input: "
<<
err
);
for
(
size_t
n
=
1
;
n
<
4
;
++
n
)
{
return
result
;
assert
(
*
next
==
'.'
);
str
=
next
+
1
;
bytes
[
n
]
=
static_cast
<
uint8_t
>
(
strtol
(
str
,
&
next
,
10
));
}
assert
(
*
next
==
':'
);
auto
port
=
static_cast
<
uint16_t
>
(
strtol
(
next
+
1
,
nullptr
,
10
));
return
ipv4_endpoint
{
ipv4_address
{
bytes
},
port
};
}
}
struct
fixture
{
struct
fixture
{
...
...
libcaf_core/test/ipv6_endpoint.cpp
View file @
660cc9bd
...
@@ -29,6 +29,8 @@
...
@@ -29,6 +29,8 @@
#include "caf/actor_system_config.hpp"
#include "caf/actor_system_config.hpp"
#include "caf/binary_deserializer.hpp"
#include "caf/binary_deserializer.hpp"
#include "caf/byte.hpp"
#include "caf/byte.hpp"
#include "caf/ipv4_address.hpp"
#include "caf/ipv4_endpoint.hpp"
#include "caf/ipv6_address.hpp"
#include "caf/ipv6_address.hpp"
#include "caf/serializer_impl.hpp"
#include "caf/serializer_impl.hpp"
#include "caf/span.hpp"
#include "caf/span.hpp"
...
@@ -37,47 +39,11 @@ using namespace caf;
...
@@ -37,47 +39,11 @@ using namespace caf;
namespace
{
namespace
{
ipv6_endpoint
operator
""
_ep
(
const
char
*
str
,
size_t
)
{
ipv6_endpoint
operator
""
_ep
(
const
char
*
str
,
size_t
size
)
{
union
{
ipv6_endpoint
result
;
std
::
array
<
uint8_t
,
16
>
xs_bytes
;
if
(
auto
err
=
detail
::
parse
(
string_view
{
str
,
size
},
result
))
std
::
array
<
uint16_t
,
8
>
xs
;
CAF_FAIL
(
"unable to parse input: "
<<
err
);
};
return
result
;
union
{
std
::
array
<
uint8_t
,
16
>
ys_bytes
;
std
::
array
<
uint16_t
,
8
>
ys
;
};
memset
(
xs_bytes
.
data
(),
0
,
xs_bytes
.
size
());
memset
(
ys_bytes
.
data
(),
0
,
xs_bytes
.
size
());
assert
(
*
str
==
'['
);
++
str
;
char
*
next
=
nullptr
;
auto
pull
=
[
&
]
{
auto
x
=
static_cast
<
uint16_t
>
(
strtol
(
str
,
&
next
,
16
));
return
detail
::
to_network_order
(
x
);
};
size_t
n
=
0
;
do
{
xs
[
n
++
]
=
pull
();
assert
(
next
!=
nullptr
);
str
=
next
+
1
;
}
while
(
*
str
!=
':'
&&
*
str
!=
']'
);
if
(
*
str
==
':'
)
{
++
str
;
do
{
ys
[
0
]
=
pull
();
std
::
rotate
(
ys
.
begin
(),
ys
.
begin
()
+
1
,
ys
.
end
());
assert
(
next
!=
nullptr
);
str
=
next
+
1
;
}
while
(
*
next
!=
']'
);
}
assert
(
*
next
==
']'
);
assert
(
*
str
==
':'
);
++
str
;
auto
port
=
static_cast
<
uint16_t
>
(
strtol
(
str
,
nullptr
,
10
));
std
::
array
<
uint8_t
,
16
>
bytes
;
for
(
size_t
i
=
0
;
i
<
16
;
++
i
)
bytes
[
i
]
=
xs_bytes
[
i
]
|
ys_bytes
[
i
];
return
ipv6_endpoint
{
ipv6_address
{
bytes
},
port
};
}
}
struct
fixture
{
struct
fixture
{
...
@@ -138,6 +104,12 @@ CAF_TEST(constructing assigning and hash_code) {
...
@@ -138,6 +104,12 @@ CAF_TEST(constructing assigning and hash_code) {
CAF_CHECK_EQUAL
(
ep1
.
hash_code
(),
ep2
.
hash_code
());
CAF_CHECK_EQUAL
(
ep1
.
hash_code
(),
ep2
.
hash_code
());
}
}
CAF_TEST
(
comparison
to
IPv4
)
{
ipv4_endpoint
v4
{
ipv4_address
({
127
,
0
,
0
,
1
}),
8080
};
ipv6_endpoint
v6
{
v4
.
address
(),
v4
.
port
()};
CAF_CHECK_EQUAL
(
v4
,
v6
);
}
CAF_TEST
(
to_string
)
{
CAF_TEST
(
to_string
)
{
CHECK_TO_STRING
(
"[::1]:8888"
);
CHECK_TO_STRING
(
"[::1]:8888"
);
CHECK_TO_STRING
(
"[4e::d00:0:ed00:0:1]:1234"
);
CHECK_TO_STRING
(
"[4e::d00:0:ed00:0:1]:1234"
);
...
...
libcaf_core/test/parse.cpp
View file @
660cc9bd
...
@@ -23,6 +23,12 @@
...
@@ -23,6 +23,12 @@
#include "caf/test/dsl.hpp"
#include "caf/test/dsl.hpp"
#include "caf/expected.hpp"
#include "caf/expected.hpp"
#include "caf/ipv4_address.hpp"
#include "caf/ipv4_endpoint.hpp"
#include "caf/ipv4_subnet.hpp"
#include "caf/ipv6_address.hpp"
#include "caf/ipv6_endpoint.hpp"
#include "caf/ipv6_subnet.hpp"
#include "caf/string_view.hpp"
#include "caf/string_view.hpp"
#include "caf/uri.hpp"
#include "caf/uri.hpp"
...
@@ -216,3 +222,51 @@ CAF_TEST(uris) {
...
@@ -216,3 +222,51 @@ CAF_TEST(uris) {
CAF_CHECK_EQUAL
(
ls
[
1
].
authority
().
host
,
std
::
string
{
"actor-framework.org"
});
CAF_CHECK_EQUAL
(
ls
[
1
].
authority
().
host
,
std
::
string
{
"actor-framework.org"
});
CAF_CHECK_EQUAL
(
ls
[
1
].
path
(),
"doc"
);
CAF_CHECK_EQUAL
(
ls
[
1
].
path
(),
"doc"
);
}
}
CAF_TEST
(
IPv4
address
)
{
CAF_CHECK_EQUAL
(
read
<
ipv4_address
>
(
"1.2.3.4"
),
ipv4_address
({
1
,
2
,
3
,
4
}));
CAF_CHECK_EQUAL
(
read
<
ipv4_address
>
(
"127.0.0.1"
),
ipv4_address
({
127
,
0
,
0
,
1
}));
CAF_CHECK_EQUAL
(
read
<
ipv4_address
>
(
"256.0.0.1"
),
pec
::
integer_overflow
);
}
CAF_TEST
(
IPv4
subnet
)
{
CAF_CHECK_EQUAL
(
read
<
ipv4_subnet
>
(
"1.2.3.0/24"
),
ipv4_subnet
(
ipv4_address
({
1
,
2
,
3
,
0
}),
24
));
CAF_CHECK_EQUAL
(
read
<
ipv4_subnet
>
(
"1.2.3.0/33"
),
pec
::
integer_overflow
);
}
CAF_TEST
(
IPv4
endpoint
)
{
CAF_CHECK_EQUAL
(
read
<
ipv4_endpoint
>
(
"127.0.0.1:0"
),
ipv4_endpoint
(
ipv4_address
({
127
,
0
,
0
,
1
}),
0
));
CAF_CHECK_EQUAL
(
read
<
ipv4_endpoint
>
(
"127.0.0.1:65535"
),
ipv4_endpoint
(
ipv4_address
({
127
,
0
,
0
,
1
}),
65535
));
CAF_CHECK_EQUAL
(
read
<
ipv4_endpoint
>
(
"127.0.0.1:65536"
),
pec
::
integer_overflow
);
}
CAF_TEST
(
IPv6
address
)
{
CAF_CHECK_EQUAL
(
read
<
ipv6_address
>
(
"1.2.3.4"
),
ipv4_address
({
1
,
2
,
3
,
4
}));
CAF_CHECK_EQUAL
(
read
<
ipv6_address
>
(
"1::"
),
ipv6_address
({{
1
},
{}}));
CAF_CHECK_EQUAL
(
read
<
ipv6_address
>
(
"::2"
),
ipv6_address
({{},
{
2
}}));
CAF_CHECK_EQUAL
(
read
<
ipv6_address
>
(
"1::2"
),
ipv6_address
({{
1
},
{
2
}}));
}
CAF_TEST
(
IPv6
subnet
)
{
CAF_CHECK_EQUAL
(
read
<
ipv6_subnet
>
(
"1.2.3.0/24"
),
ipv6_subnet
(
ipv4_address
({
1
,
2
,
3
,
0
}),
24
));
CAF_CHECK_EQUAL
(
read
<
ipv6_subnet
>
(
"1::/128"
),
ipv6_subnet
(
ipv6_address
({
1
},
{}),
128
));
CAF_CHECK_EQUAL
(
read
<
ipv6_subnet
>
(
"1::/129"
),
pec
::
integer_overflow
);
}
CAF_TEST
(
IPv6
endpoint
)
{
CAF_CHECK_EQUAL
(
read
<
ipv6_endpoint
>
(
"127.0.0.1:0"
),
ipv6_endpoint
(
ipv4_address
({
127
,
0
,
0
,
1
}),
0
));
CAF_CHECK_EQUAL
(
read
<
ipv6_endpoint
>
(
"127.0.0.1:65535"
),
ipv6_endpoint
(
ipv4_address
({
127
,
0
,
0
,
1
}),
65535
));
CAF_CHECK_EQUAL
(
read
<
ipv6_endpoint
>
(
"127.0.0.1:65536"
),
pec
::
integer_overflow
);
CAF_CHECK_EQUAL
(
read
<
ipv6_endpoint
>
(
"[1::2]:8080"
),
ipv6_endpoint
({{
1
},
{
2
}},
8080
));
}
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