X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Console%2FServer.ih;h=6bbaf5a4d5c0e475bb8372a8fe01dc3193094ad5;hb=456ee576285b76aa46240f8001f426757810dcc1;hp=d25aed3601cef3701573532cc5cc137bd99e2f54;hpb=826e50343096b75247521f6593cb78eb8c01615b;p=senf.git diff --git a/Console/Server.ih b/Console/Server.ih index d25aed3..6bbaf5a 100644 --- a/Console/Server.ih +++ b/Console/Server.ih @@ -27,97 +27,112 @@ #define IH_Server_ 1 // Custom includes -#include -#include -#include -#include -#include +#include #include -#include "../Utils/intrusive_refcount.hh" -#include "../Socket/Protocols/INet/TCPSocketHandle.hh" -#include "../Socket/ServerSocketHandle.hh" -#include "../Scheduler/Scheduler.hh" -#include "../Scheduler/ReadHelper.hh" -#include "Parse.hh" -#include "Executor.hh" ///////////////////////////////ih.p//////////////////////////////////////// namespace senf { namespace console { -namespace detail { + class Server; class Client; - /** \brief - */ - class Server - : boost::noncopyable +namespace detail { + + /** \brief Internal: Nonblocking boost::iostreams::sink + + The sink discards data if the output socket would. + */ + class NonblockingSocketSink + : public boost::iostreams::sink { - SENF_LOG_CLASS_AREA(); - SENF_LOG_DEFAULT_LEVEL( senf::log::NOTICE ); public: - /////////////////////////////////////////////////////////////////////////// - // Types + typedef ClientSocketHandle< + MakeSocketPolicy::policy > Handle; - typedef senf::ServerSocketHandle< - senf::MakeSocketPolicy< senf::TCPv4SocketProtocol::Policy, - senf::UnspecifiedAddressingPolicy>::policy > ServerHandle; + NonblockingSocketSink(Client & client); + std::streamsize write(const char * s, std::streamsize n); - ~Server(); + Client & client() const; + + private: + Client & client_; + }; - static void start(ServerHandle handle); + typedef boost::iostreams::stream NonblockingSocketOStream; - protected: + typedef senf::ServerSocketHandle< + senf::MakeSocketPolicy< senf::TCPv4SocketProtocol::Policy, + senf::UnspecifiedAddressingPolicy>::policy > ServerHandle; - private: - Server(ServerHandle handle); + /** \brief Internal: Generic client interface - void newClient(Scheduler::EventId event); - void removeClient(Client & client); - - ServerHandle handle_; - - typedef std::set< boost::intrusive_ptr > Clients; - Clients clients_; - - static boost::scoped_ptr instance_; - - friend class Client; - }; - - /** \brief + The ClientReader encapsulates the interaction of a single network client with the user: It + manages prompt display and reading an interactive command. */ - class Client - : public senf::intrusive_refcount + class ClientReader { - SENF_LOG_CLASS_AREA(); - SENF_LOG_DEFAULT_LEVEL( senf::log::NOTICE ); public: - typedef Server::ServerHandle::ClientSocketHandle ClientHandle; + typedef ServerHandle::ClientSocketHandle ClientHandle; + + virtual ~ClientReader() = 0; - ~Client(); + // Called by subclasses to get information from the Client + + Client & client() const; + std::string promptString() const; + ClientHandle handle() const; + std::ostream & stream() const; + + // Called by subclasses to perform actions in the Client void stopClient(); + void handleInput(std::string const & input) const; + + // Called by the Client + + void disablePrompt(); + void enablePrompt(); + void translate(std::string & data); protected: - + ClientReader(Client & client); + private: - Client(ClientHandle handle); + virtual void v_disablePrompt() = 0; + virtual void v_enablePrompt() = 0; + virtual void v_translate(std::string & data) = 0; + + Client & client_; + }; - void clientData(ReadHelper::ptr helper); + /** \brief Internal: Primitive ClientReader implementation - ClientHandle handle_; - std::string tail_; - SingleCommandParser parser_; - Executor executor_; + This implementation uses the cooked telnet mode to read lines from the console. It does not + support explicit line editing or any other advanced features. + */ + class DumbClientReader + : public ClientReader + { + public: + DumbClientReader(Client & client); + + private: + virtual void v_disablePrompt(); + virtual void v_enablePrompt(); + virtual void v_translate(std::string & data); - typedef boost::iostreams::stream fdostream; - fdostream out_; + void clientData(senf::ReadHelper::ptr helper); + void showPrompt(); - friend class Server; + std::string tail_; + unsigned promptLen_; + bool promptActive_; }; - + }}} ///////////////////////////////ih.e////////////////////////////////////////