Commit 77288023 authored by Dominik Charousset's avatar Dominik Charousset

Use same consumer API for IPv4 and IPv6

parent 6c41d375
...@@ -21,13 +21,14 @@ ...@@ -21,13 +21,14 @@
#include <cstdint> #include <cstdint>
#include "caf/config.hpp" #include "caf/config.hpp"
#include "caf/detail/parser/chars.hpp"
#include "caf/detail/parser/add_ascii.hpp" #include "caf/detail/parser/add_ascii.hpp"
#include "caf/detail/parser/chars.hpp"
#include "caf/detail/parser/is_char.hpp" #include "caf/detail/parser/is_char.hpp"
#include "caf/detail/parser/is_digit.hpp" #include "caf/detail/parser/is_digit.hpp"
#include "caf/detail/parser/state.hpp" #include "caf/detail/parser/state.hpp"
#include "caf/detail/parser/sub_ascii.hpp" #include "caf/detail/parser/sub_ascii.hpp"
#include "caf/detail/scope_guard.hpp" #include "caf/detail/scope_guard.hpp"
#include "caf/ipv4_address.hpp"
#include "caf/pec.hpp" #include "caf/pec.hpp"
CAF_PUSH_UNUSED_LABEL_WARNING CAF_PUSH_UNUSED_LABEL_WARNING
...@@ -38,6 +39,15 @@ namespace caf { ...@@ -38,6 +39,15 @@ namespace caf {
namespace detail { namespace detail {
namespace parser { namespace parser {
struct read_ipv4_octet_consumer {
std::array<uint8_t, 4> bytes;
int octets = 0;
inline void value(uint8_t octet) {
bytes[octets++] = octet;
}
};
template <class Iterator, class Sentinel, class Consumer> template <class Iterator, class Sentinel, class Consumer>
void read_ipv4_octet(state<Iterator, Sentinel>& ps, Consumer& consumer) { void read_ipv4_octet(state<Iterator, Sentinel>& ps, Consumer& consumer) {
uint8_t res = 0; uint8_t res = 0;
...@@ -64,18 +74,23 @@ void read_ipv4_octet(state<Iterator, Sentinel>& ps, Consumer& consumer) { ...@@ -64,18 +74,23 @@ void read_ipv4_octet(state<Iterator, Sentinel>& ps, Consumer& consumer) {
/// `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) {
int octets = 0; read_ipv4_octet_consumer f;
auto g = make_scope_guard([&] {
if (ps.code <= pec::trailing_character) {
ipv4_address result{f.bytes};
consumer.value(result);
}
});
start(); start();
state(init) { state(init) {
fsm_epsilon(read_ipv4_octet(ps, consumer), rd_dot, decimal_chars, ++octets) fsm_epsilon(read_ipv4_octet(ps, f), rd_dot, decimal_chars)
} }
state(rd_dot) { state(rd_dot) {
transition(rd_oct, '.') transition(rd_oct, '.')
} }
state(rd_oct) { state(rd_oct) {
fsm_epsilon_if(octets < 3, read_ipv4_octet(ps, consumer), rd_dot, fsm_epsilon_if(f.octets < 3, read_ipv4_octet(ps, f), rd_dot, decimal_chars)
decimal_chars, ++octets) fsm_epsilon_if(f.octets == 3, read_ipv4_octet(ps, f), done)
fsm_epsilon_if(octets == 3, read_ipv4_octet(ps, consumer), done)
} }
term_state(done) { term_state(done) {
// nop // nop
......
...@@ -33,15 +33,14 @@ inline uint32_t net_order(uint32_t value) { ...@@ -33,15 +33,14 @@ inline uint32_t net_order(uint32_t value) {
} }
struct ipv4_address_consumer { struct ipv4_address_consumer {
size_t pos;
ipv4_address& dest; ipv4_address& dest;
ipv4_address_consumer(ipv4_address& ref) : pos(0), dest(ref) { ipv4_address_consumer(ipv4_address& ref) : dest(ref) {
// nop // nop
} }
void value(uint8_t octet) { void value(ipv4_address val) {
dest[pos++] = octet; dest = val;
} }
}; };
......
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