Added vscode

This commit is contained in:
Brad Arant 2020-11-07 17:28:24 -08:00
parent 177bc602af
commit f652ba1f34
6 changed files with 165 additions and 136 deletions

29
.vscode/c_cpp_properties.json vendored Normal file
View File

@ -0,0 +1,29 @@
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**"
],
"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "gnu17",
"cppStandard": "gnu++14",
"intelliSenseMode": "gcc-x64",
"compileCommands": "./compile"
},
{
"name": "config",
"includePath": [
"${workspaceFolder}/**"
],
"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "gnu17",
"cppStandard": "gnu++17",
"intelliSenseMode": "gcc-x64",
"compileCommands": "./compile"
}
],
"version": 4
}

View File

@ -4,96 +4,96 @@
#include "Exception.h"
namespace core {
EPoll::EPoll() : Command() {
coreutils::Log(coreutils::LOG_DEBUG_2) << "EPoll object being constructed.";
maxSockets = 1000;
epfd = epoll_create1(0);
terminateThreads = false;
epfd = epoll_create1(0);
terminateThreads = false;
}
EPoll::~EPoll() {
coreutils::Log(coreutils::LOG_DEBUG_2) << "BMAEPoll destructed.";
}
bool EPoll::start(int numberOfThreads, int maxSockets) {
coreutils::Log(coreutils::LOG_DEBUG_2) << "Starting epoll event processing.";
this->numberOfThreads = numberOfThreads;
coreutils::Log(coreutils::LOG_DEBUG_3) << "Number of threads starting is " << numberOfThreads << ".";
coreutils::Log(coreutils::LOG_DEBUG_3) << "Maximum connections is " << maxSockets << ".";
// TODO: Set the number of maximum open files to the maxSockets value.
//
//
//----------------------------------------------------------------------
// Create thread objects into vector for number of threads requested.
// Hand all the threads a pointer to the EPoll object so they can run
// the socket handlers.
//----------------------------------------------------------------------
for(int ix = 0; ix < numberOfThreads; ++ix)
for(int ix = 0; ix < numberOfThreads; ++ix)
threads.emplace_back(*this);
for(int ix = 0; ix < numberOfThreads; ++ix)
threads[ix].start();
return true;
return true;
}
bool EPoll::stop() {
terminateThreads = true;
//--------------------------------------------------------
// Kill and join all the threads that have been started.
//--------------------------------------------------------
for(int ix = 0; ix < numberOfThreads; ++ix)
threads[ix].join();
//--------------------------
// Close the epoll socket.
//--------------------------
close(epfd);
return true;
return true;
}
bool EPoll::isStopping() {
return terminateThreads;
}
bool EPoll::registerSocket(Socket *socket) {
coreutils::Log(coreutils::LOG_DEBUG_3) << "Registering socket " << socket->getDescriptor() << ".";
enableSocket(socket);
return true;
}
bool EPoll::unregisterSocket(Socket *socket) {
coreutils::Log(coreutils::LOG_DEBUG_3) << "Unregistering socket " << socket->getDescriptor() << ".";
disableSocket(socket);
return true;
return true;
}
int EPoll::getDescriptor() {
return epfd;
}
int EPoll::processCommand(std::string command, TCPSession *session, std::stringstream &data) {
int sequence = 0;
int sequence = 0;
for(auto threadx : threads) {
data << "|" << ++sequence;
threadx.output(data);
threadx.output(data);
data << "|" << std::endl;
}
}
return 1;
}
void EPoll::enableSocket(Socket *socket) {
coreutils::Log(coreutils::LOG_DEBUG_4) << "Enabling socket " << socket->getDescriptor() << " for events.";
struct epoll_event event;
@ -101,13 +101,13 @@ namespace core {
event.events = EPOLLIN | EPOLLONESHOT | EPOLLRDHUP | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_ADD, socket->getDescriptor(), &event);
}
void EPoll::disableSocket(Socket *socket) {
coreutils::Log(coreutils::LOG_DEBUG_4) << "Disabling socket " << socket->getDescriptor() << " from events.";
epoll_ctl(epfd, EPOLL_CTL_DEL, socket->getDescriptor(), NULL);
}
void EPoll::resetSocket(Socket *socket) {
void EPoll::resetSocket(Socket *socket) {
coreutils::Log(coreutils::LOG_DEBUG_4) << "Resetting socket " << socket->getDescriptor() << " for read.";
struct epoll_event event;
event.data.ptr = socket;

View File

@ -10,17 +10,17 @@ namespace core {
public:
IPAddressList();
std::map<std::string, IPAddress> getList();
void add(IPAddress ipAddress);
bool remove(IPAddress ipAddress);
bool contains(std::string ipAddress);
private:
std::map<std::string, IPAddress> list;
std::map<std::string, IPAddress>::iterator it = list.begin();
std::map<std::string, IPAddress>::iterator it = list.begin();
};
}
#endif

View File

@ -4,23 +4,23 @@
#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(!server.commands.processRequest(data, this, out))
if(data != "")
server.sessionErrorHandler("Invalid data received.", out);
}
void TCPSession::onRegistered() {
onConnected();
protocol();
@ -30,17 +30,17 @@ namespace core {
}
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) {
while(lineBufferSize > 0) {
switch(mode) {
case LINE:
lineLength = strcspn(lineBuffer, "\r\n");
if(lineLength == lineBufferSize)
if(lineLength == lineBufferSize)
break;
onLineReceived(std::string(lineBuffer, lineLength));
if(lineBuffer[lineLength] == '\r')
@ -48,53 +48,59 @@ namespace core {
if(lineBuffer[lineLength] == '\n')
++lineLength;
lineBufferSize -= lineLength;
if(lineBufferSize > 0)
if(lineBufferSize > 0)
memmove(lineBuffer, lineBuffer + lineLength, lineBufferSize);
lineBuffer = (char *)realloc(lineBuffer, lineBufferSize);
break;
lineBuffer = (char *)realloc(lineBuffer, lineBufferSize);
break;
case BLOCK:
if(lineBufferSize >= blockLength) {
if(lineBufferSize >= blockLength) {
onBlockReceived(std::string(lineBuffer, blockLength));
lineBufferSize -= blockLength;
if(lineBufferSize > 0)
if(lineBufferSize > 0)
memmove(lineBuffer, lineBuffer + blockLength, lineBufferSize);
lineBuffer = (char *)realloc(lineBuffer, 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");
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)
for(auto session : server.sessions)
if(session != this)
session->write(out.str());
session->write(out.str());
out.str("");
}
void TCPSession::sendToAll(SessionFilter filter) {
for(auto session : server.sessions)
if(filter.test(*session))
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());
@ -104,5 +110,5 @@ namespace core {
void TCPSession::terminate() {
term = true;
}
}

View File

@ -8,151 +8,144 @@ namespace core {
class Command;
enum Mode {LINE, BLOCK};
class TCPServer;
///
/// TCPSession
///
/// TCPSession defines the nature of the interaction with the client
/// and stores persistent data for a defined session. TCPSession objects
/// are not sockets but instead provide a communications control
/// are not sockets but instead provide a communications control
/// mechanism. Protocol conversations are provided through extensions
/// from this object.
///
///
/// from this object.
///
///
///
class TCPSession : public TCPSocket {
public:
///
///
///
TCPSession(EPoll &ePoll, TCPServer &server, std::string text = "");
///
///
///
~TCPSession();
~TCPSession();
Command *grab = NULL;
virtual void output(std::stringstream &data);
///
/// Use out to send data to the session socket or other session sockets.
///
std::stringstream out;
///
///
/// The send method is used to output the contents of the out stream
/// to the session containing the stream.
///
void send();
///
/// Use this sendToAll method to output the contents of the out stream
/// to all the connections on the server excluding the sender session.
/// to all the connections on the server excluding the sender session.
///
void sendToAll();
///
/// Use this sendToAll method to output the contents of the out stream
/// to all the connections on the server excluding the sender session
/// and the entries identified by the passed in filter object.
///
void sendToAll(SessionFilter filter);
///
/// Use this method to terminate this TCPSession.
/// Use this method to terminate this TCPSession.
///
void terminate();
///
///
///
///
TCPServer &server;
///
/// Set this value to control the next read event coming
/// from this socket.
///
// enum Mode {LINE, BLOCK};
protected:
///
///
///
virtual void onRegistered() override;
virtual void onRegistered() override;
///
/// Override this method to receive data directly from the socket as data is
/// received. If you need data split by line termination characters then
/// override the onLineReceived method instead.
///
virtual void onDataReceived(char *data, int len) override;
virtual void onDataReceived(char *data, int len) override;
///
/// Override the onLineReceived method to receive a string of characters that
/// represents a single line of data terminated by a LF or CRLF. If onDataReceived
/// Override the onLineReceived method to receive a string of characters that
/// represents a single line of data terminated by a LF or CRLF. If onDataReceived
/// was overriden this method will not be called unless the onDataReceived calls
/// this method explicitly using the class and member name.
///
virtual void onLineReceived(std::string line);
virtual void onLineReceived(std::string line);
///
/// Override the onBlockReceived method to receive a string of characters that
/// represents a single block of data of length determined by the block length value. If
/// onDataReceived was overriden this method will not be called unless the onDataReceived
/// Override the onBlockReceived method to receive a string of characters that
/// represents a single block of data of length determined by the block length value. If
/// onDataReceived was overriden this method will not be called unless the onDataReceived
/// calls this method explicitly using the class and member name.
///
virtual void onBlockReceived(std::string block);
virtual void onBlockReceived(std::string block);
///
/// This method is called from within the protocol method when protocol is called
/// on the initial connection where the data is an empty string. Use this method
/// to deliver a message to the connection upon connection.
///
virtual void onConnected();
///
/// Override the protocol method to manage and control the session communications
/// in your inherited session. If you do not override this method then the Session
/// default will process the 'commands' added to the server object using the
/// processRequest method on the session input.
/// default will process the 'commands' added to the server object using the
/// processRequest method on the session input.
///
/// When data is received within the session two modes are available to pass the
/// When data is received within the session two modes are available to pass the
/// data through the protocol method: LINE or BLOCK.
///
virtual void protocol(std::string data);
virtual void protocol(std::string data);
///
/// Use the setMode method to set the receiving mode for the data on this socket.
/// Data can be received in LINE mode, which will receive data from the socket one
/// Use the setMode method to set the receiving mode for the data on this socket.
/// Data can be received in LINE mode, which will receive data from the socket one
/// line at a time, or BLOCK mode where a certain specified data block is received
/// before calling the onBlockReceived method.
///
void setMode(core::Mode mode, int size = 0);
void setMode(core::Mode mode, int size = 0);
private:
char *lineBuffer = NULL;
int lineBufferSize = 0;
@ -162,9 +155,9 @@ namespace core {
bool term = false;
core::Mode mode = LINE;
int blockSize;
};
}
#endif

11
compile
View File

@ -3,17 +3,17 @@
for file in *.cpp
do
filename="${file%.*}"
list="$list $filename.o"
list="$list $filename.o"
echo -n "Compiling $filename..."
g++ -g -c -I../CoreUtils $file
g++ -g -c -I../CoreUtils $file
if [ $? = '0' ]
then
echo "OK"
else
echo "ERROR"
exit -1
fi
fi
done
wait
@ -25,8 +25,9 @@ then
else
echo "ERROR"
exit -1
fi
fi
echo -n "Building library documentation manual..."
doxygen docs/latex/doxygen.sty >/dev/null 2>/dev/null
echo "OK"