#include "pch.h"
#include "System/Net/Sockets/TcpListener.h"
#include "System/Net/Sockets/SocketException.h"

namespace DotNetDupe {
    namespace System {
        namespace Net {
            namespace Sockets {

                TcpListener::TcpListener(int port)
                    : m_sIp("0.0.0.0"), m_nPort(port), m_bActive(false) {
                }

                TcpListener::TcpListener(const String& ip, int port)
                    : m_sIp(ip), m_nPort(port), m_bActive(false) {
                }

                TcpListener::~TcpListener() {
                    Stop();
                }

                TcpListener::TcpListener(TcpListener&& other) noexcept
                    : m_sIp(std::move(other.m_sIp)),
                      m_nPort(other.m_nPort),
                      m_pListenerSocket(std::move(other.m_pListenerSocket)),
                      m_bActive(other.m_bActive) {
                    other.m_bActive = false;
                }

                TcpListener& TcpListener::operator=(TcpListener&& other) noexcept {
                    if (this != &other) {
                        Stop();
                        m_sIp = std::move(other.m_sIp);
                        m_nPort = other.m_nPort;
                        m_pListenerSocket = std::move(other.m_pListenerSocket);
                        m_bActive = other.m_bActive;
                        other.m_bActive = false;
                    }
                    return *this;
                }

                void TcpListener::Start() {
                    Start(100);
                }

                void TcpListener::Start(int backlog) {
                    if (m_bActive) return;

                    m_pListenerSocket.Attach(new Socket(AddressFamily::InterNetwork, SocketType::Stream, ProtocolType::Tcp), true);
                    m_pListenerSocket->Bind(m_sIp, m_nPort);
                    m_pListenerSocket->Listen(backlog);
                    m_bActive = true;
                }

                void TcpListener::Stop() {
                    if (m_bActive) {
                        m_bActive = false;
                        if (!m_pListenerSocket.IsNull()) {
                            m_pListenerSocket->Close();
                        }
                    }
                }

                SmartPointer<TcpClient> TcpListener::AcceptTcpClient() {
                    if (!m_bActive || m_pListenerSocket.IsNull()) {
                        throw SocketException(-1, String("TcpListener is not started."));
                    }
                    SmartPointer<Socket> pListenerSocket = m_pListenerSocket;
                    SmartPointer<Socket> pClientSocket = pListenerSocket->Accept();
                    return SmartPointer<TcpClient>(new TcpClient(pClientSocket));
                }

                SmartPointer<Socket> TcpListener::AcceptSocket() {
                    if (!m_bActive || m_pListenerSocket.IsNull()) {
                        throw SocketException(-1, String("TcpListener is not started."));
                    }
                    SmartPointer<Socket> pListenerSocket = m_pListenerSocket;
                    return pListenerSocket->Accept();
                }

                bool TcpListener::Pending() {
                    if (!m_bActive || m_pListenerSocket.IsNull()) {
                        return false;
                    }
                    return m_pListenerSocket->Poll(0, SelectMode::SelectRead);
                }

            }
        }
    }
}

Generated by OpenCppCoverage (Version: 0.9.9.0)