66d8d83f4696f01c80e917cd205ff192b87b8482
[senf.git] / senf / Socket / ClientSocketHandle.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 ClientSocketHandle inline template implementation
30  */
31
32 #include "ClientSocketHandle.ih"
33
34 // Custom includes
35 #include <typeinfo>
36
37 #define prefix_ inline
38 //-/////////////////////////////////////////////////////////////////////////////////////////////////
39
40 //-/////////////////////////////////////////////////////////////////////////////////////////////////
41 // senf::detail::ReadRange<Policy,ForwardWritableRange,true>
42
43 template <class Handle, class ForwardWritableRange>
44 prefix_ typename boost::range_iterator<ForwardWritableRange>::type
45 senf::detail::ReadRange<Handle,ForwardWritableRange,true>::read(Handle & handle,
46                                                                 ForwardWritableRange & range)
47 {
48     typename boost::range_iterator<ForwardWritableRange>::type const i (boost::begin(range));
49     char * const ic (reinterpret_cast<char*>(storage_iterator(i)));
50     return i + (handle.read( ic,
51                              reinterpret_cast<char*>(storage_iterator(boost::end(range))) )
52                 - ic);
53 }
54
55 template <class Handle, class ForwardWritableRange>
56 prefix_ typename boost::range_iterator<ForwardWritableRange>::type
57 senf::detail::ReadRange<Handle,ForwardWritableRange,true>::
58 readfrom(Handle & handle, ForwardWritableRange & range, typename Handle::Address & addr)
59 {
60     typename boost::range_iterator<ForwardWritableRange>::type const i (boost::begin(range));
61     char * const ic (reinterpret_cast<char*>(storage_iterator(i)));
62     return i + (handle.readfrom( ic,
63                                  reinterpret_cast<char*>(storage_iterator(boost::end(range))),
64                                  addr )
65                 - ic);
66 }
67
68 //-/////////////////////////////////////////////////////////////////////////////////////////////////
69 // senf::detail::WriteRange<Handle, ForwardReadableRange, true>
70
71 template <class Handle, class ForwardReadableRange>
72 prefix_ typename boost::range_const_iterator<ForwardReadableRange>::type
73 senf::detail::WriteRange<Handle, ForwardReadableRange, true>::
74 write(Handle & handle, ForwardReadableRange & range)
75 {
76     typename boost::range_const_iterator<ForwardReadableRange>::type i
77         (boost::const_begin(range));
78     char const * const ic (reinterpret_cast<char const *>(storage_iterator(i)));
79     std::advance(i, handle.write(ic,
80                                  reinterpret_cast<char const *>(
81                                      storage_iterator(boost::const_end(range)))) - ic);
82     return i;
83 }
84
85 template <class Handle, class ForwardReadableRange>
86 prefix_ typename boost::range_const_iterator<ForwardReadableRange>::type
87 senf::detail::WriteRange<Handle, ForwardReadableRange, true>::
88 writeto(Handle & handle, ForwardReadableRange & range, typename Handle::Address const & addr)
89 {
90     typename boost::range_const_iterator<ForwardReadableRange>::type i
91         (boost::const_begin(range));
92     char const * const ic (reinterpret_cast<char const *>(storage_iterator(i)));
93     std::advance(i, handle.writeto(addr, ic,
94                                    reinterpret_cast<char const *>(
95                                        storage_iterator(boost::const_end(range)))) - ic);
96     return i;
97 }
98
99 //-/////////////////////////////////////////////////////////////////////////////////////////////////
100 // senf::ClientSocketHandle<Policy>
101
102 //-/////////////////////////////////////////////////////////////////////////////////////////////////
103 // structors
104
105 template <class SPolicy>
106 prefix_ senf::ClientSocketHandle<SPolicy>::ClientSocketHandle()
107 {}
108
109 #ifndef DOXYGEN
110 template <class SPolicy>
111 template <class OtherPolicy>
112 prefix_ senf::ClientSocketHandle<SPolicy>::
113 ClientSocketHandle(ClientSocketHandle<OtherPolicy> other,
114                    typename SocketHandle<SPolicy>::template IsCompatible<OtherPolicy>::type *)
115     : SocketHandle<SPolicy>(other,true)
116 {}
117 #else
118 template <class SPolicy>
119 template <class OtherPolicy>
120 prefix_ senf::ClientSocketHandle<SPolicy>::
121 ClientSocketHandle(ClientSocketHandle<OtherPolicy> other)
122 {}
123 #endif
124
125 template <class SPolicy>
126 prefix_ senf::ClientSocketHandle<SPolicy>::ClientSocketHandle(FileHandle other, bool isChecked)
127     : SocketHandle<SPolicy>(other, isChecked)
128 {}
129
130 template <class SPolicy>
131 prefix_
132 senf::ClientSocketHandle<SPolicy>::ClientSocketHandle(std::auto_ptr<SocketBody> body)
133     : SocketHandle<SPolicy>(body)
134 {}
135
136 #ifndef DOXYGEN
137 template <class SPolicy>
138 template <class OtherPolicy>
139 prefix_ typename senf::SocketHandle<SPolicy>::template IsCompatible<OtherPolicy>::type const &
140 senf::ClientSocketHandle<SPolicy>::operator=(ClientSocketHandle<OtherPolicy> other)
141 {
142     assign(other);
143     return *this;
144 }
145 #else
146 template <class SPolicy>
147 template <class OtherPolicy>
148 prefix_ OtherPolicy const &
149 senf::ClientSocketHandle<SPolicy>::operator=(ClientSocketHandle<OtherPolicy> other)
150 {}
151 #endif
152
153 //-/////////////////////////////////////////////////////////////////////////////////////////////////
154 // reading and writing
155
156 // senf::ClientSocketHandle<SPolicy>::read
157
158 #ifndef DOXYGEN
159
160 template <class SPolicy>
161 template <class ForwardWritableRange>
162 prefix_ typename boost::disable_if<boost::is_convertible<ForwardWritableRange,unsigned>,
163 typename boost::range_iterator<ForwardWritableRange>::type>::type
164 senf::ClientSocketHandle<SPolicy>::read(ForwardWritableRange const & range)
165 {
166     return detail::ReadRange<
167         ClientSocketHandle<SPolicy>,
168         ForwardWritableRange const,
169         contiguous_storage_iterator<
170             typename boost::range_iterator<ForwardWritableRange>::type
171         >::value && sizeof(typename boost::range_value<ForwardWritableRange>::type)==sizeof(char)
172         >::read(*this, range);
173 }
174 #else
175 template <class SPolicy>
176 template <class ForwardWritableRange>
177 prefix_ typename boost::range_iterator<ForwardWritableRange>::type
178 senf::ClientSocketHandle<SPolicy>::
179 read(ForwardWritableRange const & range)
180 {}
181 #endif
182
183 #ifndef DOXYGEN
184 template <class SPolicy>
185 template <class ForwardWritableRange>
186 prefix_ typename boost::disable_if<boost::is_convertible<ForwardWritableRange,unsigned>,
187 typename boost::range_iterator<ForwardWritableRange>::type>::type
188 senf::ClientSocketHandle<SPolicy>::read(ForwardWritableRange & range)
189 {
190     return detail::ReadRange<
191         ClientSocketHandle<SPolicy>,
192         ForwardWritableRange,
193         contiguous_storage_iterator<
194             typename boost::range_iterator<ForwardWritableRange>::type
195         >::value && sizeof(typename boost::range_value<ForwardWritableRange>::type)==sizeof(char)
196         >::read(*this, range);
197 }
198 #else
199 template <class SPolicy>
200 template <class ForwardWritableRange>
201 prefix_ typename boost::range_iterator<ForwardWritableRange>::type
202 senf::ClientSocketHandle<SPolicy>::
203 read(ForwardWritableRange & range)
204 {}
205 #endif
206
207 template <class SPolicy>
208 prefix_ char * senf::ClientSocketHandle<SPolicy>::read(char * start, char * end)
209 {
210     return start + SPolicy::ReadPolicy::read(*this, start, end-start);
211 }
212
213 // senf::ClientSocketHandle<SPolicy>::readfrom
214
215 template <class SPolicy>
216 template <class ForwardWritableRange>
217 prefix_ typename boost::range_iterator<ForwardWritableRange const>::type
218 senf::ClientSocketHandle<SPolicy>::readfrom(ForwardWritableRange const & range, Address & from)
219 {
220     return detail::ReadRange<
221         ClientSocketHandle<SPolicy>,
222         ForwardWritableRange const,
223         contiguous_storage_iterator<
224             typename boost::range_iterator<ForwardWritableRange>::type
225         >::value && sizeof(typename boost::range_value<ForwardWritableRange>::type)==sizeof(char)
226         >::readfrom(*this, range, from);
227 }
228
229 template <class SPolicy>
230 template <class ForwardWritableRange>
231 prefix_ typename boost::range_iterator<ForwardWritableRange>::type
232 senf::ClientSocketHandle<SPolicy>::readfrom(ForwardWritableRange & range, Address & from)
233 {
234     return detail::ReadRange<
235         ClientSocketHandle<SPolicy>,
236         ForwardWritableRange,
237         contiguous_storage_iterator<
238             typename boost::range_iterator<ForwardWritableRange>::type
239         >::value && sizeof(typename boost::range_value<ForwardWritableRange>::type)==sizeof(char)
240         >::readfrom(*this, range, from);
241 }
242
243 template <class SPolicy>
244 prefix_ char * senf::ClientSocketHandle<SPolicy>::readfrom(char * start, char * end,
245                                                           Address & from)
246 {
247     return start + SPolicy::ReadPolicy::readfrom(*this, start, end-start, from);
248 }
249
250 // senf::ClientSocketHandle<SPolicy>::write
251
252 template <class SPolicy>
253 template <class ForwardReadableRange>
254 prefix_ typename boost::range_const_iterator<ForwardReadableRange const>::type
255 senf::ClientSocketHandle<SPolicy>::write(ForwardReadableRange const & range)
256 {
257     return detail::WriteRange<
258         ClientSocketHandle<SPolicy>,
259         ForwardReadableRange const,
260         contiguous_storage_iterator<
261             typename boost::range_iterator<ForwardReadableRange>::type
262         >::value && sizeof(typename boost::range_value<ForwardReadableRange>::type)==sizeof(char)
263         >::write(*this, range);
264 }
265
266 template <class SPolicy>
267 prefix_ char const * senf::ClientSocketHandle<SPolicy>::write(char const * start, char const * end)
268 {
269     return start + SPolicy::WritePolicy::write(*this, start, end-start);
270 }
271
272 // senf::ClientSocketHandle<SPolicy>::writeto
273
274 template <class SPolicy>
275 template <class ForwardReadableRange>
276 prefix_ typename boost::range_const_iterator<ForwardReadableRange const>::type
277 senf::ClientSocketHandle<SPolicy>::writeto(AddressParam addr, ForwardReadableRange const & range)
278 {
279     return detail::WriteRange<
280         ClientSocketHandle<SPolicy>,
281         ForwardReadableRange const,
282         contiguous_storage_iterator<
283             typename boost::range_iterator<ForwardReadableRange>::type
284         >::value && sizeof(typename boost::range_value<ForwardReadableRange>::type)==sizeof(char)
285         >::writeto(*this, range, addr);
286 }
287
288 template <class SPolicy>
289 prefix_ char const * senf::ClientSocketHandle<SPolicy>::writeto(AddressParam addr,
290                                                                char const * start,
291                                                                char const * end)
292 {
293     return start + SPolicy::WritePolicy::writeto(*this, addr, start, end-start);
294 }
295
296 //-/////////////////////////////////////////////////////////////////////////////////////////////////
297 // addressing
298
299 // senf::ClientSocketHandle<SPolicy>::peer
300
301 template <class SPolicy>
302 prefix_ typename SPolicy::AddressingPolicy::Address
303 senf::ClientSocketHandle<SPolicy>::peer()
304     const
305 {
306     typename SPolicy::AddressingPolicy::Address addr;
307     this->peer(addr);
308     return addr;
309 }
310
311 template <class SPolicy>
312 prefix_ void senf::ClientSocketHandle<SPolicy>::
313 peer(typename SPolicy::AddressingPolicy::Address & addr)
314     const
315 {
316     SPolicy::AddressingPolicy::peer(*this, addr);
317 }
318
319 // senf::ClientSocketHandle<SPolicy>::local
320
321 template <class SPolicy>
322 prefix_ typename SPolicy::AddressingPolicy::Address
323 senf::ClientSocketHandle<SPolicy>::local()
324     const
325 {
326     typename SPolicy::AddressingPolicy::Address addr;
327     this->local(addr);
328     return addr;
329 }
330
331 template <class SPolicy>
332 prefix_ void senf::ClientSocketHandle<SPolicy>::
333 local(typename SPolicy::AddressingPolicy::Address & addr)
334     const
335 {
336     SPolicy::AddressingPolicy::local(*this,addr);
337 }
338
339 // senf::ClientSocketHandle<SPolicy>::connect
340
341 template <class SPolicy>
342 prefix_ void senf::ClientSocketHandle<SPolicy>::connect(AddressParam addr)
343     const
344 {
345     SPolicy::AddressingPolicy::connect(*this, addr);
346 }
347
348 // senf::ClientSocketHandle<SPolicy>::bind
349
350 template <class SPolicy>
351 prefix_ void senf::ClientSocketHandle<SPolicy>::bind(AddressParam addr)
352     const
353 {
354     SPolicy::AddressingPolicy::bind(*this, addr);
355 }
356
357 //-/////////////////////////////////////////////////////////////////////////////////////////////////
358 // Casting
359
360 template <class SPolicy>
361 prefix_ senf::ClientSocketHandle<SPolicy>
362 senf::ClientSocketHandle<SPolicy>::cast_static(FileHandle handle)
363 {
364     return ClientSocketHandle(handle, true);
365 }
366
367 template <class SPolicy>
368 prefix_ senf::ClientSocketHandle<SPolicy>
369 senf::ClientSocketHandle<SPolicy>::cast_dynamic(FileHandle handle)
370 {
371     SocketHandle<SPolicy> h (SocketHandle<SPolicy>::cast_dynamic(handle));
372     if (static_cast<SocketBody&>(FileHandle::body(h)).isServer())
373         throw std::bad_cast();
374     return cast_static(handle);
375 }
376
377 //-/////////////////////////////////////////////////////////////////////////////////////////////////
378 // State information
379
380 template <class SPolicy>
381 prefix_ void senf::ClientSocketHandle<SPolicy>::state(SocketStateMap & map, unsigned lod)
382 {
383     map["handle"] = prettyName(typeid(*this));
384     if (this->valid()) {
385         map["valid"] << "true";
386         this->body().state(map,lod);
387     } else
388         map["valid"] << "false";
389 }
390
391 template <class SPolicy>
392 prefix_ std::string senf::ClientSocketHandle<SPolicy>::dumpState(unsigned lod)
393 {
394     SocketStateMap map;
395     state(map,lod);
396     return detail::dumpState(map);
397 }
398
399 //-/////////////////////////////////////////////////////////////////////////////////////////////////
400 #undef prefix_
401
402 \f
403 // Local Variables:
404 // mode: c++
405 // fill-column: 100
406 // c-file-style: "senf"
407 // indent-tabs-mode: nil
408 // ispell-local-dictionary: "american"
409 // compile-command: "scons -u test"
410 // comment-column: 40
411 // End: