From 5d7f8d76b408f45341c86ad7530748f4a68c9e38 Mon Sep 17 00:00:00 2001 From: pk910 Date: Mon, 10 Mar 2014 13:30:09 +0100 Subject: [PATCH] [IOMultiplexerV2] added c++ interface --- .gitignore | 1 + configure.ac | 5 +- src/IOHandler++/.gitignore | 5 + src/IOHandler++/IOHandler.cpp | 32 ++++++ src/IOHandler++/IOHandler.h | 33 ++++++ src/IOHandler++/IOSocket.cpp | 142 ++++++++++++++++++++++++ src/IOHandler++/IOSocket.h | 74 ++++++++++++ src/IOHandler++/Makefile.am | 9 ++ src/IOHandler/IOSockets.h | 13 ++- src/IOHandler_test/Makefile.am | 2 +- src/IOHandler_test/socket++/.gitignore | 7 ++ src/IOHandler_test/socket++/Makefile.am | 8 ++ src/IOHandler_test/socket++/iotest.cpp | 57 ++++++++++ src/IOHandler_test/socket/.gitignore | 4 + src/IOHandler_test/timer/.gitignore | 7 ++ src/Makefile.am | 2 +- 16 files changed, 391 insertions(+), 10 deletions(-) create mode 100644 src/IOHandler++/.gitignore create mode 100644 src/IOHandler++/IOHandler.cpp create mode 100644 src/IOHandler++/IOHandler.h create mode 100644 src/IOHandler++/IOSocket.cpp create mode 100644 src/IOHandler++/IOSocket.h create mode 100644 src/IOHandler++/Makefile.am create mode 100644 src/IOHandler_test/socket++/.gitignore create mode 100644 src/IOHandler_test/socket++/Makefile.am create mode 100644 src/IOHandler_test/socket++/iotest.cpp create mode 100644 src/IOHandler_test/timer/.gitignore diff --git a/.gitignore b/.gitignore index f134593..946fb4a 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ aclocal.m4 config.guess config.h config.h.in +config.h.in~ config.log config.status config.sub diff --git a/configure.ac b/configure.ac index bd831bc..a1a544f 100644 --- a/configure.ac +++ b/configure.ac @@ -5,7 +5,7 @@ AC_INIT([IOMultiplexer], [2.0], [iohandler@pk910.de], [pk910], [http://pk910.de] AC_PREFIX_DEFAULT([~/iotest]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([foreign]) -#AM_SILENT_RULES([yes]) +AM_SILENT_RULES([yes]) AC_CONFIG_HEADERS([config.h]) #LT_INIT([disable-static]) @@ -16,6 +16,7 @@ AC_SUBST(MODULES) # Checks for programs. AC_PROG_AWK AC_PROG_CC +AC_PROG_CXX AC_PROG_INSTALL AC_PROG_MAKE_SET AC_PROG_RANLIB @@ -48,5 +49,5 @@ AC_CHECK_LIB(pthread, pthread_create, [ ]) ]) -AC_CONFIG_FILES([Makefile src/Makefile src/IOHandler/Makefile src/IOHandler_test/Makefile src/IOHandler_test/socket/Makefile src/IOHandler_test/timer/Makefile]) +AC_CONFIG_FILES([Makefile src/Makefile src/IOHandler/Makefile src/IOHandler++/Makefile src/IOHandler_test/Makefile src/IOHandler_test/socket/Makefile src/IOHandler_test/socket++/Makefile src/IOHandler_test/timer/Makefile]) AC_OUTPUT diff --git a/src/IOHandler++/.gitignore b/src/IOHandler++/.gitignore new file mode 100644 index 0000000..95c9342 --- /dev/null +++ b/src/IOHandler++/.gitignore @@ -0,0 +1,5 @@ +.deps +Makefile.in +Makefile +*.o +*.a diff --git a/src/IOHandler++/IOHandler.cpp b/src/IOHandler++/IOHandler.cpp new file mode 100644 index 0000000..33b730c --- /dev/null +++ b/src/IOHandler++/IOHandler.cpp @@ -0,0 +1,32 @@ +/* IOHandler.cpp - IOMultiplexer v2 + * Copyright (C) 2014 Philipp Kreil (pk910) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +extern "C" { + #include "../IOHandler/IOHandler.h" +} +#include "IOHandler.h" + +CIOHandler::CIOHandler() { + iohandler_init(); +} + +void CIOHandler::start() { + iohandler_run(); +} + +void CIOHandler::stop() { + iohandler_stop(); +} diff --git a/src/IOHandler++/IOHandler.h b/src/IOHandler++/IOHandler.h new file mode 100644 index 0000000..fd3ebf7 --- /dev/null +++ b/src/IOHandler++/IOHandler.h @@ -0,0 +1,33 @@ +/* IOHandler.h - IOMultiplexer v2 + * Copyright (C) 2014 Philipp Kreil (pk910) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef _IOHandler_cpp_h +#define _IOHandler_cpp_h + +extern "C" { + #define IOSOCKET_CPP + #include "../IOHandler/IOHandler.h" +} + +class CIOHandler { +public: + CIOHandler(); + + void start(); + void stop(); +}; + +#endif diff --git a/src/IOHandler++/IOSocket.cpp b/src/IOHandler++/IOSocket.cpp new file mode 100644 index 0000000..0662516 --- /dev/null +++ b/src/IOHandler++/IOSocket.cpp @@ -0,0 +1,142 @@ +/* IOSocket.cpp - IOMultiplexer v2 + * Copyright (C) 2014 Philipp Kreil (pk910) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +extern "C" { + #include "../IOHandler/IOSockets.h" +} +#include "IOSocket.h" +#include +#include +#include + +static IOSOCKET_CALLBACK(c_socket_callback) { + CIOSocket *ciosock = (CIOSocket *) event->socket->data; + ciosock->socket_callback(event); +} + +CIOSocket::CIOSocket() { + +} +CIOSocket::CIOSocket(IOSocket *iosocket) { + this->iosocket = iosocket; +} + +int CIOSocket::connect(char *hostname, unsigned int port, int ssl, char *bindhost) { + return this->connect(hostname, port, ssl, bindhost, IOSOCKET_ADDR_IPV6 | IOSOCKET_ADDR_IPV4); +} + +int CIOSocket::connect(char *hostname, unsigned int port, int ssl, char *bindhost, int flags) { + this->iosocket = iosocket_connect_flags(hostname, port, (ssl ? 1 : 0), (bindhost ? bindhost : NULL), c_socket_callback, flags); + if(this->iosocket) { + this->iosocket->data = this; + return 1; + } else + return 0; +} + +int CIOSocket::listen(char *hostname, unsigned int port) { + return this->listen(hostname, port, IOSOCKET_ADDR_IPV6 | IOSOCKET_ADDR_IPV4); +} +int CIOSocket::listen(char *hostname, unsigned int port, int flags) { + this->iosocket = iosocket_listen_flags(hostname, port, c_socket_callback, flags); + if(this->iosocket) { + this->iosocket->data = this; + return 1; + } else + return 0; +} + +int CIOSocket::listen_ssl(char *hostname, unsigned int port, char *certfile, char *keyfile) { + return listen_ssl(hostname, port, certfile, keyfile, IOSOCKET_ADDR_IPV6 | IOSOCKET_ADDR_IPV4); +} +int CIOSocket::listen_ssl(char *hostname, unsigned int port, char *certfile, char *keyfile, int flags) { + this->iosocket = iosocket_listen_ssl_flags(hostname, port, certfile, keyfile, c_socket_callback, flags); + if(this->iosocket) { + this->iosocket->data = this; + return 1; + } else + return 0; +} + +void CIOSocket::write(const char *data, int len) { + iosocket_send(iosocket, data, len); +} +#define IOSOCKET_PRINTF_LEN 2048 +void CIOSocket::writef(const char *format, ...) { + va_list arg_list; + char sendBuf[IOSOCKET_PRINTF_LEN]; + int pos; + sendBuf[0] = '\0'; + va_start(arg_list, format); + pos = vsnprintf(sendBuf, IOSOCKET_PRINTF_LEN - 1, format, arg_list); + va_end(arg_list); + if (pos < 0 || pos > (IOSOCKET_PRINTF_LEN - 1)) pos = IOSOCKET_PRINTF_LEN - 1; + sendBuf[pos] = '\0'; + iosocket_send(iosocket, sendBuf, pos); +} + +void CIOSocket::close() { + iosocket_close(iosocket); +}; + + +void CIOSocket::socket_callback(IOSocketEvent *event) { + switch(event->type) { + case IOSOCKETEVENT_RECV: + if(iosocket->parse_delimiter) + this->recvLine(event->data.recv_str); + else { + IOSocketBuffer *recvbuf = event->data.recv_buf; + int usedlen; + usedlen = this->recvEvent(recvbuf->buffer, recvbuf->bufpos); + if(usedlen == recvbuf->bufpos) { + recvbuf->bufpos = 0; + } else { + memmove(recvbuf->buffer, recvbuf->buffer + usedlen, recvbuf->bufpos - usedlen); + recvbuf->bufpos -= usedlen; + } + } + break; + case IOSOCKETEVENT_CONNECTED: + this->connectedEvent(); + break; + case IOSOCKETEVENT_NOTCONNECTED: + this->notConnectedEvent(event->data.errid); + break; + case IOSOCKETEVENT_CLOSED: + this->closedEvent(event->data.errid); + break; + case IOSOCKETEVENT_ACCEPT: + this->acceptedEvent(new CIOSocket(event->data.accept_socket)); + break; + case IOSOCKETEVENT_DNSFAILED: + this->dnsErrEvent(event->data.recv_str); + break; + } +} + +int CIOSocket::getSSL() { + +} +int CIOSocket::getIPv6() { + +} +int CIOSocket::getConnected() { + +} +int CIOSocket::getListening() { + +} diff --git a/src/IOHandler++/IOSocket.h b/src/IOHandler++/IOSocket.h new file mode 100644 index 0000000..3c886d3 --- /dev/null +++ b/src/IOHandler++/IOSocket.h @@ -0,0 +1,74 @@ +/* IOSocket.h - IOMultiplexer v2 + * Copyright (C) 2014 Philipp Kreil (pk910) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef _IOSocket_cpp_h +#define _IOSocket_cpp_h + +extern "C" { + #define IOSOCKET_CPP + #include "../IOHandler/IOSockets.h" +} +#include +#include + +struct IOSocket; + +class CIOSocket { +public: + CIOSocket(); + + int connect(char *hostname, unsigned int port, int ssl, char *bindhost); + int connect(char *hostname, unsigned int port, int ssl, char *bindhost, int flags); + + int listen(char *hostname, unsigned int port); + int listen(char *hostname, unsigned int port, int flags); + int listen_ssl(char *hostname, unsigned int port, char *certfile, char *keyfile); + int listen_ssl(char *hostname, unsigned int port, char *certfile, char *keyfile, int flags); + + void write(const char *data, int len); + void writef(const char *format, ...); + + CIOSocket accept(); + + void close(); + + + int getSSL(); + int getIPv6(); + int getConnected(); + int getListening(); + + + void socket_callback(IOSocketEvent *event); +protected: + virtual int recvEvent(const char *data, int len) { return len; }; + virtual void recvLine(char *line) {}; + void enableRecvLine(); + void disableRecvLine(); + + virtual void connectedEvent() {}; + virtual void notConnectedEvent(int errid) {}; + virtual void closedEvent(int errid) {}; + virtual void acceptedEvent(CIOSocket *client) { client->close(); }; + virtual void dnsErrEvent(char *errormsg) {}; + +private: + IOSocket *iosocket; + + CIOSocket(IOSocket *iosocket); +}; + +#endif diff --git a/src/IOHandler++/Makefile.am b/src/IOHandler++/Makefile.am new file mode 100644 index 0000000..cb9ced4 --- /dev/null +++ b/src/IOHandler++/Makefile.am @@ -0,0 +1,9 @@ +##Process this file with automake to create Makefile.in +ACLOCAL_AMFLAGS = -I m4 + +noinst_LIBRARIES = libiohandler.cpp.a + +libiohandler_cpp_a_LIBADD = ../IOHandler/libiohandler.a +libiohandler_cpp_a_SOURCES = IOHandler.cpp \ +IOSocket.cpp + diff --git a/src/IOHandler/IOSockets.h b/src/IOHandler/IOSockets.h index f2d01e2..21536fb 100644 --- a/src/IOHandler/IOSockets.h +++ b/src/IOHandler/IOSockets.h @@ -134,7 +134,7 @@ void iosocket_events_callback(struct _IOSocket *iosock, int readable, int writea #define iosocket_wants_reads(IOSOCK) \ (\ ((IOSOCK->socket_flags & (IOSOCKETFLAG_SSL_READHS | IOSOCKETFLAG_SSL_WRITEHS)) && !(IOSOCK->socket_flags & IOSOCKETFLAG_SSL_WANTWRITE)) || \ - (!(IOSOCK->socket_flags & IOSOCKETFLAG_OVERRIDE_WANT_RW) || \ + (!(IOSOCK->socket_flags & IOSOCKETFLAG_OVERRIDE_WANT_RW)) || \ (IOSOCK->socket_flags & (IOSOCKETFLAG_OVERRIDE_WANT_RW | IOSOCKETFLAG_OVERRIDE_WANT_R) == (IOSOCKETFLAG_OVERRIDE_WANT_RW | IOSOCKETFLAG_OVERRIDE_WANT_R)) \ ) #define iosocket_wants_writes(IOSOCK) \ @@ -169,6 +169,11 @@ enum IOSocketEventType { IOSOCKETEVENT_DNSFAILED /* failed to lookup DNS information (recv_str contains error message) */ }; +#define IOSOCKET_ADDR_IPV4 0x01 +#define IOSOCKET_ADDR_IPV6 0x02 /* overrides IOSOCKET_ADDR_IPV4 */ +#define IOSOCKET_PROTO_UDP 0x04 + +#if !defined IOSOCKET_CPP struct IOSocket { void *iosocket; @@ -194,11 +199,6 @@ struct IOSocketEvent { } data; }; - -#define IOSOCKET_ADDR_IPV4 0x01 -#define IOSOCKET_ADDR_IPV6 0x02 /* overrides IOSOCKET_ADDR_IPV4 */ -#define IOSOCKET_PROTO_UDP 0x04 - struct IOSocket *iosocket_connect(const char *hostname, unsigned int port, int ssl, const char *bindhost, iosocket_callback *callback); struct IOSocket *iosocket_connect_flags(const char *hostname, unsigned int port, int ssl, const char *bindhost, iosocket_callback *callback, int flags); struct IOSocket *iosocket_listen(const char *hostname, unsigned int port, iosocket_callback *callback); @@ -211,3 +211,4 @@ void iosocket_printf(struct IOSocket *iosocket, const char *text, ...); void iosocket_close(struct IOSocket *iosocket); #endif +#endif diff --git a/src/IOHandler_test/Makefile.am b/src/IOHandler_test/Makefile.am index 5fc8fac..1f4d5e5 100644 --- a/src/IOHandler_test/Makefile.am +++ b/src/IOHandler_test/Makefile.am @@ -1,3 +1,3 @@ ##Process this file with automake to create Makefile.in ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = socket timer +SUBDIRS = socket socket++ timer diff --git a/src/IOHandler_test/socket++/.gitignore b/src/IOHandler_test/socket++/.gitignore new file mode 100644 index 0000000..7af2f69 --- /dev/null +++ b/src/IOHandler_test/socket++/.gitignore @@ -0,0 +1,7 @@ +.deps +.libs +*.o +*.exe +iotest +Makefile +Makefile.in diff --git a/src/IOHandler_test/socket++/Makefile.am b/src/IOHandler_test/socket++/Makefile.am new file mode 100644 index 0000000..fdf06d3 --- /dev/null +++ b/src/IOHandler_test/socket++/Makefile.am @@ -0,0 +1,8 @@ +##Process this file with automake to create Makefile.in +ACLOCAL_AMFLAGS = -I m4 + +noinst_PROGRAMS = iotest + +iotest_LDADD = ../../IOHandler++/libiohandler.cpp.a \ +../../IOHandler/libiohandler.a +iotest_SOURCES = iotest.cpp diff --git a/src/IOHandler_test/socket++/iotest.cpp b/src/IOHandler_test/socket++/iotest.cpp new file mode 100644 index 0000000..151ce0d --- /dev/null +++ b/src/IOHandler_test/socket++/iotest.cpp @@ -0,0 +1,57 @@ +/* main.c - IOMultiplexer + * Copyright (C) 2012 Philipp Kreil (pk910) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include "../../IOHandler++/IOHandler.h" +#include "../../IOHandler++/IOSocket.h" + +class IOTestSocket : public CIOSocket { +protected: + virtual void connectedEvent() { + printf("[connect]\n"); + this->writef("GET / HTTP/1.1\r\n"); + this->writef("Host: test.pk910.de\r\n"); + this->writef("\r\n"); + }; + virtual void notConnectedEvent(int errid) { + printf("[not connected]\n"); + }; + virtual void closedEvent(int errid) { + printf("[disconnect]\n"); + }; + virtual void acceptedEvent(CIOSocket *client) { + client->close(); + }; + virtual void dnsErrEvent(std::string *errormsg) { + + }; + virtual int recvEvent(const char *data, int len) { + int i; + for(i = 0; i < len; i++) + putchar(data[i]); + return len; + }; +}; + + +int main(int argc, char *argv[]) { + CIOHandler *iohandler = new CIOHandler(); + IOTestSocket *sock = new IOTestSocket(); + sock->connect("test.pk910.de", 443, 1, NULL); + + iohandler->start(); +} diff --git a/src/IOHandler_test/socket/.gitignore b/src/IOHandler_test/socket/.gitignore index d6a00c5..7af2f69 100644 --- a/src/IOHandler_test/socket/.gitignore +++ b/src/IOHandler_test/socket/.gitignore @@ -1,3 +1,7 @@ .deps +.libs *.o +*.exe iotest +Makefile +Makefile.in diff --git a/src/IOHandler_test/timer/.gitignore b/src/IOHandler_test/timer/.gitignore new file mode 100644 index 0000000..7af2f69 --- /dev/null +++ b/src/IOHandler_test/timer/.gitignore @@ -0,0 +1,7 @@ +.deps +.libs +*.o +*.exe +iotest +Makefile +Makefile.in diff --git a/src/Makefile.am b/src/Makefile.am index 58909b1..2f259ff 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,3 +1,3 @@ ##Process this file with automake to create Makefile.in ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = IOHandler IOHandler_test +SUBDIRS = IOHandler IOHandler++ IOHandler_test -- 2.20.1