2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
15 \brief SocketHandle inline template implementation
18 #include "SocketHandle.ih"
22 #include <senf/Utils/senfassert.hh>
23 #include <senf/Utils/TypeInfo.hh>
25 #define prefix_ inline
26 //-/////////////////////////////////////////////////////////////////////////////////////////////////
28 //-/////////////////////////////////////////////////////////////////////////////////////////////////
29 // senf::SocketHandle<SPolicy>
31 template <class SPolicy>
32 prefix_ senf::SocketHandle<SPolicy>::SocketHandle()
35 template <class SPolicy>
36 template <class OtherPolicy>
37 prefix_ senf::SocketHandle<SPolicy>::SocketHandle(SocketHandle<OtherPolicy> other,
38 typename IsCompatible<OtherPolicy>::type *)
42 template <class SPolicy>
43 template <class OtherPolicy>
44 prefix_ typename senf::SocketHandle<SPolicy>::template IsCompatible<OtherPolicy>::type const &
45 senf::SocketHandle<SPolicy>::operator=(SocketHandle<OtherPolicy> other)
51 template <class SPolicy>
53 senf::SocketHandle<SPolicy>::SocketHandle(std::unique_ptr<SocketBody> body)
54 : FileHandle(std::unique_ptr<FileBody>(body.release()))
57 template <class SPolicy>
58 prefix_ senf::SocketHandle<SPolicy>::SocketHandle(FileHandle other, bool isChecked)
61 SENF_ASSERT( isChecked, "Internal failure: Wrong overload called !!" );
62 SENF_ASSERT( ! valid() || dynamic_cast<SocketBody *>(&FileHandle::body()),
63 "Internal failure: Replacing or re-assigning non-empty incompatible handle");
66 template <class SPolicy>
67 prefix_ senf::SocketBody & senf::SocketHandle<SPolicy>::body()
69 SENF_ASSERT( dynamic_cast<SocketBody *>(&FileHandle::body()),
70 "Internal failure: Invalid body found it's way into SocketHandle");
71 return static_cast<SocketBody &>(FileHandle::body());
74 template <class SPolicy>
75 prefix_ senf::SocketBody const & senf::SocketHandle<SPolicy>::body()
78 SENF_ASSERT( dynamic_cast<SocketBody const *>(&FileHandle::body()),
79 "Internal failure: Invalid body found it's way into SocketHandle");
80 return static_cast<SocketBody const &>(FileHandle::body());
83 template <class SPolicy>
84 prefix_ senf::SocketProtocol & senf::SocketHandle<SPolicy>::protocol()
87 return body().protocol();
90 template <class SPolicy>
91 prefix_ void senf::SocketHandle<SPolicy>::assign(FileHandle other)
93 FileHandle::operator=(other);
96 template <class SPolicy>
97 prefix_ senf::SocketHandle<SPolicy>
98 senf::SocketHandle<SPolicy>::cast_static(FileHandle handle)
100 return SocketHandle(handle,true);
103 template <class SPolicy>
104 prefix_ senf::SocketHandle<SPolicy>
105 senf::SocketHandle<SPolicy>::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 (already wrapped ...)
110 SPolicy::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 SENF_ASSERT( check_socket_cast<Target>(handle),
123 "Invalid static_socket_cast" );
124 return Target::cast_static(handle);
127 template <class Target, class Source>
128 prefix_ Target senf::dynamic_socket_cast(Source handle)
130 // BOOST_STATIC_ASSERT((
131 // boost::is_convertible<Source*,FileHandle*>::value &&
132 // boost::is_convertible<Target*,FileHandle*>::value &&
133 // ( boost::is_convertible<Source,Target>::value ||
134 // boost::is_convertible<Target,Source>::value ) ));
136 return Target::cast_dynamic(handle);
138 SENF_WRAP_EXC_MSG(std::bad_cast, "in dynamic_socket_cast()")
141 template <class Target, class Source>
142 prefix_ bool senf::check_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 ) ));
149 // we don't have a non-throwing variant of cast_dynamic
151 // a) since the handle is passed back by value, we cannot return
152 // something like a null handle
153 // b) it is simpler to implement cast_dynamic throwing bad_cast on
154 // failure than implementing cast_check
156 Target::cast_dynamic(handle);
158 catch (std::bad_cast const &) {
164 template <class SPolicy>
165 prefix_ void senf::SocketHandle<SPolicy>::state(SocketStateMap & map, unsigned lod)
167 // We use typeid here even though the type of *this is static
168 // (SocketHandle is not polymorphic and has no vtable). This will
169 // automatically include the SocketPolicy template parameter in
170 // the type name and therefore show the \e static policy of the
172 map["handle"] << prettyName(typeid(*this));
174 map["valid"] << "true";
175 body().state(map,lod);
177 map["valid"] << "false";
180 template <class SPolicy>
181 prefix_ std::string senf::SocketHandle<SPolicy>::dumpState(unsigned lod)
185 return detail::dumpState(map);
188 template <class SPolicy>
189 template <class Facet>
190 prefix_ Facet & senf::SocketHandle<SPolicy>::facet()
194 return dynamic_cast<Facet &>(protocol());
196 SENF_WRAP_EXC_MSG(std::bad_cast, "in SocketHandle::facet()")
199 //-/////////////////////////////////////////////////////////////////////////////////////////////////
200 // senf::ProtocolSocketBody<SProtocol>
202 template <class SProtocol>
203 prefix_ senf::ProtocolSocketBody<SProtocol>::ProtocolSocketBody(bool isServer)
204 : SocketBody(isServer)
207 template <class SProtocol>
208 prefix_ senf::ProtocolSocketBody<SProtocol>::ProtocolSocketBody(bool isServer, int fd)
209 : SocketBody(isServer, fd)
212 //-/////////////////////////////////////////////////////////////////////////////////////////////////
214 template <class SPolicy>
215 prefix_ std::ostream & senf::operator<<(std::ostream & os, SocketHandle<SPolicy> handle)
217 os << handle.dumpState();
221 //-/////////////////////////////////////////////////////////////////////////////////////////////////
228 // c-file-style: "senf"
229 // indent-tabs-mode: nil
230 // ispell-local-dictionary: "american"
231 // compile-command: "scons -u test"
232 // comment-column: 40