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