Socket: Documentation for new addressing classes
[senf.git] / Console / Server.ih
index de12c41..925fd64 100644 (file)
@@ -29,6 +29,7 @@
 // Custom includes
 #include <boost/iostreams/concepts.hpp>
 #include <boost/iostreams/stream.hpp>
+#include <set>
 
 ///////////////////////////////ih.p////////////////////////////////////////
 
@@ -40,9 +41,29 @@ namespace console {
 
 namespace detail {
 
+    class ServerManager
+        : public senf::singleton<ServerManager>
+    {
+    public:
+        typedef boost::intrusive_ptr<Server> ptr;
+
+    protected:
+
+    private:
+        static void add(ptr server);
+        static void remove(ptr server);
+
+        typedef std::set<ptr> Servers;
+        Servers servers_;
+
+        friend class senf::console::Server;
+    };
+
     /** \brief Internal: Nonblocking boost::iostreams::sink
 
         The sink discards data if the output socket would.
+
+        \fixme Don't throw exceptions ... set stream error indicator (if at all)
      */
     class NonblockingSocketSink 
         : public boost::iostreams::sink
@@ -53,11 +74,13 @@ namespace detail {
                              WriteablePolicy,
                              ConnectedCommunicationPolicy>::policy > Handle;
 
-        NonblockingSocketSink(Handle handle);
+        NonblockingSocketSink(Client & client);
         std::streamsize write(const char * s, std::streamsize n);
+
+        Client & client() const;
         
     private:
-        Handle handle_;
+        Client & client_;
     };
 
     typedef boost::iostreams::stream<NonblockingSocketSink> NonblockingSocketOStream;
@@ -75,20 +98,26 @@ namespace detail {
     {
     public:
         typedef ServerHandle::ClientSocketHandle ClientHandle;
-        typedef NonblockingSocketOStream OutputStream;
 
         virtual ~ClientReader() = 0;
 
+        // Called by subclasses to get information from the Client
+
         Client & client() const;
         std::string promptString() const;
         ClientHandle handle() const;
-        OutputStream & stream() const;
+        std::ostream & stream() const;
+
+        // Called by subclasses to perform actions in the Client
+
         void stopClient();
-        
-        void handleInput(std::string const & input) const;
+        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);
@@ -96,6 +125,7 @@ namespace detail {
     private:
         virtual void v_disablePrompt() = 0;
         virtual void v_enablePrompt() = 0;
+        virtual void v_translate(std::string & data) = 0;
 
         Client & client_;
     };
@@ -114,6 +144,7 @@ namespace detail {
     private:
         virtual void v_disablePrompt();
         virtual void v_enablePrompt();
+        virtual void v_translate(std::string & data);
 
         void clientData(senf::ReadHelper<ClientHandle>::ptr helper);
         void showPrompt();
@@ -122,6 +153,28 @@ namespace detail {
         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_;
+    };
     
 }}}