75fb060f54fdb282fb01fb7f7547c8846ed1a2f3
[senf.git] / senf / Utils / Console / Server.ih
1 // $Id$
2 //
3 // Copyright (C) 2008
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief Server internal header */
25
26 #ifndef IH_SENF_Scheduler_Console_Server_
27 #define IH_SENF_Scheduler_Console_Server_ 1
28
29 // Custom includes
30 #include <boost/iostreams/concepts.hpp>
31 #include <boost/iostreams/stream.hpp>
32 #include <senf/Scheduler/ReadHelper.hh>
33 #include <senf/Socket/Protocols/INet/TCPSocketHandle.hh>
34 #include <senf/Utils/Logger/SenfLog.hh>
35
36 //-/////////////////////////////////////////////////////////////////////////////////////////////////
37
38 namespace senf {
39 namespace console {
40
41     class Server;
42     class Client;
43
44 namespace detail {
45
46     class ServerManager
47     {
48     public:
49         typedef boost::intrusive_ptr<Server> ptr;
50
51     protected:
52
53     private:
54         static void add(ptr server);
55         static void remove(ptr server);
56
57         static ServerManager & instance();
58
59         typedef std::set<ptr> Servers;
60         Servers servers_;
61
62         friend class senf::console::Server;
63     };
64
65     /** \brief Internal: Nonblocking boost::iostreams::sink
66
67         The sink discards data if the output socket would.
68
69         \fixme Don't throw exceptions ... set stream error indicator (if at all)
70      */
71     class NonblockingSocketSink
72         : public boost::iostreams::sink
73     {
74     public:
75         NonblockingSocketSink(Client & client);
76         std::streamsize write(const char * s, std::streamsize n);
77
78         Client & client() const;
79
80     private:
81         Client & client_;
82     };
83
84     typedef boost::iostreams::stream<NonblockingSocketSink> NonblockingSocketOStream;
85
86     typedef senf::ServerSocketHandle<
87         senf::MakeSocketPolicy< senf::TCPv4SocketProtocol::Policy,
88                                 senf::BSDAddressingPolicy>::policy > ServerHandle;
89
90     /** \brief Internal: Generic client interface
91
92         The ClientReader encapsulates the interaction of a single network client with the user: It
93         manages prompt display and reading an interactive command.
94      */
95     class ClientReader
96     {
97     public:
98         SENF_LOG_CLASS_AREA();
99
100         typedef ServerHandle::ClientHandle ClientHandle;
101
102         virtual ~ClientReader() = 0;
103
104         // Called by subclasses to get information from the Client
105
106         Client & client() const;
107         std::string promptString() const;
108         ClientHandle handle() const;
109         std::ostream & stream() const;
110
111         // Called by subclasses to perform actions in the Client
112
113         void stopClient();
114         std::string::size_type handleInput(std::string const & input, bool incremental=false) const;
115
116         // Called by the Client
117
118         void disablePrompt();
119         void enablePrompt();
120         void write(std::string const & data);
121         unsigned width() const;
122
123     protected:
124         ClientReader(Client & client);
125
126     private:
127         virtual void v_disablePrompt() = 0;
128         virtual void v_enablePrompt() = 0;
129         virtual void v_write(std::string const & data) = 0;
130         virtual unsigned v_width() const = 0;
131
132         Client & client_;
133     };
134
135     /** \brief Internal: Primitive ClientReader implementation
136
137         This implementation uses the cooked telnet mode to read lines from the console. It does not
138         support explicit line editing or any other advanced features.
139      */
140     class DumbClientReader
141         : public ClientReader
142     {
143     public:
144         DumbClientReader(Client & client);
145
146     private:
147         virtual void v_disablePrompt();
148         virtual void v_enablePrompt();
149         virtual void v_write(std::string const & data);
150         virtual unsigned v_width() const;
151
152         void clientData(senf::ReadHelper<ClientHandle>::ptr helper);
153         void showPrompt();
154
155         std::string tail_;
156         unsigned promptLen_;
157         bool promptActive_;
158     };
159
160     /** \brief Internal: Primitive ClientReader implementation
161
162         This implementation uses the cooked telnet mode to read lines from the console. It does not
163         support explicit line editing or any other advanced features.
164      */
165     class NoninteractiveClientReader
166         : public ClientReader
167     {
168     public:
169         NoninteractiveClientReader(Client & client);
170
171     private:
172         virtual void v_disablePrompt();
173         virtual void v_enablePrompt();
174         virtual void v_write(std::string const & data);
175         virtual unsigned v_width() const;
176
177         void newData(int event);
178
179         scheduler::FdEvent readevent_;
180         std::string buffer_;
181     };
182
183 }}}
184
185 //-/////////////////////////////////////////////////////////////////////////////////////////////////
186 #endif
187
188 \f
189 // Local Variables:
190 // mode: c++
191 // fill-column: 100
192 // comment-column: 40
193 // c-file-style: "senf"
194 // indent-tabs-mode: nil
195 // ispell-local-dictionary: "american"
196 // compile-command: "scons -u test"
197 // End: