Packets: Fix VariantParser invalid parser access bug
[senf.git] / Socket / SocketHandle.ih
1 // $Id$
2 //
3 // Copyright (C) 2006
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 SocketHandle internal header
25  */
26
27 #ifndef IH_SENF_Socket_SocketHandle_
28 #define IH_SENF_Socket_SocketHandle_ 1
29
30 // Custom includes
31 #include <map>
32 #include <string>
33 #include <boost/scoped_ptr.hpp>
34 #include "FileHandle.hh"
35
36 ///////////////////////////////ih.p////////////////////////////////////////
37
38 namespace senf {
39
40
41     class SocketProtocol;
42
43     namespace detail {
44
45         /** \brief String supporting automatic type conversion
46
47             The StreamableString class is used to simplify creating a text representation of
48             arbitrary values. StreamableString is an ordinary string with an additional constructor
49             which allows constructing the string from any arbitrary, streamable type.
50
51             \note It is generally not advisable to derive from the standard library container
52             classes. However, in this concrete case, the derivation is safe since only the
53             additional functionality is added. It is absolutely safe to convert the derived class
54             back to the base type.
55          */
56         class StreamableString : public std::string
57         {
58         public:
59             using std::string::operator=;
60
61             template <class T>
62             StreamableString & operator<<(T const & other);
63                                         ///< Value assigment
64                                         /**< This operator will assign the string from any
65                                              arbitrary type. It will use boost::lexical_cast to
66                                              convert the argument to its string representation. 
67
68                                              If the string is non-empty, an additional separating
69                                              comma is added to the string. */
70
71             StreamableString & operator<<(bool v);  ///< Bool assignment
72                                         /**< The bool assignment is defined explicitly to use a
73                                              specialized representation (the strings 'true' and
74                                              'false'). */
75         };
76
77     }
78
79     typedef std::map< std::string, detail::StreamableString > SocketStateMap;
80
81     namespace detail {
82         /** \brief Helper to convert SocketStateMap to multiline string representation
83             \internal
84          */
85         std::string dumpState(SocketStateMap const & map);
86     }
87
88     template <class Policy, class Self> class ConcreteSocketProtocol;
89
90     /** \brief SocketHandle referenced body
91
92         \internal
93
94         senf::SocketBody is the extended (relatively to senf::FileBody) body of
95         senf::SocketHandle. Every SocketHandle must have a SocketBody as it's body (and not a simple
96         FileBody). The casting and conversion operators defined will ensure this if used
97         properly. If this invariant is violated, your Program will probably crash.
98      */
99     class SocketBody
100         : public FileBody
101     {
102     public:
103         ///////////////////////////////////////////////////////////////////////////
104         // Types
105
106         typedef boost::intrusive_ptr<SocketBody> ptr;
107
108         ///////////////////////////////////////////////////////////////////////////
109         ///\name Structors and default members
110         ///@{
111
112         SocketBody(bool isServer);      /**< \param isServer \c true, if this socket is a server
113                                              socket, false otherwise */
114         SocketBody(bool isServer, int fd);
115                                         /**< \param isServer \c true, if this socket is a server
116                                              socket, false otherwise
117                                              \param fd socket file descriptor */
118
119         // no copy
120         // no conversion constructors
121
122         ///@}
123         ///////////////////////////////////////////////////////////////////////////
124
125         SocketProtocol & protocol(); ///< Access the protocol instance
126         SocketProtocol const & protocol() const; ///< Access the protocol instance (const)
127
128         bool isServer();                ///< Check socket type
129                                         /**< \return \c true, if this is a server socket, \c false
130                                            otherwise */
131
132         void state(SocketStateMap & map, unsigned lod);
133
134         std::auto_ptr<SocketBody> clone(bool isServer) const;
135         std::auto_ptr<SocketBody> clone(int fd, bool isServer) const;
136
137     private:
138         virtual void v_close();         ///< Close socket
139                                         /**< This override will automatically \c shutdown() the
140                                            socket whenever it is closed.
141                                            \throws senf::SystemException */
142         virtual void v_terminate();     ///< Forcibly close socket
143                                         /**< This override will automatically \c shutfown() the
144                                            socket whenever it is called. Additionally it will
145                                            disable SO_LINGER to ensure, that v_terminate will not
146                                            block. Like the overriden method, this member will ignore
147                                            failures and will never throw. It therefore safe to be
148                                            called from a destructor. */
149         virtual bool v_eof() const;     ///< Check for eof condition
150                                         /**< Since the eof check for sockets is very protocol
151                                            dependent, this member will forward the call to
152                                            senf::SocketPolicy::eof() */
153
154         virtual SocketProtocol const & v_protocol() const = 0;
155         virtual std::string v_protocolName() const = 0;
156
157         bool isServer_;
158     };
159
160     template <class SProtocol>
161     class ProtocolSocketBody 
162         : public SocketBody, 
163           private SProtocol,
164           public senf::pool_alloc_mixin< ProtocolSocketBody<SProtocol> >
165     {
166     public:
167         typedef SProtocol Protocol;
168
169         using senf::pool_alloc_mixin< ProtocolSocketBody<SProtocol> >::operator new;
170         using senf::pool_alloc_mixin< ProtocolSocketBody<SProtocol> >::operator delete;
171
172         ProtocolSocketBody(bool isServer); /**< \param isServer \c true, if this socket is a server
173                                              socket, false otherwise */
174         ProtocolSocketBody(bool isServer, int fd);
175                                         /**< \param isServer \c true, if this socket is a server
176                                              socket, false otherwise
177                                              \param fd socket file descriptor */
178         
179     private:
180         virtual SocketProtocol const & v_protocol() const;
181         virtual std::string v_protocolName() const;
182
183         friend class ConcreteSocketProtocol<typename SProtocol::Policy, SProtocol>;
184     };
185
186 }
187
188 ///////////////////////////////ih.e////////////////////////////////////////
189 #endif
190
191 \f
192 // Local Variables:
193 // mode: c++
194 // fill-column: 100
195 // c-file-style: "senf"
196 // indent-tabs-mode: nil
197 // ispell-local-dictionary: "american"
198 // compile-command: "scons -u test"
199 // comment-column: 40
200 // End: