7ab7a706a233c6282748bd91272e11b0553b0f20
[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 template <class SPolicy>
160 template <class ForwardWritableRange>
161 prefix_ typename boost::range_iterator<ForwardWritableRange>::type
162 senf::ClientSocketHandle<SPolicy>::
163 read(ForwardWritableRange const & range,
164      typename boost::disable_if< boost::is_convertible<ForwardWritableRange,unsigned> >::type *)
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::range_iterator<ForwardWritableRange>::type
187 senf::ClientSocketHandle<SPolicy>::
188 read(ForwardWritableRange & range,
189      typename boost::disable_if< boost::is_convertible<ForwardWritableRange,unsigned> >::type *)
190 {
191     return detail::ReadRange<
192         ClientSocketHandle<SPolicy>,
193         ForwardWritableRange,
194         contiguous_storage_iterator<
195             typename boost::range_iterator<ForwardWritableRange>::type
196         >::value && sizeof(typename boost::range_value<ForwardWritableRange>::type)==sizeof(char)
197         >::read(*this, range);
198 }
199 #else
200 template <class SPolicy>
201 template <class ForwardWritableRange>
202 prefix_ typename boost::range_iterator<ForwardWritableRange>::type
203 senf::ClientSocketHandle<SPolicy>::
204 read(ForwardWritableRange & range)
205 {}
206 #endif
207
208 template <class SPolicy>
209 prefix_ char * senf::ClientSocketHandle<SPolicy>::read(char * start, char * end)
210 {
211     return start + SPolicy::ReadPolicy::read(*this, start, end-start);
212 }
213
214 // senf::ClientSocketHandle<SPolicy>::readfrom
215
216 template <class SPolicy>
217 template <class ForwardWritableRange>
218 prefix_ typename boost::range_iterator<ForwardWritableRange const>::type
219 senf::ClientSocketHandle<SPolicy>::readfrom(ForwardWritableRange const & range, Address & from)
220 {
221     return detail::ReadRange<
222         ClientSocketHandle<SPolicy>,
223         ForwardWritableRange const,
224         contiguous_storage_iterator<
225             typename boost::range_iterator<ForwardWritableRange>::type
226         >::value && sizeof(typename boost::range_value<ForwardWritableRange>::type)==sizeof(char)
227         >::readfrom(*this, range, from);
228 }
229
230 template <class SPolicy>
231 template <class ForwardWritableRange>
232 prefix_ typename boost::range_iterator<ForwardWritableRange>::type
233 senf::ClientSocketHandle<SPolicy>::readfrom(ForwardWritableRange & range, Address & from)
234 {
235     return detail::ReadRange<
236         ClientSocketHandle<SPolicy>,
237         ForwardWritableRange,
238         contiguous_storage_iterator<
239             typename boost::range_iterator<ForwardWritableRange>::type
240         >::value && sizeof(typename boost::range_value<ForwardWritableRange>::type)==sizeof(char)
241         >::readfrom(*this, range, from);
242 }
243
244 template <class SPolicy>
245 prefix_ char * senf::ClientSocketHandle<SPolicy>::readfrom(char * start, char * end,
246                                                           Address & from)
247 {
248     return start + SPolicy::ReadPolicy::readfrom(*this, start, end-start, from);
249 }
250
251 // senf::ClientSocketHandle<SPolicy>::write
252
253 template <class SPolicy>
254 template <class ForwardReadableRange>
255 prefix_ typename boost::range_const_iterator<ForwardReadableRange const>::type
256 senf::ClientSocketHandle<SPolicy>::write(ForwardReadableRange const & range)
257 {
258     return detail::WriteRange<
259         ClientSocketHandle<SPolicy>,
260         ForwardReadableRange const,
261         contiguous_storage_iterator<
262             typename boost::range_iterator<ForwardReadableRange>::type
263         >::value && sizeof(typename boost::range_value<ForwardReadableRange>::type)==sizeof(char)
264         >::write(*this, range);
265 }
266
267 template <class SPolicy>
268 prefix_ char const * senf::ClientSocketHandle<SPolicy>::write(char const * start, char const * end)
269 {
270     return start + SPolicy::WritePolicy::write(*this, start, end-start);
271 }
272
273 // senf::ClientSocketHandle<SPolicy>::writeto
274
275 template <class SPolicy>
276 template <class ForwardReadableRange>
277 prefix_ typename boost::range_const_iterator<ForwardReadableRange const>::type
278 senf::ClientSocketHandle<SPolicy>::writeto(AddressParam addr, ForwardReadableRange const & range)
279 {
280     return detail::WriteRange<
281         ClientSocketHandle<SPolicy>,
282         ForwardReadableRange const,
283         contiguous_storage_iterator<
284             typename boost::range_iterator<ForwardReadableRange>::type
285         >::value && sizeof(typename boost::range_value<ForwardReadableRange>::type)==sizeof(char)
286         >::writeto(*this, range, addr);
287 }
288
289 template <class SPolicy>
290 prefix_ char const * senf::ClientSocketHandle<SPolicy>::writeto(AddressParam addr,
291                                                                char const * start,
292                                                                char const * end)
293 {
294     return start + SPolicy::WritePolicy::writeto(*this, addr, start, end-start);
295 }
296
297 //-/////////////////////////////////////////////////////////////////////////////////////////////////
298 // addressing
299
300 // senf::ClientSocketHandle<SPolicy>::peer
301
302 template <class SPolicy>
303 prefix_ typename SPolicy::AddressingPolicy::Address
304 senf::ClientSocketHandle<SPolicy>::peer()
305     const
306 {
307     typename SPolicy::AddressingPolicy::Address addr;
308     this->peer(addr);
309     return addr;
310 }
311
312 template <class SPolicy>
313 prefix_ void senf::ClientSocketHandle<SPolicy>::
314 peer(typename SPolicy::AddressingPolicy::Address & addr)
315     const
316 {
317     SPolicy::AddressingPolicy::peer(*this, addr);
318 }
319
320 // senf::ClientSocketHandle<SPolicy>::local
321
322 template <class SPolicy>
323 prefix_ typename SPolicy::AddressingPolicy::Address
324 senf::ClientSocketHandle<SPolicy>::local()
325     const
326 {
327     typename SPolicy::AddressingPolicy::Address addr;
328     this->local(addr);
329     return addr;
330 }
331
332 template <class SPolicy>
333 prefix_ void senf::ClientSocketHandle<SPolicy>::
334 local(typename SPolicy::AddressingPolicy::Address & addr)
335     const
336 {
337     SPolicy::AddressingPolicy::local(*this,addr);
338 }
339
340 // senf::ClientSocketHandle<SPolicy>::connect
341
342 template <class SPolicy>
343 prefix_ void senf::ClientSocketHandle<SPolicy>::connect(AddressParam addr)
344     const
345 {
346     SPolicy::AddressingPolicy::connect(*this, addr);
347 }
348
349 // senf::ClientSocketHandle<SPolicy>::bind
350
351 template <class SPolicy>
352 prefix_ void senf::ClientSocketHandle<SPolicy>::bind(AddressParam addr)
353     const
354 {
355     SPolicy::AddressingPolicy::bind(*this, addr);
356 }
357
358 //-/////////////////////////////////////////////////////////////////////////////////////////////////
359 // Casting
360
361 template <class SPolicy>
362 prefix_ senf::ClientSocketHandle<SPolicy>
363 senf::ClientSocketHandle<SPolicy>::cast_static(FileHandle handle)
364 {
365     return ClientSocketHandle(handle, true);
366 }
367
368 template <class SPolicy>
369 prefix_ senf::ClientSocketHandle<SPolicy>
370 senf::ClientSocketHandle<SPolicy>::cast_dynamic(FileHandle handle)
371 {
372     SocketHandle<SPolicy> h (SocketHandle<SPolicy>::cast_dynamic(handle));
373     if (static_cast<SocketBody&>(FileHandle::body(h)).isServer())
374         throw std::bad_cast();
375     return cast_static(handle);
376 }
377
378 //-/////////////////////////////////////////////////////////////////////////////////////////////////
379 // State information
380
381 template <class SPolicy>
382 prefix_ void senf::ClientSocketHandle<SPolicy>::state(SocketStateMap & map, unsigned lod)
383 {
384     map["handle"] = prettyName(typeid(*this));
385     if (this->valid()) {
386         map["valid"] << "true";
387         this->body().state(map,lod);
388     } else
389         map["valid"] << "false";
390 }
391
392 template <class SPolicy>
393 prefix_ std::string senf::ClientSocketHandle<SPolicy>::dumpState(unsigned lod)
394 {
395     SocketStateMap map;
396     state(map,lod);
397     return detail::dumpState(map);
398 }
399
400 //-/////////////////////////////////////////////////////////////////////////////////////////////////
401 #undef prefix_
402
403 \f
404 // Local Variables:
405 // mode: c++
406 // fill-column: 100
407 // c-file-style: "senf"
408 // indent-tabs-mode: nil
409 // ispell-local-dictionary: "american"
410 // compile-command: "scons -u test"
411 // comment-column: 40
412 // End: