Skip to content
Snippets Groups Projects
Commit 6e379f64 authored by Benny Baumann's avatar Benny Baumann
Browse files

chg: Make the connection_client class a template

parent ba885f32
No related branches found
No related tags found
1 merge request!1First unit tests
...@@ -13,7 +13,8 @@ ...@@ -13,7 +13,8 @@
namespace rmrf::net { namespace rmrf::net {
class connection_client : public std::enable_shared_from_this<connection_client> { template<class client>
class connection_client : public std::enable_shared_from_this<client> {
public: public:
/** /**
* This function type accepts a reference to the incomming data string which it may not alter * This function type accepts a reference to the incomming data string which it may not alter
......
...@@ -38,61 +38,4 @@ std::string::size_type default_eol_search( ...@@ -38,61 +38,4 @@ std::string::size_type default_eol_search(
return std::string::npos; return std::string::npos;
} }
connection_line_buffer::connection_line_buffer(
std::shared_ptr<connection_client> c,
found_next_line_cb_t found_next_line_cb_,
std::string::size_type max_line_size,
eol_search_t search_lb
) :
search(search_lb),
client(c),
found_next_line_cb(found_next_line_cb_),
max(max_line_size),
data("")
{
this->client->set_incomming_data_callback(
[this](const std::string& data_in) {
conn_data_in_cb(data_in);
});
}
connection_line_buffer::connection_line_buffer(
std::shared_ptr<connection_client> c,
found_next_line_cb_t found_next_line_cb_,
std::string::size_type max_line_size
) :
connection_line_buffer{c, found_next_line_cb_, max_line_size, &default_eol_search}
{}
void connection_line_buffer::conn_data_in_cb(const std::string &data_in) {
// Iterate throug the incomming data as long as we find line breaks
for (std::string::size_type strpos = 0, nextpos = -1; strpos != std::string::npos; strpos = nextpos++) {
// Search for the next line break
nextpos = this->search(data_in, strpos);
// Advance, if the line would be empty
if (nextpos == strpos) {
nextpos = this->search(data_in, ++strpos);
}
if (nextpos == std::string::npos) {
// If we didn't find one we store the remaining data in the buffer
this->data += data_in.substr(strpos, data_in.length() - strpos);
break;
} else {
// If we find one we send the buffer plus the incomming data up to the line break to the callback
const std::string data_to_send = this->data + data_in.substr(strpos, nextpos - strpos);
this->found_next_line_cb(data_to_send, true);
// and clear the buffer
this->data = std::string("");
}
}
if (this->data.length() > this->max) {
this->found_next_line_cb(this->data, false);
this->data = std::string("");
}
}
} }
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <string> #include <string>
#include <sstream>
#include "net/connection_client.hpp" #include "net/connection_client.hpp"
...@@ -58,6 +59,7 @@ std::string::size_type default_eol_search(const std::string& data, std::string:: ...@@ -58,6 +59,7 @@ std::string::size_type default_eol_search(const std::string& data, std::string::
* @see rmrf::net::default_eol_search * @see rmrf::net::default_eol_search
* @see rmrf::net::eol_search_t * @see rmrf::net::eol_search_t
*/ */
template<class client_type>
class connection_line_buffer { class connection_line_buffer {
public: public:
/** /**
...@@ -72,10 +74,11 @@ public: ...@@ -72,10 +74,11 @@ public:
private: private:
const eol_search_t search; const eol_search_t search;
std::shared_ptr<connection_client> client; std::shared_ptr<connection_client<client_type>> client;
found_next_line_cb_t found_next_line_cb; found_next_line_cb_t found_next_line_cb;
std::string::size_type max; std::string::size_type max;
std::string data; std::ostringstream data_buffer;
size_t buffer_length;
public: public:
/** /**
...@@ -86,7 +89,7 @@ public: ...@@ -86,7 +89,7 @@ public:
* @param max_line_size The maximum line length to aquire prior to collection abort and transmission of the incomplete line * @param max_line_size The maximum line length to aquire prior to collection abort and transmission of the incomplete line
* @param search_lb The callback to use for line break detection * @param search_lb The callback to use for line break detection
*/ */
connection_line_buffer(std::shared_ptr<connection_client> c, found_next_line_cb_t found_next_line_cb_, std::string::size_type max_line_size, eol_search_t search_lb); connection_line_buffer(std::shared_ptr<connection_client<client_type>> c, found_next_line_cb_t found_next_line_cb_, std::string::size_type max_line_size, eol_search_t search_lb);
/** /**
* This constructor creates a new buffer based on a given client, an input callback and the maximum line size. * This constructor creates a new buffer based on a given client, an input callback and the maximum line size.
...@@ -96,10 +99,81 @@ public: ...@@ -96,10 +99,81 @@ public:
* @param found_next_line_cb_ The callback to be called when a complete new line arrived * @param found_next_line_cb_ The callback to be called when a complete new line arrived
* @param max_line_size The maximum line length to aquire prior to collection abort and transmission of the incomplete line * @param max_line_size The maximum line length to aquire prior to collection abort and transmission of the incomplete line
*/ */
connection_line_buffer(std::shared_ptr<connection_client> c, found_next_line_cb_t found_next_line_cb_, std::string::size_type max_line_size); connection_line_buffer(std::shared_ptr<connection_client<client_type>> c, found_next_line_cb_t found_next_line_cb_, std::string::size_type max_line_size);
private: private:
void conn_data_in_cb(const std::string& data_in); void conn_data_in_cb(const std::string& data_in);
void clear();
}; };
template <class client_type>
connection_line_buffer<client_type>::connection_line_buffer(
std::shared_ptr<connection_client<client_type>> c,
found_next_line_cb_t found_next_line_cb_,
std::string::size_type max_line_size,
eol_search_t search_lb
) :
search(search_lb),
client(c),
found_next_line_cb(found_next_line_cb_),
max(max_line_size),
data_buffer(std::ostringstream::ate),
buffer_length{0}
{
this->client->set_incomming_data_callback(
[this](const std::string& data_in) {
conn_data_in_cb(data_in);
});
}
template <class client_type>
connection_line_buffer<client_type>::connection_line_buffer(
std::shared_ptr<connection_client<client_type>> c,
found_next_line_cb_t found_next_line_cb_,
std::string::size_type max_line_size
) :
connection_line_buffer{c, found_next_line_cb_, max_line_size, &default_eol_search}
{}
template <class client_type>
void connection_line_buffer<client_type>::clear() {
this->data_buffer.str(std::string());
this->data_buffer.clear();
this->buffer_length = 0;
}
template <class client_type>
void connection_line_buffer<client_type>::conn_data_in_cb(const std::string& data_in) {
// Iterate throug the incomming data as long as we find line breaks
for (std::string::size_type strpos = 0, nextpos = -1; strpos != std::string::npos; strpos = nextpos++) {
// Search for the next line break
nextpos = this->search(data_in, strpos);
// Advance, if the line would be empty
if (nextpos == strpos) {
nextpos = this->search(data_in, ++strpos);
}
if (nextpos == std::string::npos) {
// If we didn't find one we store the remaining data in the buffer
const auto length = data_in.length() - strpos;
this->data_buffer << data_in.substr(strpos, length);
this->buffer_length += length;
break;
} else {
// If we find one we send the buffer plus the incomming data up to the line break to the callback
const std::string data_to_send = this->data_buffer.str() + data_in.substr(strpos, nextpos - strpos);
this->found_next_line_cb(data_to_send, true);
// and clear the buffer
this->clear();
}
}
if (this->buffer_length > this->max) {
this->found_next_line_cb(this->data_buffer.str(), false);
this->clear();
}
}
} }
...@@ -32,7 +32,7 @@ enum class exit_status_t : uint16_t { ...@@ -32,7 +32,7 @@ enum class exit_status_t : uint16_t {
* @author doralitze BenBe * @author doralitze BenBe
* @brief A raw TCP client. * @brief A raw TCP client.
*/ */
class tcp_client : public connection_client, std::enable_shared_from_this<tcp_client> { class tcp_client : public connection_client<tcp_client> {
public: public:
/** /**
* A callback for the destructor must match this definition. * A callback for the destructor must match this definition.
......
...@@ -67,7 +67,7 @@ BOOST_AUTO_TEST_CASE(Default_EoL_Search_Test) { ...@@ -67,7 +67,7 @@ BOOST_AUTO_TEST_CASE(Default_EoL_Search_Test) {
BOOST_AUTO_TEST_CASE(Connection_Line_Buffer_Test) { BOOST_AUTO_TEST_CASE(Connection_Line_Buffer_Test) {
mut_send_stage = 0; mut_send_stage = 0;
auto ll_client = std::make_shared<loopback_connection_client>(mut_send_data_cb, false); auto ll_client = std::make_shared<loopback_connection_client>(mut_send_data_cb, false);
connection_line_buffer clb(ll_client, next_line_cb, 150); connection_line_buffer<loopback_connection_client> clb(ll_client, next_line_cb, 150);
if constexpr (display_dbg_msg) std::cout << "Testing legit lines" << std::endl; if constexpr (display_dbg_msg) std::cout << "Testing legit lines" << std::endl;
......
...@@ -10,9 +10,9 @@ namespace rmrf::test { ...@@ -10,9 +10,9 @@ namespace rmrf::test {
/** /**
* Use this class to mock a connection client. * Use this class to mock a connection client.
*/ */
class loopback_connection_client : public rmrf::net::connection_client { class loopback_connection_client : public rmrf::net::connection_client<loopback_connection_client> {
private: private:
const rmrf::net::connection_client::incomming_data_cb send_data_cb; const incomming_data_cb send_data_cb;
std::vector<std::string> data_archive; std::vector<std::string> data_archive;
const bool echo_data_transfer; const bool echo_data_transfer;
...@@ -22,10 +22,10 @@ public: ...@@ -22,10 +22,10 @@ public:
* send data. * send data.
*/ */
loopback_connection_client( loopback_connection_client(
rmrf::net::connection_client::incomming_data_cb send_data_cb_, const incomming_data_cb& send_data_cb_,
bool echo_data bool echo_data
) : ) :
rmrf::net::connection_client{}, rmrf::net::connection_client<loopback_connection_client>{},
send_data_cb(send_data_cb_), send_data_cb(send_data_cb_),
data_archive{}, data_archive{},
echo_data_transfer(echo_data) echo_data_transfer(echo_data)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment