switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / Utils / Console / Server.ih
1 // $Id$
2 //
3 // Copyright (C) 2008
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at 
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis, 
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
24 //
25 // Contributor(s):
26 //   Stefan Bund <g0dil@berlios.de>
27
28 /** \file
29     \brief Server internal header */
30
31 #ifndef IH_SENF_Scheduler_Console_Server_
32 #define IH_SENF_Scheduler_Console_Server_ 1
33
34 // Custom includes
35 #include <boost/iostreams/concepts.hpp>
36 #include <boost/iostreams/stream.hpp>
37 #include <senf/Scheduler/ReadHelper.hh>
38 #include <senf/Socket/Protocols/INet/TCPSocketHandle.hh>
39 #include <senf/Utils/Logger/SenfLog.hh>
40
41 //-/////////////////////////////////////////////////////////////////////////////////////////////////
42
43 namespace senf {
44 namespace console {
45
46     class Server;
47     class Client;
48
49 namespace detail {
50
51     class ServerManager
52     {
53     public:
54         typedef boost::intrusive_ptr<Server> ptr;
55
56     protected:
57
58     private:
59         static void add(ptr server);
60         static void remove(ptr server);
61
62         static ServerManager & instance();
63
64         typedef std::set<ptr> Servers;
65         Servers servers_;
66
67         friend class senf::console::Server;
68     };
69
70     /** \brief Internal: Nonblocking boost::iostreams::sink
71
72         The sink discards data if the output socket would.
73
74         \fixme Don't throw exceptions ... set stream error indicator (if at all)
75      */
76     class NonblockingSocketSink
77         : public boost::iostreams::sink
78     {
79     public:
80         NonblockingSocketSink(Client & client);
81         std::streamsize write(const char * s, std::streamsize n);
82
83         Client & client() const;
84
85     private:
86         Client & client_;
87     };
88
89     typedef boost::iostreams::stream<NonblockingSocketSink> NonblockingSocketOStream;
90
91     typedef senf::ServerSocketHandle<
92         senf::MakeSocketPolicy< senf::TCPv4SocketProtocol::Policy,
93                                 senf::BSDAddressingPolicy>::policy > ServerHandle;
94
95     /** \brief Internal: Generic client interface
96
97         The ClientReader encapsulates the interaction of a single network client with the user: It
98         manages prompt display and reading an interactive command.
99      */
100     class ClientReader
101     {
102     public:
103         SENF_LOG_CLASS_AREA();
104
105         typedef ServerHandle::ClientHandle ClientHandle;
106
107         virtual ~ClientReader() = 0;
108
109         // Called by subclasses to get information from the Client
110
111         Client & client() const;
112         std::string promptString() const;
113         ClientHandle handle() const;
114         std::ostream & stream() const;
115
116         // Called by subclasses to perform actions in the Client
117
118         void stopClient();
119         std::string::size_type handleInput(std::string const & input, bool incremental=false) const;
120
121         // Called by the Client
122
123         void disablePrompt();
124         void enablePrompt();
125         void write(std::string const & data);
126         unsigned width() const;
127
128     protected:
129         ClientReader(Client & client);
130
131     private:
132         virtual void v_disablePrompt() = 0;
133         virtual void v_enablePrompt() = 0;
134         virtual void v_write(std::string const & data) = 0;
135         virtual unsigned v_width() const = 0;
136
137         Client & client_;
138     };
139
140     /** \brief Internal: Primitive ClientReader implementation
141
142         This implementation uses the cooked telnet mode to read lines from the console. It does not
143         support explicit line editing or any other advanced features.
144      */
145     class DumbClientReader
146         : public ClientReader
147     {
148     public:
149         DumbClientReader(Client & client);
150
151     private:
152         virtual void v_disablePrompt();
153         virtual void v_enablePrompt();
154         virtual void v_write(std::string const & data);
155         virtual unsigned v_width() const;
156
157         void clientData(senf::ReadHelper<ClientHandle>::ptr helper);
158         void showPrompt();
159
160         std::string tail_;
161         unsigned promptLen_;
162         bool promptActive_;
163     };
164
165     /** \brief Internal: Primitive ClientReader implementation
166
167         This implementation uses the cooked telnet mode to read lines from the console. It does not
168         support explicit line editing or any other advanced features.
169      */
170     class NoninteractiveClientReader
171         : public ClientReader
172     {
173     public:
174         NoninteractiveClientReader(Client & client);
175
176     private:
177         virtual void v_disablePrompt();
178         virtual void v_enablePrompt();
179         virtual void v_write(std::string const & data);
180         virtual unsigned v_width() const;
181
182         void newData(int event);
183
184         scheduler::FdEvent readevent_;
185         std::string buffer_;
186     };
187
188 }}}
189
190 //-/////////////////////////////////////////////////////////////////////////////////////////////////
191 #endif
192
193 \f
194 // Local Variables:
195 // mode: c++
196 // fill-column: 100
197 // comment-column: 40
198 // c-file-style: "senf"
199 // indent-tabs-mode: nil
200 // ispell-local-dictionary: "american"
201 // compile-command: "scons -u test"
202 // End: