Imported Upstream version 1.64.0
[platform/upstream/boost.git] / boost / asio / detail / winrt_ssocket_service.hpp
1 //
2 // detail/winrt_ssocket_service.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2017 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_DETAIL_WINRT_SSOCKET_SERVICE_HPP
12 #define BOOST_ASIO_DETAIL_WINRT_SSOCKET_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
20 #if defined(BOOST_ASIO_WINDOWS_RUNTIME)
21
22 #include <boost/asio/error.hpp>
23 #include <boost/asio/io_service.hpp>
24 #include <boost/asio/detail/addressof.hpp>
25 #include <boost/asio/detail/winrt_socket_connect_op.hpp>
26 #include <boost/asio/detail/winrt_ssocket_service_base.hpp>
27 #include <boost/asio/detail/winrt_utils.hpp>
28
29 #include <boost/asio/detail/push_options.hpp>
30
31 namespace boost {
32 namespace asio {
33 namespace detail {
34
35 template <typename Protocol>
36 class winrt_ssocket_service :
37   public winrt_ssocket_service_base
38 {
39 public:
40   // The protocol type.
41   typedef Protocol protocol_type;
42
43   // The endpoint type.
44   typedef typename Protocol::endpoint endpoint_type;
45
46   // The native type of a socket.
47   typedef Windows::Networking::Sockets::StreamSocket^ native_handle_type;
48
49   // The implementation type of the socket.
50   struct implementation_type : base_implementation_type
51   {
52     // Default constructor.
53     implementation_type()
54       : base_implementation_type(),
55         protocol_(endpoint_type().protocol())
56     {
57     }
58
59     // The protocol associated with the socket.
60     protocol_type protocol_;
61   };
62
63   // Constructor.
64   winrt_ssocket_service(boost::asio::io_service& io_service)
65     : winrt_ssocket_service_base(io_service)
66   {
67   }
68
69   // Move-construct a new socket implementation.
70   void move_construct(implementation_type& impl,
71       implementation_type& other_impl)
72   {
73     this->base_move_construct(impl, other_impl);
74
75     impl.protocol_ = other_impl.protocol_;
76     other_impl.protocol_ = endpoint_type().protocol();
77   }
78
79   // Move-assign from another socket implementation.
80   void move_assign(implementation_type& impl,
81       winrt_ssocket_service& other_service,
82       implementation_type& other_impl)
83   {
84     this->base_move_assign(impl, other_service, other_impl);
85
86     impl.protocol_ = other_impl.protocol_;
87     other_impl.protocol_ = endpoint_type().protocol();
88   }
89
90   // Move-construct a new socket implementation from another protocol type.
91   template <typename Protocol1>
92   void converting_move_construct(implementation_type& impl,
93       winrt_ssocket_service<Protocol1>&,
94       typename winrt_ssocket_service<
95         Protocol1>::implementation_type& other_impl)
96   {
97     this->base_move_construct(impl, other_impl);
98
99     impl.protocol_ = protocol_type(other_impl.protocol_);
100     other_impl.protocol_ = typename Protocol1::endpoint().protocol();
101   }
102
103   // Open a new socket implementation.
104   boost::system::error_code open(implementation_type& impl,
105       const protocol_type& protocol, boost::system::error_code& ec)
106   {
107     if (is_open(impl))
108     {
109       ec = boost::asio::error::already_open;
110       return ec;
111     }
112
113     try
114     {
115       impl.socket_ = ref new Windows::Networking::Sockets::StreamSocket;
116       impl.protocol_ = protocol;
117       ec = boost::system::error_code();
118     }
119     catch (Platform::Exception^ e)
120     {
121       ec = boost::system::error_code(e->HResult,
122             boost::system::system_category());
123     }
124
125     return ec;
126   }
127
128   // Assign a native socket to a socket implementation.
129   boost::system::error_code assign(implementation_type& impl,
130       const protocol_type& protocol, const native_handle_type& native_socket,
131       boost::system::error_code& ec)
132   {
133     if (is_open(impl))
134     {
135       ec = boost::asio::error::already_open;
136       return ec;
137     }
138
139     impl.socket_ = native_socket;
140     impl.protocol_ = protocol;
141     ec = boost::system::error_code();
142
143     return ec;
144   }
145
146   // Bind the socket to the specified local endpoint.
147   boost::system::error_code bind(implementation_type&,
148       const endpoint_type&, boost::system::error_code& ec)
149   {
150     ec = boost::asio::error::operation_not_supported;
151     return ec;
152   }
153
154   // Get the local endpoint.
155   endpoint_type local_endpoint(const implementation_type& impl,
156       boost::system::error_code& ec) const
157   {
158     endpoint_type endpoint;
159     endpoint.resize(do_get_endpoint(impl, true,
160           endpoint.data(), endpoint.size(), ec));
161     return endpoint;
162   }
163
164   // Get the remote endpoint.
165   endpoint_type remote_endpoint(const implementation_type& impl,
166       boost::system::error_code& ec) const
167   {
168     endpoint_type endpoint;
169     endpoint.resize(do_get_endpoint(impl, false,
170           endpoint.data(), endpoint.size(), ec));
171     return endpoint;
172   }
173
174   // Set a socket option.
175   template <typename Option>
176   boost::system::error_code set_option(implementation_type& impl,
177       const Option& option, boost::system::error_code& ec)
178   {
179     return do_set_option(impl, option.level(impl.protocol_),
180         option.name(impl.protocol_), option.data(impl.protocol_),
181         option.size(impl.protocol_), ec);
182   }
183
184   // Get a socket option.
185   template <typename Option>
186   boost::system::error_code get_option(const implementation_type& impl,
187       Option& option, boost::system::error_code& ec) const
188   {
189     std::size_t size = option.size(impl.protocol_);
190     do_get_option(impl, option.level(impl.protocol_),
191         option.name(impl.protocol_),
192         option.data(impl.protocol_), &size, ec);
193     if (!ec)
194       option.resize(impl.protocol_, size);
195     return ec;
196   }
197
198   // Connect the socket to the specified endpoint.
199   boost::system::error_code connect(implementation_type& impl,
200       const endpoint_type& peer_endpoint, boost::system::error_code& ec)
201   {
202     return do_connect(impl, peer_endpoint.data(), ec);
203   }
204
205   // Start an asynchronous connect.
206   template <typename Handler>
207   void async_connect(implementation_type& impl,
208       const endpoint_type& peer_endpoint, Handler& handler)
209   {
210     bool is_continuation =
211       boost_asio_handler_cont_helpers::is_continuation(handler);
212
213     // Allocate and construct an operation to wrap the handler.
214     typedef winrt_socket_connect_op<Handler> op;
215     typename op::ptr p = { boost::asio::detail::addressof(handler),
216       boost_asio_handler_alloc_helpers::allocate(
217         sizeof(op), handler), 0 };
218     p.p = new (p.v) op(handler);
219
220     BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_connect"));
221
222     start_connect_op(impl, peer_endpoint.data(), p.p, is_continuation);
223     p.v = p.p = 0;
224   }
225 };
226
227 } // namespace detail
228 } // namespace asio
229 } // namespace boost
230
231 #include <boost/asio/detail/pop_options.hpp>
232
233 #endif // defined(BOOST_ASIO_WINDOWS_RUNTIME)
234
235 #endif // BOOST_ASIO_DETAIL_WINRT_SSOCKET_SERVICE_HPP