4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
6 // Stefan Bund <stefan.bund@fokus.fraunhofer.de>
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.
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.
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.
24 \brief SocketHandle inline template implementation
27 #include "SocketHandle.ih"
31 #include <boost/lexical_cast.hpp>
32 #include "Utils/TypeInfo.hh"
34 #define prefix_ inline
35 ///////////////////////////////cti.p///////////////////////////////////////
37 template <class SocketPolicy>
38 template <class OtherPolicy>
39 prefix_ senf::SocketHandle<SocketPolicy>::SocketHandle(SocketHandle<OtherPolicy> other,
40 typename IsCompatible<OtherPolicy>::type *)
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)
53 template <class SocketPolicy>
55 senf::SocketHandle<SocketPolicy>::SocketHandle(std::auto_ptr<SocketProtocol> protocol,
57 : FileHandle(std::auto_ptr<FileBody>(new SocketBody(protocol,isServer)))
60 template <class SocketPolicy>
61 prefix_ senf::SocketHandle<SocketPolicy>::SocketHandle(FileHandle other, bool isChecked)
64 BOOST_ASSERT( isChecked );
65 BOOST_ASSERT( dynamic_cast<SocketBody *>(&FileHandle::body()) );
68 template <class SocketPolicy>
69 prefix_ senf::SocketBody & senf::SocketHandle<SocketPolicy>::body()
71 BOOST_ASSERT( dynamic_cast<SocketBody *>(&FileHandle::body()) );
72 return static_cast<SocketBody &>(FileHandle::body());
75 template <class SocketPolicy>
76 prefix_ senf::SocketBody const & senf::SocketHandle<SocketPolicy>::body()
79 BOOST_ASSERT( dynamic_cast<SocketBody const *>(&FileHandle::body()) );
80 return static_cast<SocketBody const &>(FileHandle::body());
83 template <class SocketPolicy>
84 prefix_ senf::SocketProtocol const & senf::SocketHandle<SocketPolicy>::protocol()
87 return body().protocol();
90 template <class SocketPolicy>
91 prefix_ void senf::SocketHandle<SocketPolicy>::assign(FileHandle other)
93 FileHandle::operator=(other);
96 template <class SocketPolicy>
97 prefix_ senf::SocketHandle<SocketPolicy>
98 senf::SocketHandle<SocketPolicy>::cast_static(FileHandle handle)
100 return SocketHandle(handle,true);
103 template <class SocketPolicy>
104 prefix_ senf::SocketHandle<SocketPolicy>
105 senf::SocketHandle<SocketPolicy>::cast_dynamic(FileHandle handle)
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);
114 template <class Target, class Source>
115 prefix_ Target senf::static_socket_cast(Source handle)
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);
126 template <class Target, class Source>
127 prefix_ Target senf::dynamic_socket_cast(Source handle)
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);
137 template <class Target, class Source>
138 prefix_ bool senf::check_socket_cast(Source handle)
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
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
152 Target::cast_dynamic(handle);
154 catch (std::bad_cast const &) {
160 template <class SocketPolicy>
161 prefix_ void senf::SocketHandle<SocketPolicy>::state(SocketStateMap & map, unsigned lod)
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
168 map["handle"] = prettyName(typeid(*this));
169 body().state(map,lod);
172 template <class SocketPolicy>
173 prefix_ std::string senf::SocketHandle<SocketPolicy>::dumpState(unsigned lod)
177 return detail::dumpState(map);
180 ///////////////////////////////////////////////////////////////////////////
181 // senf::detail::ConvertibleString
184 prefix_ senf::detail::ConvertibleString::ConvertibleString(T const & other)
185 : std::string(boost::lexical_cast<std::string>(other))
188 ///////////////////////////////cti.e///////////////////////////////////////
195 // c-file-style: "senf"
196 // indent-tabs-mode: nil
197 // ispell-local-dictionary: "american"