1 // 2 // detail/winrt_ssocket_service.hpp 3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4 // 5 // Copyright (c) 2003-2015 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. implementation_typeboost::asio::detail::winrt_ssocket_service::implementation_type53 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. winrt_ssocket_service(boost::asio::io_service & io_service)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. move_construct(implementation_type & impl,implementation_type & other_impl)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. move_assign(implementation_type & impl,winrt_ssocket_service & other_service,implementation_type & other_impl)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> converting_move_construct(implementation_type & impl,typename winrt_ssocket_service<Protocol1>::implementation_type & other_impl)92 void converting_move_construct(implementation_type& impl, 93 typename winrt_ssocket_service< 94 Protocol1>::implementation_type& other_impl) 95 { 96 this->base_move_construct(impl, other_impl); 97 98 impl.protocol_ = protocol_type(other_impl.protocol_); 99 other_impl.protocol_ = typename Protocol1::endpoint().protocol(); 100 } 101 102 // Open a new socket implementation. open(implementation_type & impl,const protocol_type & protocol,boost::system::error_code & ec)103 boost::system::error_code open(implementation_type& impl, 104 const protocol_type& protocol, boost::system::error_code& ec) 105 { 106 if (is_open(impl)) 107 { 108 ec = boost::asio::error::already_open; 109 return ec; 110 } 111 112 try 113 { 114 impl.socket_ = ref new Windows::Networking::Sockets::StreamSocket; 115 impl.protocol_ = protocol; 116 ec = boost::system::error_code(); 117 } 118 catch (Platform::Exception^ e) 119 { 120 ec = boost::system::error_code(e->HResult, 121 boost::system::system_category()); 122 } 123 124 return ec; 125 } 126 127 // Assign a native socket to a socket implementation. assign(implementation_type & impl,const protocol_type & protocol,const native_handle_type & native_socket,boost::system::error_code & ec)128 boost::system::error_code assign(implementation_type& impl, 129 const protocol_type& protocol, const native_handle_type& native_socket, 130 boost::system::error_code& ec) 131 { 132 if (is_open(impl)) 133 { 134 ec = boost::asio::error::already_open; 135 return ec; 136 } 137 138 impl.socket_ = native_socket; 139 impl.protocol_ = protocol; 140 ec = boost::system::error_code(); 141 142 return ec; 143 } 144 145 // Bind the socket to the specified local endpoint. bind(implementation_type &,const endpoint_type &,boost::system::error_code & ec)146 boost::system::error_code bind(implementation_type&, 147 const endpoint_type&, boost::system::error_code& ec) 148 { 149 ec = boost::asio::error::operation_not_supported; 150 return ec; 151 } 152 153 // Get the local endpoint. local_endpoint(const implementation_type & impl,boost::system::error_code & ec) const154 endpoint_type local_endpoint(const implementation_type& impl, 155 boost::system::error_code& ec) const 156 { 157 endpoint_type endpoint; 158 endpoint.resize(do_get_endpoint(impl, true, 159 endpoint.data(), endpoint.size(), ec)); 160 return endpoint; 161 } 162 163 // Get the remote endpoint. remote_endpoint(const implementation_type & impl,boost::system::error_code & ec) const164 endpoint_type remote_endpoint(const implementation_type& impl, 165 boost::system::error_code& ec) const 166 { 167 endpoint_type endpoint; 168 endpoint.resize(do_get_endpoint(impl, false, 169 endpoint.data(), endpoint.size(), ec)); 170 return endpoint; 171 } 172 173 // Set a socket option. 174 template <typename Option> set_option(implementation_type & impl,const Option & option,boost::system::error_code & ec)175 boost::system::error_code set_option(implementation_type& impl, 176 const Option& option, boost::system::error_code& ec) 177 { 178 return do_set_option(impl, option.level(impl.protocol_), 179 option.name(impl.protocol_), option.data(impl.protocol_), 180 option.size(impl.protocol_), ec); 181 } 182 183 // Get a socket option. 184 template <typename Option> get_option(const implementation_type & impl,Option & option,boost::system::error_code & ec) const185 boost::system::error_code get_option(const implementation_type& impl, 186 Option& option, boost::system::error_code& ec) const 187 { 188 std::size_t size = option.size(impl.protocol_); 189 do_get_option(impl, option.level(impl.protocol_), 190 option.name(impl.protocol_), 191 option.data(impl.protocol_), &size, ec); 192 if (!ec) 193 option.resize(impl.protocol_, size); 194 return ec; 195 } 196 197 // Connect the socket to the specified endpoint. connect(implementation_type & impl,const endpoint_type & peer_endpoint,boost::system::error_code & ec)198 boost::system::error_code connect(implementation_type& impl, 199 const endpoint_type& peer_endpoint, boost::system::error_code& ec) 200 { 201 return do_connect(impl, peer_endpoint.data(), ec); 202 } 203 204 // Start an asynchronous connect. 205 template <typename Handler> async_connect(implementation_type & impl,const endpoint_type & peer_endpoint,Handler & handler)206 void async_connect(implementation_type& impl, 207 const endpoint_type& peer_endpoint, Handler& handler) 208 { 209 bool is_continuation = 210 boost_asio_handler_cont_helpers::is_continuation(handler); 211 212 // Allocate and construct an operation to wrap the handler. 213 typedef winrt_socket_connect_op<Handler> op; 214 typename op::ptr p = { boost::asio::detail::addressof(handler), 215 boost_asio_handler_alloc_helpers::allocate( 216 sizeof(op), handler), 0 }; 217 p.p = new (p.v) op(handler); 218 219 BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_connect")); 220 221 start_connect_op(impl, peer_endpoint.data(), p.p, is_continuation); 222 p.v = p.p = 0; 223 } 224 }; 225 226 } // namespace detail 227 } // namespace asio 228 } // namespace boost 229 230 #include <boost/asio/detail/pop_options.hpp> 231 232 #endif // defined(BOOST_ASIO_WINDOWS_RUNTIME) 233 234 #endif // BOOST_ASIO_DETAIL_WINRT_SSOCKET_SERVICE_HPP 235