#include "TCPSession.h" #include "TCPServer.h" #include "Log.h" #include "PString.h" namespace core { TCPSession::TCPSession(EPoll &ePoll, TCPServer &server, std::string text) : TCPSocket(ePoll, text), server(server) {} TCPSession::~TCPSession() { server.removeFromSessionList(this); } void TCPSession::output(std::stringstream &data) { data << "|" << ipAddress.getClientAddressAndPort(); } void TCPSession::protocol(std::string data = "") { if(!server.commands.processRequest(data, this, out)) if(data != "") server.sessionErrorHandler("Invalid data received.", out); } void TCPSession::onRegistered() { onConnected(); protocol(); send(); if(term) shutdown("termination requested"); } void TCPSession::onConnected() {} void TCPSession::onDataReceived(char *data, int len) { if(len > 0) { lineBuffer = (char *)realloc(lineBuffer, lineBufferSize + len); memcpy(lineBuffer + lineBufferSize, data, len); lineBufferSize += len; while(lineBufferSize > 0) { switch(mode) { case LINE: lineLength = strcspn(lineBuffer, "\r\n"); if(lineLength == lineBufferSize) break; onLineReceived(std::string(lineBuffer, lineLength)); if(lineBuffer[lineLength] == '\r') ++lineLength; if(lineBuffer[lineLength] == '\n') ++lineLength; lineBufferSize -= lineLength; if(lineBufferSize > 0) memmove(lineBuffer, lineBuffer + lineLength, lineBufferSize); lineBuffer = (char *)realloc(lineBuffer, lineBufferSize); break; case BLOCK: if(lineBufferSize >= blockLength) { onBlockReceived(std::string(lineBuffer, blockLength)); lineBufferSize -= blockLength; if(lineBufferSize > 0) memmove(lineBuffer, lineBuffer + blockLength, lineBufferSize); lineBuffer = (char *)realloc(lineBuffer, lineBufferSize); } break; } } } } void TCPSession::setMode(core::Mode mode, int blockSize) { this->mode = mode; this->blockSize = blockSize; } void TCPSession::onLineReceived(std::string line) { coreutils::Log(coreutils::LOG_DEBUG_3) << "[" << line << "]"; protocol(line); send(); if(term) shutdown("termination requested"); } void TCPSession::onBlockReceived(std::string block) { coreutils::Log(coreutils::LOG_DEBUG_3) << "[" << block.length() << "]"; if(term) shutdown("termination requested"); } void TCPSession::sendToAll() { for(auto session : server.sessions) if(session != this) session->write(out.str()); out.str(""); } void TCPSession::sendToAll(SessionFilter filter) { for(auto session : server.sessions) if(filter.test(*session)) if(session != this) session->write(out.str()); out.str(""); } void TCPSession::send() { if(out.tellp() > 0) write(out.str()); out.str(""); } void TCPSession::terminate() { term = true; } }