4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at
9 // http://senf.berlios.de/license.html
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on,
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
15 // Software distributed under the License is distributed on an "AS IS" basis,
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
17 // for the specific language governing rights and limitations under the License.
19 // The Original Code is Fraunhofer FOKUS code.
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V.
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
26 // Stefan Bund <g0dil@berlios.de>
29 \brief SocketHandle inline template implementation
32 #include "SocketHandle.ih"
36 #include <senf/Utils/senfassert.hh>
37 #include <senf/Utils/TypeInfo.hh>
39 #define prefix_ inline
40 //-/////////////////////////////////////////////////////////////////////////////////////////////////
42 //-/////////////////////////////////////////////////////////////////////////////////////////////////
43 // senf::SocketHandle<SPolicy>
45 template <class SPolicy>
46 prefix_ senf::SocketHandle<SPolicy>::SocketHandle()
49 template <class SPolicy>
50 template <class OtherPolicy>
51 prefix_ senf::SocketHandle<SPolicy>::SocketHandle(SocketHandle<OtherPolicy> other,
52 typename IsCompatible<OtherPolicy>::type *)
56 template <class SPolicy>
57 template <class OtherPolicy>
58 prefix_ typename senf::SocketHandle<SPolicy>::template IsCompatible<OtherPolicy>::type const &
59 senf::SocketHandle<SPolicy>::operator=(SocketHandle<OtherPolicy> other)
65 template <class SPolicy>
67 senf::SocketHandle<SPolicy>::SocketHandle(std::auto_ptr<SocketBody> body)
68 : FileHandle(std::auto_ptr<FileBody>(body.release()))
71 template <class SPolicy>
72 prefix_ senf::SocketHandle<SPolicy>::SocketHandle(FileHandle other, bool isChecked)
75 SENF_ASSERT( isChecked, "Internal failure: Wrong overload called !!" );
76 SENF_ASSERT( ! valid() || dynamic_cast<SocketBody *>(&FileHandle::body()),
77 "Internal failure: Replacing or re-assigning non-empty incompatible handle");
80 template <class SPolicy>
81 prefix_ senf::SocketBody & senf::SocketHandle<SPolicy>::body()
83 SENF_ASSERT( dynamic_cast<SocketBody *>(&FileHandle::body()),
84 "Internal failure: Invalid body found it's way into SocketHandle");
85 return static_cast<SocketBody &>(FileHandle::body());
88 template <class SPolicy>
89 prefix_ senf::SocketBody const & senf::SocketHandle<SPolicy>::body()
92 SENF_ASSERT( dynamic_cast<SocketBody const *>(&FileHandle::body()),
93 "Internal failure: Invalid body found it's way into SocketHandle");
94 return static_cast<SocketBody const &>(FileHandle::body());
97 template <class SPolicy>
98 prefix_ senf::SocketProtocol & senf::SocketHandle<SPolicy>::protocol()
101 return body().protocol();
104 template <class SPolicy>
105 prefix_ void senf::SocketHandle<SPolicy>::assign(FileHandle other)
107 FileHandle::operator=(other);
110 template <class SPolicy>
111 prefix_ senf::SocketHandle<SPolicy>
112 senf::SocketHandle<SPolicy>::cast_static(FileHandle handle)
114 return SocketHandle(handle,true);
117 template <class SPolicy>
118 prefix_ senf::SocketHandle<SPolicy>
119 senf::SocketHandle<SPolicy>::cast_dynamic(FileHandle handle)
121 // throws bad_cast if the body is not a SocketBody
122 SocketBody & body (dynamic_cast<SocketBody&>(FileHandle::body(handle)));
123 // throws bad_cast if the policy is not compatible (already wrapped ...)
124 SPolicy::checkBaseOf(body.protocol().policy());
125 return cast_static(handle);
128 template <class Target, class Source>
129 prefix_ Target senf::static_socket_cast(Source handle)
131 BOOST_STATIC_ASSERT((
132 boost::is_convertible<Source*,FileHandle*>::value &&
133 boost::is_convertible<Target*,FileHandle*>::value &&
134 ( boost::is_convertible<Source,Target>::value ||
135 boost::is_convertible<Target,Source>::value ) ));
136 SENF_ASSERT( check_socket_cast<Target>(handle),
137 "Invalid static_socket_cast" );
138 return Target::cast_static(handle);
141 template <class Target, class Source>
142 prefix_ Target senf::dynamic_socket_cast(Source handle)
144 // BOOST_STATIC_ASSERT((
145 // boost::is_convertible<Source*,FileHandle*>::value &&
146 // boost::is_convertible<Target*,FileHandle*>::value &&
147 // ( boost::is_convertible<Source,Target>::value ||
148 // boost::is_convertible<Target,Source>::value ) ));
150 return Target::cast_dynamic(handle);
152 SENF_WRAP_EXC(std::bad_cast)
155 template <class Target, class Source>
156 prefix_ bool senf::check_socket_cast(Source handle)
158 // BOOST_STATIC_ASSERT((
159 // boost::is_convertible<Source*,FileHandle*>::value &&
160 // boost::is_convertible<Target*,FileHandle*>::value &&
161 // ( boost::is_convertible<Source,Target>::value ||
162 // boost::is_convertible<Target,Source>::value ) ));
163 // we don't have a non-throwing variant of cast_dynamic
165 // a) since the handle is passed back by value, we cannot return
166 // something like a null handle
167 // b) it is simpler to implement cast_dynamic throwig bad_cast on
168 // failure than implementing cast_check
170 Target::cast_dynamic(handle);
172 catch (std::bad_cast const &) {
178 template <class SPolicy>
179 prefix_ void senf::SocketHandle<SPolicy>::state(SocketStateMap & map, unsigned lod)
181 // We use typeid here even though the type of *this is static
182 // (SocketHandle is not polymorphic and has no vtable). This will
183 // automatically include the SocketPolicy template parameter in
184 // the type name and therefore show the \e static policy of the
186 map["handle"] << prettyName(typeid(*this));
188 map["valid"] << "true";
189 body().state(map,lod);
191 map["valid"] << "false";
194 template <class SPolicy>
195 prefix_ std::string senf::SocketHandle<SPolicy>::dumpState(unsigned lod)
199 return detail::dumpState(map);
202 template <class SPolicy>
203 template <class Facet>
204 prefix_ Facet & senf::SocketHandle<SPolicy>::facet()
208 return dynamic_cast<Facet &>(protocol());
210 SENF_WRAP_EXC(std::bad_cast)
213 //-/////////////////////////////////////////////////////////////////////////////////////////////////
214 // senf::ProtocolSocketBody<SProtocol>
216 template <class SProtocol>
217 prefix_ senf::ProtocolSocketBody<SProtocol>::ProtocolSocketBody(bool isServer)
218 : SocketBody(isServer)
221 template <class SProtocol>
222 prefix_ senf::ProtocolSocketBody<SProtocol>::ProtocolSocketBody(bool isServer, int fd)
223 : SocketBody(isServer, fd)
226 //-/////////////////////////////////////////////////////////////////////////////////////////////////
228 template <class SPolicy>
229 prefix_ std::ostream & senf::operator<<(std::ostream & os, SocketHandle<SPolicy> handle)
231 os << handle.dumpState();
235 //-/////////////////////////////////////////////////////////////////////////////////////////////////
242 // c-file-style: "senf"
243 // indent-tabs-mode: nil
244 // ispell-local-dictionary: "american"
245 // compile-command: "scons -u test"
246 // comment-column: 40