a7ddf61055cb456231d911cf88f71913873d8986
[senf.git] / Socket / SocketHandle.ih
1 // $Id$
2 //
3 // Copyright (C) 2006 
4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
6 //     Stefan Bund <stefan.bund@fokus.fraunhofer.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_SocketHandle_
28 #define IH_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 ConvertibleString class is used to simplify creating a text representation of
48             arbitrary values. ConvertibleString 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 ConvertibleString : public std::string
57         {
58         public:
59             ConvertibleString();
60             ConvertibleString(bool v);  ///< Bool conversion constructor
61                                         /**< The bool conversion is defined explicitly to use a
62                                            specialized representation (the strings 'true' and
63                                            'false') */
64             template <class T>
65             ConvertibleString(T const & other);
66                                         ///< Conversion constructor
67                                         /**< This constructor will assign the string from any
68                                            arbitrary type. It will use boost::lexical_cast to
69                                            convert the argument to its string representation. */
70
71             template <class T>
72             ConvertibleString & operator+= (ConvertibleString const & other);
73                                         ///< Add additional values with separator
74                                         /**< This operator facilitates the representation of
75                                            multiple values in a single string. Each value is first
76                                            converted to a string (using the type conversion
77                                            machinery of C++ and the ConvertibleString conversion
78                                            constructors). It is then appended to the current string
79                                            with ', ' as a separator (if the current string is
80                                            non-empty). */
81         };
82
83         /** \brief Special ordering for the SocketStateMap
84             \internal
85
86             This special ordering will sort 'hierarchical' strings correctly. A hierarchical string
87             in this context is a string like a path- or hostname with '.' as the hierarchical
88             separator.
89          */
90         struct StateMapOrdering
91             : public std::binary_function<std::string,std::string,bool>
92         {
93             bool operator()(std::string const & a1, std::string const & a2) const;
94         };
95
96     }
97
98     typedef std::map< std::string, detail::ConvertibleString, detail::StateMapOrdering > SocketStateMap;
99
100     namespace detail {
101         /** \brief Helper to convert SocketStateMap to multiline string representation
102             \internal
103          */
104         std::string dumpState(SocketStateMap const & map);
105     }
106
107     /** \brief SocketHandle referenced body
108         
109         \internal
110
111         senf::SocketBody is the extended (relatively to senf::FileBody) body of
112         senf::SocketHandle. Every SocketHandle must have a SocketBody as it's body (and not a simple
113         FileBody). The casting and conversion operators defined will ensure this if used
114         properly. If this invariant is violated, your Program will probably crash.
115      */
116     class SocketBody
117         : public FileBody
118     {
119     public:
120         ///////////////////////////////////////////////////////////////////////////
121         // Types
122
123         typedef boost::intrusive_ptr<SocketBody> ptr;
124
125         ///////////////////////////////////////////////////////////////////////////
126         ///\name Structors and default members
127         ///@{
128
129         SocketBody(std::auto_ptr<SocketProtocol> protocol, bool isServer);
130                                         /**< 
131                                            \param protocol Protocol class implementing the desired
132                                            protocol 
133                                            \param isServer \c true, if this socket is a server
134                                            socket, false otherwise */
135         SocketBody(std::auto_ptr<SocketProtocol> protocol, bool isServer, int fd);
136                                         /**< 
137                                            \param protocol Protocol class implementing the desired
138                                            protocol 
139                                            \param isServer \c true, if this socket is a server
140                                            socket, false otherwise
141                                            \param fd socket file descriptor */
142
143         // no copy
144         // no conversion constructors
145
146         ///@}
147         ///////////////////////////////////////////////////////////////////////////
148
149         SocketProtocol const & protocol() const;
150                                         ///< Access the protocol instance
151         bool isServer();                ///< Check socket type
152                                         /**< \return \c true, if this is a server socket, \c false
153                                            otherwise */
154
155         void state(SocketStateMap & map, unsigned lod);
156
157     private:
158         virtual void v_close();         ///< Close socket
159                                         /**< This override will automatically \c shutdown() the
160                                            socket whenever it is closed.
161                                            \throws senf::SystemException */
162         virtual void v_terminate();     ///< Forcibly close socket
163                                         /**< This override will automatically \c shutfown() the
164                                            socket whenever it is called. Additionally it will
165                                            disable SO_LINGER to ensure, that v_terminate will not
166                                            block. Like the overriden method, this member will ignore
167                                            failures and will never throw. It therefore safe to be
168                                            called from a destructor. */
169         virtual bool v_eof() const;     ///< Check for eof condition
170                                         /**< Since the eof check for sockets is very protocol
171                                            dependent, this member will forward the call to
172                                            senf::SocketPolicy::eof() */
173
174         boost::scoped_ptr<SocketProtocol> protocol_;
175         bool isServer_;
176     };
177
178 }
179
180 ///////////////////////////////ih.e////////////////////////////////////////
181 #endif
182
183 \f
184 // Local Variables:
185 // mode: c++
186 // c-file-style: "senf"
187 // fill-column: 100
188 // End: