4d03d6768277b89ead9be3c062d7d0fa89e637c0
[senf.git] / Socket / SocketHandle.cti
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 inline template implementation
25  */
26
27 #include "SocketHandle.ih"
28
29 // Custom includes
30 #include <typeinfo>
31 #include <boost/lexical_cast.hpp>
32 #include "Utils/TypeInfo.hh"
33
34 #define prefix_ inline
35 ///////////////////////////////cti.p///////////////////////////////////////
36
37 template <class SocketPolicy>
38 template <class OtherPolicy>
39 prefix_ senf::SocketHandle<SocketPolicy>::SocketHandle(SocketHandle<OtherPolicy> other,
40                                                               typename IsCompatible<OtherPolicy>::type *)
41     : FileHandle(other)
42 {}
43
44 template <class SocketPolicy>
45 template <class OtherPolicy>
46 prefix_ typename senf::SocketHandle<SocketPolicy>::template IsCompatible<OtherPolicy>::type const &
47 senf::SocketHandle<SocketPolicy>::operator=(SocketHandle<OtherPolicy> other)
48 {
49     assign(other);
50     return *this;
51 }
52
53 template <class SocketPolicy>
54 prefix_ 
55 senf::SocketHandle<SocketPolicy>::SocketHandle(std::auto_ptr<SocketProtocol> protocol,
56                                                       bool isServer)
57     : FileHandle(std::auto_ptr<FileBody>(new SocketBody(protocol,isServer)))
58 {}
59
60 template <class SocketPolicy>
61 prefix_ senf::SocketHandle<SocketPolicy>::SocketHandle(FileHandle other, bool isChecked)
62     : FileHandle(other)
63 {
64     BOOST_ASSERT( isChecked );
65     BOOST_ASSERT( dynamic_cast<SocketBody *>(&FileHandle::body()) );
66 }
67
68 template <class SocketPolicy>
69 prefix_ senf::SocketBody & senf::SocketHandle<SocketPolicy>::body()
70 {
71     BOOST_ASSERT( dynamic_cast<SocketBody *>(&FileHandle::body()) );
72     return static_cast<SocketBody &>(FileHandle::body());
73 }
74
75 template <class SocketPolicy>
76 prefix_ senf::SocketBody const & senf::SocketHandle<SocketPolicy>::body()
77     const
78 {
79     BOOST_ASSERT( dynamic_cast<SocketBody const *>(&FileHandle::body()) );
80     return static_cast<SocketBody const &>(FileHandle::body());
81 }
82
83 template <class SocketPolicy>
84 prefix_ senf::SocketProtocol const & senf::SocketHandle<SocketPolicy>::protocol()
85     const
86 {
87     return body().protocol();
88 }
89
90 template <class SocketPolicy>
91 prefix_ void senf::SocketHandle<SocketPolicy>::assign(FileHandle other)
92 {
93     FileHandle::operator=(other);
94 }
95
96 template <class SocketPolicy>
97 prefix_ senf::SocketHandle<SocketPolicy>
98 senf::SocketHandle<SocketPolicy>::cast_static(FileHandle handle)
99 {
100     return SocketHandle(handle,true);
101 }
102
103 template <class SocketPolicy>
104 prefix_ senf::SocketHandle<SocketPolicy>
105 senf::SocketHandle<SocketPolicy>::cast_dynamic(FileHandle handle)
106 {
107     // throws bad_cast if the body is not a SocketBody
108     SocketBody & body (dynamic_cast<SocketBody&>(FileHandle::body(handle)));
109     // throws bad_cast if the policy is not compatible
110     SocketPolicy::checkBaseOf(body.protocol().policy());
111     return cast_static(handle);
112 }
113
114 template <class Target, class Source>
115 prefix_ Target senf::static_socket_cast(Source handle)
116 {
117     BOOST_STATIC_ASSERT((
118         boost::is_convertible<Source*,FileHandle*>::value &&
119         boost::is_convertible<Target*,FileHandle*>::value &&
120         ( boost::is_convertible<Source,Target>::value ||
121           boost::is_convertible<Target,Source>::value ) ));
122     BOOST_ASSERT( check_socket_cast<Target>(handle) );
123     return Target::cast_static(handle);
124 }
125
126 template <class Target, class Source>
127 prefix_ Target senf::dynamic_socket_cast(Source handle)
128 {
129     BOOST_STATIC_ASSERT((
130         boost::is_convertible<Source*,FileHandle*>::value &&
131         boost::is_convertible<Target*,FileHandle*>::value &&
132         ( boost::is_convertible<Source,Target>::value ||
133           boost::is_convertible<Target,Source>::value ) ));
134     return Target::cast_dynamic(handle);
135 }
136
137 template <class Target, class Source>
138 prefix_ bool senf::check_socket_cast(Source handle)
139 {
140     BOOST_STATIC_ASSERT((
141         boost::is_convertible<Source*,FileHandle*>::value &&
142         boost::is_convertible<Target*,FileHandle*>::value &&
143         ( boost::is_convertible<Source,Target>::value ||
144           boost::is_convertible<Target,Source>::value ) ));
145     // we don't have a non-throwing variant of cast_dynamic
146     // for two reasons:
147     // a) since the handle is passed back by value, we cannot return
148     //    something like a null handle
149     // b) it is simpler to implement cast_dynamic throwig bad_cast on
150     //    failure than implementing cast_check
151     try {
152         Target::cast_dynamic(handle);
153     }
154     catch (std::bad_cast const &) {
155         return false;
156     }
157     return true;
158 }
159
160 template <class SocketPolicy>
161 prefix_ void senf::SocketHandle<SocketPolicy>::state(SocketStateMap & map, unsigned lod)
162 {
163     // We use typeid here even though the type of *this is static
164     // (SocketHandle is not polymorphic and has no vtable). This will
165     // automatically include the SocketPolicy template parameter in
166     // the type name and therefore show the \e static policy of the
167     // socket handle.
168     map["handle"] = prettyName(typeid(*this));
169     body().state(map,lod);
170 }
171
172 template <class SocketPolicy>
173 prefix_ std::string senf::SocketHandle<SocketPolicy>::dumpState(unsigned lod)
174 {
175     SocketStateMap map;
176     state(map,lod);
177     return detail::dumpState(map);
178 }
179
180 ///////////////////////////////////////////////////////////////////////////
181 // senf::detail::ConvertibleString
182
183 template <class T>
184 prefix_ senf::detail::ConvertibleString::ConvertibleString(T const & other)
185     : std::string(boost::lexical_cast<std::string>(other))
186 {}
187
188 ///////////////////////////////cti.e///////////////////////////////////////
189 #undef prefix_
190
191 \f
192 // Local Variables:
193 // mode: c++
194 // c-file-style: "senf"
195 // End: