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