###########################################################################
-sources = SENFSCons.GlobSources()
+sources = SENFSCons.GlobSources( exclude = [ 'testServer.cc' ] )
SENFSCons.StandardTargets(env)
+
SENFSCons.Lib(env,
library = 'Console',
sources = sources,
LIBS = [ 'Socket', 'Scheduler', 'Utils' ])
+
+SENFSCons.Binary(env, 'testServer',
+ sources = [ 'testServer.cc' ],
+ no_includes = True,
+ LIBS = [ 'Console', 'Socket', 'Scheduler', 'Utils' ])
+
SENFSCons.Doxygen(env)
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2008
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+// Stefan Bund <g0dil@berlios.de>
+//
+// 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 2 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, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+/** \file
+ \brief Server non-inline non-template implementation */
+
+#include "Server.hh"
+#include "Server.ih"
+
+// Custom includes
+#include <boost/algorithm/string/trim.hpp>
+#include "../Utils/senfassert.hh"
+#include "../Utils/membind.hh"
+#include "../Utils/Logger/SenfLog.hh"
+
+//#include "Server.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+prefix_ void senf::console::start(senf::INet4SocketAddress const & address)
+{
+ senf::console::detail::Server::start(senf::TCPv4ServerSocketHandle(address));
+ SENF_LOG((detail::Server::SENFLogArea)(log::NOTICE)(
+ "Console server started at " << address ));
+}
+
+prefix_ void senf::console::start(senf::INet6SocketAddress const & address)
+{
+ senf::console::detail::Server::start(senf::TCPv6ServerSocketHandle(address));
+ SENF_LOG((detail::Server::SENFLogArea)(log::NOTICE)(
+ "Console server started at " << address ));
+}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::console::detail::Server
+
+boost::scoped_ptr<senf::console::detail::Server> senf::console::detail::Server::instance_;
+
+prefix_ void senf::console::detail::Server::start(ServerHandle handle)
+{
+ SENF_ASSERT( ! instance_ );
+ instance_.reset(new Server(handle));
+}
+
+prefix_ senf::console::detail::Server::Server(ServerHandle handle)
+ : handle_ (handle)
+{
+ Scheduler::instance().add( handle_, senf::membind(&Server::newClient, this) );
+}
+
+prefix_ senf::console::detail::Server::~Server()
+{
+ Scheduler::instance().remove(handle_);
+}
+
+prefix_ void senf::console::detail::Server::newClient(Scheduler::EventId event)
+{
+ ServerHandle::ClientSocketHandle client (handle_.accept());
+ boost::intrusive_ptr<Client> p (new Client(client));
+ clients_.insert( p );
+ SENF_LOG(( "Registered new client " << p.get() ));
+}
+
+prefix_ void senf::console::detail::Server::removeClient(Client & client)
+{
+ SENF_LOG(( "Disposing client " << & client ));
+ // THIS DELETES THE CLIENT INSTANCE !!
+ clients_.erase(boost::intrusive_ptr<Client>(&client));
+}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::console::detail::Client
+
+prefix_ senf::console::detail::Client::Client(ClientHandle handle)
+ : handle_ (handle)
+{
+ ReadHelper<ClientHandle>::dispatch( handle_, 16384u, ReadUntil("\n"),
+ senf::membind(&Client::clientData, this) );
+}
+
+prefix_ senf::console::detail::Client::~Client()
+{}
+
+prefix_ void senf::console::detail::Client::stopClient()
+{
+ // THIS COMMITS SUICIDE. THE INSTANCE IS GONE AFTER removeClient RETURNS
+ Server::instance_->removeClient(*this);
+}
+
+prefix_ void senf::console::detail::Client::clientData(ReadHelper<ClientHandle>::ptr helper)
+{
+ if (helper->error() || handle_.eof()) {
+ // THIS COMMITS SUICIDE. THE INSTANCE IS GONE AFTER stopClient RETURNS
+ stopClient();
+ return;
+ }
+
+ std::string data (tail_ + helper->data());
+ tail_ = helper->tail();
+ boost::trim(data); // Gets rid of superfluous \r or \n characters
+
+ SENF_LOG(( this << ": " << data ));
+ ReadHelper<ClientHandle>::dispatch( handle_, 16384u, ReadUntil("\n"),
+ senf::membind(&Client::clientData, this) );
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "Server.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2008
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+// Stefan Bund <g0dil@berlios.de>
+//
+// 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 2 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, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+/** \file
+ \brief Server public header */
+
+#ifndef HH_Server_
+#define HH_Server_ 1
+
+// Custom includes
+#include "../Socket/Protocols/INet/INetAddressing.hh"
+
+//#include "Server.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace senf {
+namespace console {
+
+ void start(senf::INet4SocketAddress const & address);
+ void start(senf::INet6SocketAddress const & address);
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "Server.cci"
+//#include "Server.ct"
+//#include "Server.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2008
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+// Stefan Bund <g0dil@berlios.de>
+//
+// 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 2 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, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+/** \file
+ \brief Server internal header */
+
+#ifndef IH_Server_
+#define IH_Server_ 1
+
+// Custom includes
+#include <set>
+#include <boost/utility.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/shared_ptr.hpp>
+#include "../Utils/intrusive_refcount.hh"
+#include "../Socket/Protocols/INet/TCPSocketHandle.hh"
+#include "../Socket/ServerSocketHandle.hh"
+#include "../Scheduler/Scheduler.hh"
+#include "../Scheduler/ReadHelper.hh"
+
+///////////////////////////////ih.p////////////////////////////////////////
+
+namespace senf {
+namespace console {
+namespace detail {
+
+ class Client;
+
+ /** \brief
+ */
+ class Server
+ : boost::noncopyable
+ {
+ SENF_LOG_CLASS_AREA();
+ SENF_LOG_DEFAULT_LEVEL( senf::log::NOTICE );
+ public:
+ ///////////////////////////////////////////////////////////////////////////
+ // Types
+
+ typedef senf::ServerSocketHandle<
+ senf::MakeSocketPolicy< senf::TCPv4SocketProtocol::Policy,
+ senf::UnspecifiedAddressingPolicy>::policy > ServerHandle;
+
+ ~Server();
+
+ static void start(ServerHandle handle);
+
+ protected:
+
+ private:
+ Server(ServerHandle handle);
+
+ void newClient(Scheduler::EventId event);
+ void removeClient(Client & client);
+
+ ServerHandle handle_;
+
+ typedef std::set< boost::intrusive_ptr<Client> > Clients;
+ Clients clients_;
+
+ static boost::scoped_ptr<Server> instance_;
+
+ friend class Client;
+ };
+
+ /** \brief
+ */
+ class Client
+ : public senf::intrusive_refcount
+ {
+ SENF_LOG_CLASS_AREA();
+ SENF_LOG_DEFAULT_LEVEL( senf::log::NOTICE );
+ public:
+ typedef Server::ServerHandle::ClientSocketHandle ClientHandle;
+
+ ~Client();
+
+ void stopClient();
+
+ protected:
+
+ private:
+ Client(ClientHandle handle);
+
+ void clientData(ReadHelper<ClientHandle>::ptr helper);
+
+ ClientHandle handle_;
+ std::string tail_;
+
+ friend class Server;
+ };
+
+}}}
+
+///////////////////////////////ih.e////////////////////////////////////////
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2008
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+// Stefan Bund <g0dil@berlios.de>
+//
+// 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 2 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, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+/** \file
+ \brief Server.test unit tests */
+
+//#include "Server.test.hh"
+//#include "Server.test.ih"
+
+// Custom includes
+#include "Server.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+BOOST_AUTO_UNIT_TEST(server)
+{}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2008
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+// Stefan Bund <g0dil@berlios.de>
+//
+// 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 2 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, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+/** \file
+ \brief test non-inline non-template implementation */
+
+//#include "test.hh"
+//#include "test.ih"
+
+// Custom includes
+#include <iostream>
+#include "Server.hh"
+#include "../Scheduler/Scheduler.hh"
+#include "../Utils/Logger/SenfLog.hh"
+
+//#include "test.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+int main(int, char const **)
+{
+ senf::log::ConsoleTarget::instance().route< senf::SenfLog, senf::log::NOTICE >();
+
+ senf::console::start( senf::INet4SocketAddress("127.0.0.1:23232") );
+
+ senf::Scheduler::instance().process();
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "test.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -U testServer"
+// End:
// scheduler. This ensures, that the refcount is at least 1 as
// long as the helper is registered with the scheduler.
senf::Scheduler::instance()
- .add(handle,boost::bind(&ReadHelper::dispatchProcess,ptr(this),_1,_2),
+ .add(handle,boost::bind(&ReadHelper::dispatchProcess,ptr(this), handle, _1),
senf::Scheduler::EV_READ);
}