b2d9f7c546c8db7ffbd39ec9c000caf5eadc550f
[senf.git] / senf / Socket / SocketHandle.cti
1 // $Id$
2 //
3 // Copyright (C) 2006
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
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
10 //
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.
14 //
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.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
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.
24 //
25 // Contributor(s):
26 //   Stefan Bund <g0dil@berlios.de>
27
28 /** \file
29     \brief SocketHandle inline template implementation
30  */
31
32 #include "SocketHandle.ih"
33
34 // Custom includes
35 #include <typeinfo>
36 #include <senf/Utils/senfassert.hh>
37 #include <senf/Utils/TypeInfo.hh>
38
39 #define prefix_ inline
40 //-/////////////////////////////////////////////////////////////////////////////////////////////////
41
42 //-/////////////////////////////////////////////////////////////////////////////////////////////////
43 // senf::SocketHandle<SPolicy>
44
45 template <class SPolicy>
46 prefix_ senf::SocketHandle<SPolicy>::SocketHandle()
47 {}
48
49 template <class SPolicy>
50 template <class OtherPolicy>
51 prefix_ senf::SocketHandle<SPolicy>::SocketHandle(SocketHandle<OtherPolicy> other,
52                                                   typename IsCompatible<OtherPolicy>::type *)
53     : FileHandle(other)
54 {}
55
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)
60 {
61     assign(other);
62     return *this;
63 }
64
65 template <class SPolicy>
66 prefix_
67 senf::SocketHandle<SPolicy>::SocketHandle(std::auto_ptr<SocketBody> body)
68     : FileHandle(std::auto_ptr<FileBody>(body.release()))
69 {}
70
71 template <class SPolicy>
72 prefix_ senf::SocketHandle<SPolicy>::SocketHandle(FileHandle other, bool isChecked)
73     : FileHandle(other)
74 {
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");
78 }
79
80 template <class SPolicy>
81 prefix_ senf::SocketBody & senf::SocketHandle<SPolicy>::body()
82 {
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());
86 }
87
88 template <class SPolicy>
89 prefix_ senf::SocketBody const & senf::SocketHandle<SPolicy>::body()
90     const
91 {
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());
95 }
96
97 template <class SPolicy>
98 prefix_ senf::SocketProtocol & senf::SocketHandle<SPolicy>::protocol()
99     const
100 {
101     return body().protocol();
102 }
103
104 template <class SPolicy>
105 prefix_ void senf::SocketHandle<SPolicy>::assign(FileHandle other)
106 {
107     FileHandle::operator=(other);
108 }
109
110 template <class SPolicy>
111 prefix_ senf::SocketHandle<SPolicy>
112 senf::SocketHandle<SPolicy>::cast_static(FileHandle handle)
113 {
114     return SocketHandle(handle,true);
115 }
116
117 template <class SPolicy>
118 prefix_ senf::SocketHandle<SPolicy>
119 senf::SocketHandle<SPolicy>::cast_dynamic(FileHandle handle)
120 {
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);
126 }
127
128 template <class Target, class Source>
129 prefix_ Target senf::static_socket_cast(Source handle)
130 {
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);
139 }
140
141 template <class Target, class Source>
142 prefix_ Target senf::dynamic_socket_cast(Source handle)
143 {
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     try {
150         return Target::cast_dynamic(handle);
151     }
152     SENF_WRAP_EXC(std::bad_cast)
153 }
154
155 template <class Target, class Source>
156 prefix_ bool senf::check_socket_cast(Source handle)
157 {
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
164     // for two reasons:
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
169     try {
170         Target::cast_dynamic(handle);
171     }
172     catch (std::bad_cast const &) {
173         return false;
174     }
175     return true;
176 }
177
178 template <class SPolicy>
179 prefix_ void senf::SocketHandle<SPolicy>::state(SocketStateMap & map, unsigned lod)
180 {
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
185     // socket handle.
186     map["handle"] << prettyName(typeid(*this));
187     if (valid()) {
188         map["valid"] << "true";
189         body().state(map,lod);
190     } else
191         map["valid"] << "false";
192 }
193
194 template <class SPolicy>
195 prefix_ std::string senf::SocketHandle<SPolicy>::dumpState(unsigned lod)
196 {
197     SocketStateMap map;
198     state(map,lod);
199     return detail::dumpState(map);
200 }
201
202 template <class SPolicy>
203 template <class Facet>
204 prefix_ Facet & senf::SocketHandle<SPolicy>::facet()
205
206 {
207     try {
208         return dynamic_cast<Facet &>(protocol());
209     }
210     SENF_WRAP_EXC(std::bad_cast)
211 }
212
213 //-/////////////////////////////////////////////////////////////////////////////////////////////////
214 // senf::ProtocolSocketBody<SProtocol>
215
216 template <class SProtocol>
217 prefix_ senf::ProtocolSocketBody<SProtocol>::ProtocolSocketBody(bool isServer)
218     : SocketBody(isServer)
219 {}
220
221 template <class SProtocol>
222 prefix_ senf::ProtocolSocketBody<SProtocol>::ProtocolSocketBody(bool isServer, int fd)
223     : SocketBody(isServer, fd)
224 {}
225
226 //-/////////////////////////////////////////////////////////////////////////////////////////////////
227
228 template <class SPolicy>
229 prefix_ std::ostream & senf::operator<<(std::ostream & os, SocketHandle<SPolicy> handle)
230 {
231     os << handle.dumpState();
232     return os;
233 }
234
235 //-/////////////////////////////////////////////////////////////////////////////////////////////////
236 #undef prefix_
237
238 \f
239 // Local Variables:
240 // mode: c++
241 // fill-column: 100
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
247 // End: