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 ClientSocketHandle inline template implementation
18 #include "ClientSocketHandle.ih"
23 #define prefix_ inline
24 //-/////////////////////////////////////////////////////////////////////////////////////////////////
26 //-/////////////////////////////////////////////////////////////////////////////////////////////////
27 // senf::detail::ReadRange<Policy,ForwardWritableRange,true>
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)
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))) )
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)
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))),
54 //-/////////////////////////////////////////////////////////////////////////////////////////////////
55 // senf::detail::WriteRange<Handle, ForwardReadableRange, true>
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)
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);
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)
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);
85 //-/////////////////////////////////////////////////////////////////////////////////////////////////
86 // senf::ClientSocketHandle<Policy>
88 //-/////////////////////////////////////////////////////////////////////////////////////////////////
91 template <class SPolicy>
92 prefix_ senf::ClientSocketHandle<SPolicy>::ClientSocketHandle()
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)
104 template <class SPolicy>
105 template <class OtherPolicy>
106 prefix_ senf::ClientSocketHandle<SPolicy>::
107 ClientSocketHandle(ClientSocketHandle<OtherPolicy> other)
111 template <class SPolicy>
112 prefix_ senf::ClientSocketHandle<SPolicy>::ClientSocketHandle(FileHandle other, bool isChecked)
113 : SocketHandle<SPolicy>(other, isChecked)
116 template <class SPolicy>
118 senf::ClientSocketHandle<SPolicy>::ClientSocketHandle(std::unique_ptr<SocketBody> body)
119 : SocketHandle<SPolicy>(std::move(body))
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)
132 template <class SPolicy>
133 template <class OtherPolicy>
134 prefix_ OtherPolicy const &
135 senf::ClientSocketHandle<SPolicy>::operator=(ClientSocketHandle<OtherPolicy> other)
139 //-/////////////////////////////////////////////////////////////////////////////////////////////////
140 // reading and writing
142 // senf::ClientSocketHandle<SPolicy>::read
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)
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);
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)
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)
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);
185 template <class SPolicy>
186 template <class ForwardWritableRange>
187 prefix_ typename boost::range_iterator<ForwardWritableRange>::type
188 senf::ClientSocketHandle<SPolicy>::
189 read(ForwardWritableRange & range)
193 template <class SPolicy>
194 prefix_ char * senf::ClientSocketHandle<SPolicy>::read(char * start, char * end)
196 return start + SPolicy::ReadPolicy::read(*this, start, end-start);
199 // senf::ClientSocketHandle<SPolicy>::readfrom
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)
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);
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)
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);
229 template <class SPolicy>
230 prefix_ char * senf::ClientSocketHandle<SPolicy>::readfrom(char * start, char * end,
233 return start + SPolicy::ReadPolicy::readfrom(*this, start, end-start, from);
236 // senf::ClientSocketHandle<SPolicy>::write
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)
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);
252 template <class SPolicy>
253 prefix_ char const * senf::ClientSocketHandle<SPolicy>::write(char const * start, char const * end)
255 return start + SPolicy::WritePolicy::write(*this, start, end-start);
258 // senf::ClientSocketHandle<SPolicy>::writeto
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)
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);
274 template <class SPolicy>
275 prefix_ char const * senf::ClientSocketHandle<SPolicy>::writeto(AddressParam addr,
279 return start + SPolicy::WritePolicy::writeto(*this, addr, start, end-start);
282 //-/////////////////////////////////////////////////////////////////////////////////////////////////
283 // queue based read/write
285 template <class SPolicy>
286 prefix_ boost::optional<typename SPolicy::ReadPolicy::Buffer>
287 senf::ClientSocketHandle<SPolicy>::dequeue()
289 return SPolicy::ReadPolicy::dequeue(*this);
292 template <class SPolicy>
293 prefix_ void senf::ClientSocketHandle<SPolicy>::release()
295 return SPolicy::ReadPolicy::release(*this);
298 template <class SPolicy>
299 prefix_ boost::optional<typename SPolicy::WritePolicy::Buffer>
300 senf::ClientSocketHandle<SPolicy>::enqueue()
302 return SPolicy::WritePolicy::enqueue(*this);
305 template <class SPolicy>
306 prefix_ bool senf::ClientSocketHandle<SPolicy>::send()
308 return SPolicy::WritePolicy::send(*this);
311 //-/////////////////////////////////////////////////////////////////////////////////////////////////
314 // senf::ClientSocketHandle<SPolicy>::peer
316 template <class SPolicy>
317 prefix_ typename SPolicy::AddressingPolicy::Address
318 senf::ClientSocketHandle<SPolicy>::peer()
321 typename SPolicy::AddressingPolicy::Address addr;
326 template <class SPolicy>
327 prefix_ void senf::ClientSocketHandle<SPolicy>::
328 peer(typename SPolicy::AddressingPolicy::Address & addr)
331 SPolicy::AddressingPolicy::peer(*this, addr);
334 // senf::ClientSocketHandle<SPolicy>::local
336 template <class SPolicy>
337 prefix_ typename SPolicy::AddressingPolicy::Address
338 senf::ClientSocketHandle<SPolicy>::local()
341 typename SPolicy::AddressingPolicy::Address addr;
346 template <class SPolicy>
347 prefix_ void senf::ClientSocketHandle<SPolicy>::
348 local(typename SPolicy::AddressingPolicy::Address & addr)
351 SPolicy::AddressingPolicy::local(*this,addr);
354 // senf::ClientSocketHandle<SPolicy>::connect
356 template <class SPolicy>
357 prefix_ void senf::ClientSocketHandle<SPolicy>::connect(AddressParam addr)
360 SPolicy::AddressingPolicy::connect(*this, addr);
363 // senf::ClientSocketHandle<SPolicy>::bind
365 template <class SPolicy>
366 prefix_ void senf::ClientSocketHandle<SPolicy>::bind(AddressParam addr)
369 SPolicy::AddressingPolicy::bind(*this, addr);
372 //-/////////////////////////////////////////////////////////////////////////////////////////////////
375 template <class SPolicy>
376 prefix_ senf::ClientSocketHandle<SPolicy>
377 senf::ClientSocketHandle<SPolicy>::cast_static(FileHandle handle)
379 return ClientSocketHandle(handle, true);
382 template <class SPolicy>
383 prefix_ senf::ClientSocketHandle<SPolicy>
384 senf::ClientSocketHandle<SPolicy>::cast_dynamic(FileHandle handle)
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);
392 //-/////////////////////////////////////////////////////////////////////////////////////////////////
395 template <class SPolicy>
396 prefix_ void senf::ClientSocketHandle<SPolicy>::state(SocketStateMap & map, unsigned lod)
398 map["handle"] = prettyName(typeid(*this));
400 map["valid"] << "true";
401 this->body().state(map,lod);
403 map["valid"] << "false";
406 template <class SPolicy>
407 prefix_ std::string senf::ClientSocketHandle<SPolicy>::dumpState(unsigned lod)
411 return detail::dumpState(map);
414 //-/////////////////////////////////////////////////////////////////////////////////////////////////
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