Program Listing for File NetioReceiver.cpp

Return to documentation for file (NetioReceiver.cpp)

#include "netio3/NetioReceiver.hpp"

#include <stdexcept>
#include <memory>
#include <utility>

#include <netio3-backend/EventLoop/BaseEventLoop.hpp>
#include <netio3-backend/Netio3Backend.hpp>

#include "netio3/BufferFormatter.hpp"

using namespace netio3;

NetioReceiver::NetioReceiver(const NetioReceiverConfig& config,
                             std::shared_ptr<BaseEventLoop> evloop) :
    m_backend_type{config.backend_type},
    m_backend(NetworkBackend::create(
                  m_backend_type,
                  {
                      .mode=config.backend_mode,
                      .thread_safety = config.thread_safety,
                      .callbacks{
                        .on_data_cb = [this] (std::span<const uint8_t> data){
                            on_data(data);},
                        .on_connection_established_cb = [this] (
                            const EndPointAddress& ep, const EndPointAddress&, EndpointCapabilities) {
                            connection_established(ep);},
                        .on_connection_closed_cb = [this] (
                            const EndPointAddress& ep, const std::vector<std::uint64_t>& /* keys */) {connection_closed(ep);}
                        }
                  },
                  evloop)) {
    ERS_DEBUG(5, "Entered");
}

NetioReceiver::~NetioReceiver() {
    ERS_DEBUG(5, "Entered "
           << " now have " << m_listeners.size() << " listeners");
    for (auto con : m_listeners) {
        ERS_DEBUG(1, "Closing handle: " << con << "");
        try {
            m_backend->close_listen_endpoint(con);
        }
        catch(const std::invalid_argument& exc) {
            continue;
        }
    }
    ERS_DEBUG(5, "Finished");
}

unsigned short NetioReceiver::listen(const EndPointAddress& ep, const ConnectionParametersRecv& conn_params) {
    auto epaddr = m_backend->open_listen_endpoint(ep, {.recv_params{conn_params}});
    m_listeners.insert(epaddr);
    ERS_DEBUG(6, " now have " << m_listeners.size() << " listeners");

    return epaddr.port();
}

void NetioReceiver::close(const EndPointAddress& ep) {
    m_backend->close_listen_endpoint(ep);
    m_listeners.erase(ep);
    ERS_DEBUG(6, " now have " << m_listeners.size() << " listeners");
}

void NetioReceiver::on_data(std::span<const uint8_t> data) {
    ERS_DEBUG(6, " Recieved data of size " << data.size());
    if (m_on_buffer_cb) {
        m_on_buffer_cb(data);
    }
    if (m_on_data_cb) {
        BufferFormatter::decode(data, m_on_data_cb);
    }
}

void NetioReceiver::connection_established(const EndPointAddress& ep) {
    m_on_connection_established_cb(ep);
}
void NetioReceiver::connection_closed(const EndPointAddress& ep) {
    m_on_connection_closed_cb(ep);
}

void NetioReceiver::set_on_data_cb (CbMessageReceived cb) {
    m_on_data_cb = std::move(cb);
}

void NetioReceiver::set_on_buffer_cb (CbBufferReceived cb) {
    m_on_buffer_cb = std::move(cb);
}

void NetioReceiver::set_on_connection_established_cb (OnConnectionEstablishedSimpleCb cb) {
    m_on_connection_established_cb = std::move(cb);
}
void NetioReceiver::set_on_connection_closed_cb (OnConnectionClosedCb cb) {
    m_on_connection_closed_cb = std::move(cb);
}