diff options
-rw-r--r-- | Limber/.gitignore | 1 | ||||
-rw-r--r-- | Limber/Makefile.inc | 3 | ||||
-rw-r--r-- | Limber/main.cpp | 134 |
3 files changed, 135 insertions, 3 deletions
diff --git a/Limber/.gitignore b/Limber/.gitignore new file mode 100644 index 0000000..6c52f38 --- /dev/null +++ b/Limber/.gitignore @@ -0,0 +1 @@ +limber diff --git a/Limber/Makefile.inc b/Limber/Makefile.inc index 1214311..a77bd5f 100644 --- a/Limber/Makefile.inc +++ b/Limber/Makefile.inc @@ -7,7 +7,8 @@ LIMBER_OBJECTS = \ .PHONY: limber limber: $(LIMBER_TARGET) -$(LIMBER_TARGET): $(LIMBER_OBJECTS) +$(LIMBER_TARGET): $(SWIFTEN_TARGET) $(LIMBER_OBJECTS) + $(QUIET_LINK)$(CXX) -o $(LIMBER_TARGET) $(LIMBER_OBJECTS) $(LDFLAGS) $(SWIFTEN_TARGET) $(LIBS) TARGETS += $(LIMBER_TARGET) CLEANFILES += $(LIMBER_OBJECTS) diff --git a/Limber/main.cpp b/Limber/main.cpp index 8a3b3be..bc061e5 100644 --- a/Limber/main.cpp +++ b/Limber/main.cpp @@ -1,3 +1,133 @@ -int main(int argc, char* argv[]) { - return 0; + +#include <iostream> +#include <string> +#include <boost/asio.hpp> +#include <boost/signal.hpp> +#include <boost/bind.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/enable_shared_from_this.hpp> +#include <boost/thread.hpp> + +#include "Swiften/Base/ByteArray.h" +#include "Swiften/EventLoop/MainEventLoop.h" +#include "Swiften/EventLoop/SimpleEventLoop.h" + +using namespace Swift; + +// A reference-counted non-modifiable buffer class. +class SharedBuffer { + public: + SharedBuffer(const ByteArray& data) : + data_(new std::vector<char>(data.begin(), data.end())), + buffer_(boost::asio::buffer(*data_)) { + } + + // ConstBufferSequence requirements. + typedef boost::asio::const_buffer value_type; + typedef const boost::asio::const_buffer* const_iterator; + const boost::asio::const_buffer* begin() const { return &buffer_; } + const boost::asio::const_buffer* end() const { return &buffer_ + 1; } + + private: + boost::shared_ptr< std::vector<char> > data_; + boost::asio::const_buffer buffer_; +}; + +class IncomingBoostConnection : public boost::enable_shared_from_this<IncomingBoostConnection> { + public: + typedef boost::shared_ptr<IncomingBoostConnection> pointer; + + static pointer create(boost::asio::io_service& ioService) { + return pointer(new IncomingBoostConnection(ioService)); + } + + boost::asio::ip::tcp::socket& getSocket() { + return socket_; + } + + void write(const ByteArray& data) { + boost::asio::async_write(socket_, SharedBuffer(data), + boost::bind( + &IncomingBoostConnection::handleDataWritten, + shared_from_this(), + boost::asio::placeholders::error)); + } + + private: + IncomingBoostConnection(boost::asio::io_service& ioService) : socket_(ioService) { + } + + void handleDataWritten(const boost::system::error_code& error) { + if (error) { + std::cerr << "ERROR: Unable to write data to socket" << std::endl; + } + } + + boost::asio::ip::tcp::socket socket_; + std::string message_; +}; + +class BoostIOServiceThread { + public: + BoostIOServiceThread() : thread_(boost::bind(&BoostIOServiceThread::doRun, this)) { + } + + ~BoostIOServiceThread() { + ioService_.stop(); + thread_.join(); + } + + boost::asio::io_service& getIOService() { + return ioService_; + } + + private: + void doRun() { + boost::asio::io_service::work work(ioService_); + ioService_.run(); + } + + private: + boost::asio::io_service ioService_; + boost::thread thread_; +}; + +class BoostConnectionServer { + public: + BoostConnectionServer(int port, boost::asio::io_service& ioService) : acceptor_(ioService, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)) { + acceptNextConnection(); + } + + boost::signal<void (IncomingBoostConnection::pointer)> onNewConnection; + + private: + // Called from Asio thread + void acceptNextConnection() { + IncomingBoostConnection::pointer newConnection = IncomingBoostConnection::create(acceptor_.io_service()); + acceptor_.async_accept(newConnection->getSocket(), + boost::bind(&BoostConnectionServer::handleAccept, this, newConnection, boost::asio::placeholders::error)); + } + + // Called from Asio thread + void handleAccept(IncomingBoostConnection::pointer newConnection, const boost::system::error_code& error) { + if (!error) { + MainEventLoop::postEvent(boost::bind(boost::ref(onNewConnection), newConnection), this); + acceptNextConnection(); + } + } + + boost::asio::ip::tcp::acceptor acceptor_; +}; + +void doSomething(IncomingBoostConnection::pointer c) { + c->write("Hello\n"); +} + +int main() { + SimpleEventLoop eventLoop; + BoostIOServiceThread boostIOServiceThread; + BoostConnectionServer server(5222, boostIOServiceThread.getIOService()); + server.onNewConnection.connect(boost::bind(doSomething, _1)); + eventLoop.run(); + return 0; } |