X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Console%2FServer.ih;h=d31f7133f4187512a421d5cd23c98e69ae7d846d;hb=feeec0e9cd78825120bd52f9ef4e115d383bf6a8;hp=8355450fd76daf5341bbc91d0e9ba421c3b07d34;hpb=4fc732480d3ba33ac2589caece3b04224e51d32b;p=senf.git diff --git a/Console/Server.ih b/Console/Server.ih index 8355450..d31f713 100644 --- a/Console/Server.ih +++ b/Console/Server.ih @@ -27,88 +27,134 @@ #define IH_Server_ 1 // Custom includes -#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 +#include ///////////////////////////////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(); + std::string::size_type handleInput(std::string const & input, bool incremental=false) 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_; + 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); - friend class Server; + void clientData(senf::ReadHelper::ptr helper); + void showPrompt(); + + std::string tail_; + unsigned promptLen_; + bool promptActive_; }; + /** \brief Internal: Primitive ClientReader implementation + + 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 NoninteractiveClientReader + : public ClientReader + { + public: + NoninteractiveClientReader(Client & client); + + private: + virtual void v_disablePrompt(); + virtual void v_enablePrompt(); + virtual void v_translate(std::string & data); + + void newData(senf::Scheduler::EventId event); + + SchedulerBinding binding_; + std::string buffer_; + }; + }}} ///////////////////////////////ih.e////////////////////////////////////////