Imported Upstream version 1.57.0
[platform/upstream/boost.git] / boost / asio / seq_packet_socket_service.hpp
1 //
2 // seq_packet_socket_service.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10
11 #ifndef BOOST_ASIO_SEQ_PACKET_SOCKET_SERVICE_HPP
12 #define BOOST_ASIO_SEQ_PACKET_SOCKET_SERVICE_HPP
13
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17
18 #include <boost/asio/detail/config.hpp>
19 #include <cstddef>
20 #include <boost/asio/async_result.hpp>
21 #include <boost/asio/detail/type_traits.hpp>
22 #include <boost/asio/error.hpp>
23 #include <boost/asio/io_service.hpp>
24
25 #if defined(BOOST_ASIO_WINDOWS_RUNTIME)
26 # include <boost/asio/detail/null_socket_service.hpp>
27 #elif defined(BOOST_ASIO_HAS_IOCP)
28 # include <boost/asio/detail/win_iocp_socket_service.hpp>
29 #else
30 # include <boost/asio/detail/reactive_socket_service.hpp>
31 #endif
32
33 #include <boost/asio/detail/push_options.hpp>
34
35 namespace boost {
36 namespace asio {
37
38 /// Default service implementation for a sequenced packet socket.
39 template <typename Protocol>
40 class seq_packet_socket_service
41 #if defined(GENERATING_DOCUMENTATION)
42   : public boost::asio::io_service::service
43 #else
44   : public boost::asio::detail::service_base<
45       seq_packet_socket_service<Protocol> >
46 #endif
47 {
48 public:
49 #if defined(GENERATING_DOCUMENTATION)
50   /// The unique service identifier.
51   static boost::asio::io_service::id id;
52 #endif
53
54   /// The protocol type.
55   typedef Protocol protocol_type;
56
57   /// The endpoint type.
58   typedef typename Protocol::endpoint endpoint_type;
59
60 private:
61   // The type of the platform-specific implementation.
62 #if defined(BOOST_ASIO_WINDOWS_RUNTIME)
63   typedef detail::null_socket_service<Protocol> service_impl_type;
64 #elif defined(BOOST_ASIO_HAS_IOCP)
65   typedef detail::win_iocp_socket_service<Protocol> service_impl_type;
66 #else
67   typedef detail::reactive_socket_service<Protocol> service_impl_type;
68 #endif
69
70 public:
71   /// The type of a sequenced packet socket implementation.
72 #if defined(GENERATING_DOCUMENTATION)
73   typedef implementation_defined implementation_type;
74 #else
75   typedef typename service_impl_type::implementation_type implementation_type;
76 #endif
77
78   /// (Deprecated: Use native_handle_type.) The native socket type.
79 #if defined(GENERATING_DOCUMENTATION)
80   typedef implementation_defined native_type;
81 #else
82   typedef typename service_impl_type::native_handle_type native_type;
83 #endif
84
85   /// The native socket type.
86 #if defined(GENERATING_DOCUMENTATION)
87   typedef implementation_defined native_handle_type;
88 #else
89   typedef typename service_impl_type::native_handle_type native_handle_type;
90 #endif
91
92   /// Construct a new sequenced packet socket service for the specified
93   /// io_service.
94   explicit seq_packet_socket_service(boost::asio::io_service& io_service)
95     : boost::asio::detail::service_base<
96         seq_packet_socket_service<Protocol> >(io_service),
97       service_impl_(io_service)
98   {
99   }
100
101   /// Construct a new sequenced packet socket implementation.
102   void construct(implementation_type& impl)
103   {
104     service_impl_.construct(impl);
105   }
106
107 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
108   /// Move-construct a new sequenced packet socket implementation.
109   void move_construct(implementation_type& impl,
110       implementation_type& other_impl)
111   {
112     service_impl_.move_construct(impl, other_impl);
113   }
114
115   /// Move-assign from another sequenced packet socket implementation.
116   void move_assign(implementation_type& impl,
117       seq_packet_socket_service& other_service,
118       implementation_type& other_impl)
119   {
120     service_impl_.move_assign(impl, other_service.service_impl_, other_impl);
121   }
122
123   /// Move-construct a new sequenced packet socket implementation from another
124   /// protocol type.
125   template <typename Protocol1>
126   void converting_move_construct(implementation_type& impl,
127       typename seq_packet_socket_service<
128         Protocol1>::implementation_type& other_impl,
129       typename enable_if<is_convertible<
130         Protocol1, Protocol>::value>::type* = 0)
131   {
132     service_impl_.template converting_move_construct<Protocol1>(
133         impl, other_impl);
134   }
135 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
136
137   /// Destroy a sequenced packet socket implementation.
138   void destroy(implementation_type& impl)
139   {
140     service_impl_.destroy(impl);
141   }
142
143   /// Open a sequenced packet socket.
144   boost::system::error_code open(implementation_type& impl,
145       const protocol_type& protocol, boost::system::error_code& ec)
146   {
147     if (protocol.type() == BOOST_ASIO_OS_DEF(SOCK_SEQPACKET))
148       service_impl_.open(impl, protocol, ec);
149     else
150       ec = boost::asio::error::invalid_argument;
151     return ec;
152   }
153
154   /// Assign an existing native socket to a sequenced packet socket.
155   boost::system::error_code assign(implementation_type& impl,
156       const protocol_type& protocol, const native_handle_type& native_socket,
157       boost::system::error_code& ec)
158   {
159     return service_impl_.assign(impl, protocol, native_socket, ec);
160   }
161
162   /// Determine whether the socket is open.
163   bool is_open(const implementation_type& impl) const
164   {
165     return service_impl_.is_open(impl);
166   }
167
168   /// Close a sequenced packet socket implementation.
169   boost::system::error_code close(implementation_type& impl,
170       boost::system::error_code& ec)
171   {
172     return service_impl_.close(impl, ec);
173   }
174
175   /// (Deprecated: Use native_handle().) Get the native socket implementation.
176   native_type native(implementation_type& impl)
177   {
178     return service_impl_.native_handle(impl);
179   }
180
181   /// Get the native socket implementation.
182   native_handle_type native_handle(implementation_type& impl)
183   {
184     return service_impl_.native_handle(impl);
185   }
186
187   /// Cancel all asynchronous operations associated with the socket.
188   boost::system::error_code cancel(implementation_type& impl,
189       boost::system::error_code& ec)
190   {
191     return service_impl_.cancel(impl, ec);
192   }
193
194   /// Determine whether the socket is at the out-of-band data mark.
195   bool at_mark(const implementation_type& impl,
196       boost::system::error_code& ec) const
197   {
198     return service_impl_.at_mark(impl, ec);
199   }
200
201   /// Determine the number of bytes available for reading.
202   std::size_t available(const implementation_type& impl,
203       boost::system::error_code& ec) const
204   {
205     return service_impl_.available(impl, ec);
206   }
207
208   /// Bind the sequenced packet socket to the specified local endpoint.
209   boost::system::error_code bind(implementation_type& impl,
210       const endpoint_type& endpoint, boost::system::error_code& ec)
211   {
212     return service_impl_.bind(impl, endpoint, ec);
213   }
214
215   /// Connect the sequenced packet socket to the specified endpoint.
216   boost::system::error_code connect(implementation_type& impl,
217       const endpoint_type& peer_endpoint, boost::system::error_code& ec)
218   {
219     return service_impl_.connect(impl, peer_endpoint, ec);
220   }
221
222   /// Start an asynchronous connect.
223   template <typename ConnectHandler>
224   BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler,
225       void (boost::system::error_code))
226   async_connect(implementation_type& impl,
227       const endpoint_type& peer_endpoint,
228       BOOST_ASIO_MOVE_ARG(ConnectHandler) handler)
229   {
230     detail::async_result_init<
231       ConnectHandler, void (boost::system::error_code)> init(
232         BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler));
233
234     service_impl_.async_connect(impl, peer_endpoint, init.handler);
235
236     return init.result.get();
237   }
238
239   /// Set a socket option.
240   template <typename SettableSocketOption>
241   boost::system::error_code set_option(implementation_type& impl,
242       const SettableSocketOption& option, boost::system::error_code& ec)
243   {
244     return service_impl_.set_option(impl, option, ec);
245   }
246
247   /// Get a socket option.
248   template <typename GettableSocketOption>
249   boost::system::error_code get_option(const implementation_type& impl,
250       GettableSocketOption& option, boost::system::error_code& ec) const
251   {
252     return service_impl_.get_option(impl, option, ec);
253   }
254
255   /// Perform an IO control command on the socket.
256   template <typename IoControlCommand>
257   boost::system::error_code io_control(implementation_type& impl,
258       IoControlCommand& command, boost::system::error_code& ec)
259   {
260     return service_impl_.io_control(impl, command, ec);
261   }
262
263   /// Gets the non-blocking mode of the socket.
264   bool non_blocking(const implementation_type& impl) const
265   {
266     return service_impl_.non_blocking(impl);
267   }
268
269   /// Sets the non-blocking mode of the socket.
270   boost::system::error_code non_blocking(implementation_type& impl,
271       bool mode, boost::system::error_code& ec)
272   {
273     return service_impl_.non_blocking(impl, mode, ec);
274   }
275
276   /// Gets the non-blocking mode of the native socket implementation.
277   bool native_non_blocking(const implementation_type& impl) const
278   {
279     return service_impl_.native_non_blocking(impl);
280   }
281
282   /// Sets the non-blocking mode of the native socket implementation.
283   boost::system::error_code native_non_blocking(implementation_type& impl,
284       bool mode, boost::system::error_code& ec)
285   {
286     return service_impl_.native_non_blocking(impl, mode, ec);
287   }
288
289   /// Get the local endpoint.
290   endpoint_type local_endpoint(const implementation_type& impl,
291       boost::system::error_code& ec) const
292   {
293     return service_impl_.local_endpoint(impl, ec);
294   }
295
296   /// Get the remote endpoint.
297   endpoint_type remote_endpoint(const implementation_type& impl,
298       boost::system::error_code& ec) const
299   {
300     return service_impl_.remote_endpoint(impl, ec);
301   }
302
303   /// Disable sends or receives on the socket.
304   boost::system::error_code shutdown(implementation_type& impl,
305       socket_base::shutdown_type what, boost::system::error_code& ec)
306   {
307     return service_impl_.shutdown(impl, what, ec);
308   }
309
310   /// Send the given data to the peer.
311   template <typename ConstBufferSequence>
312   std::size_t send(implementation_type& impl,
313       const ConstBufferSequence& buffers,
314       socket_base::message_flags flags, boost::system::error_code& ec)
315   {
316     return service_impl_.send(impl, buffers, flags, ec);
317   }
318
319   /// Start an asynchronous send.
320   template <typename ConstBufferSequence, typename WriteHandler>
321   BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
322       void (boost::system::error_code, std::size_t))
323   async_send(implementation_type& impl,
324       const ConstBufferSequence& buffers,
325       socket_base::message_flags flags,
326       BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
327   {
328     detail::async_result_init<
329       WriteHandler, void (boost::system::error_code, std::size_t)> init(
330         BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
331
332     service_impl_.async_send(impl, buffers, flags, init.handler);
333
334     return init.result.get();
335   }
336
337   /// Receive some data from the peer.
338   template <typename MutableBufferSequence>
339   std::size_t receive(implementation_type& impl,
340       const MutableBufferSequence& buffers, socket_base::message_flags in_flags,
341       socket_base::message_flags& out_flags, boost::system::error_code& ec)
342   {
343     return service_impl_.receive_with_flags(impl,
344         buffers, in_flags, out_flags, ec);
345   }
346
347   /// Start an asynchronous receive.
348   template <typename MutableBufferSequence, typename ReadHandler>
349   BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
350       void (boost::system::error_code, std::size_t))
351   async_receive(implementation_type& impl,
352       const MutableBufferSequence& buffers, socket_base::message_flags in_flags,
353       socket_base::message_flags& out_flags,
354       BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
355   {
356     detail::async_result_init<
357       ReadHandler, void (boost::system::error_code, std::size_t)> init(
358         BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
359
360     service_impl_.async_receive_with_flags(impl,
361         buffers, in_flags, out_flags, init.handler);
362
363     return init.result.get();
364   }
365
366 private:
367   // Destroy all user-defined handler objects owned by the service.
368   void shutdown_service()
369   {
370     service_impl_.shutdown_service();
371   }
372
373   // The platform-specific implementation.
374   service_impl_type service_impl_;
375 };
376
377 } // namespace asio
378 } // namespace boost
379
380 #include <boost/asio/detail/pop_options.hpp>
381
382 #endif // BOOST_ASIO_SEQ_PACKET_SOCKET_SERVICE_HPP