1 // 2 // detail/null_socket_service.hpp 3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4 // 5 // Copyright (c) 2003-2019 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 ASIO_DETAIL_NULL_SOCKET_SERVICE_HPP 12 #define ASIO_DETAIL_NULL_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 "asio/detail/config.hpp" 19 20 #if defined(ASIO_WINDOWS_RUNTIME) 21 22 #include "asio/buffer.hpp" 23 #include "asio/error.hpp" 24 #include "asio/execution_context.hpp" 25 #include "asio/post.hpp" 26 #include "asio/socket_base.hpp" 27 #include "asio/detail/bind_handler.hpp" 28 29 #include "asio/detail/push_options.hpp" 30 31 namespace asio { 32 namespace detail { 33 34 template <typename Protocol> 35 class null_socket_service : 36 public execution_context_service_base<null_socket_service<Protocol> > 37 { 38 public: 39 // The protocol type. 40 typedef Protocol protocol_type; 41 42 // The endpoint type. 43 typedef typename Protocol::endpoint endpoint_type; 44 45 // The native type of a socket. 46 typedef int native_handle_type; 47 48 // The implementation type of the socket. 49 struct implementation_type 50 { 51 }; 52 53 // Constructor. null_socket_service(execution_context & context)54 null_socket_service(execution_context& context) 55 : execution_context_service_base<null_socket_service<Protocol> >(context) 56 { 57 } 58 59 // Destroy all user-defined handler objects owned by the service. shutdown()60 void shutdown() 61 { 62 } 63 64 // Construct a new socket implementation. construct(implementation_type &)65 void construct(implementation_type&) 66 { 67 } 68 69 // Move-construct a new socket implementation. move_construct(implementation_type &,implementation_type &)70 void move_construct(implementation_type&, implementation_type&) 71 { 72 } 73 74 // Move-assign from another socket implementation. move_assign(implementation_type &,null_socket_service &,implementation_type &)75 void move_assign(implementation_type&, 76 null_socket_service&, implementation_type&) 77 { 78 } 79 80 // Move-construct a new socket implementation from another protocol type. 81 template <typename Protocol1> converting_move_construct(implementation_type &,null_socket_service<Protocol1> &,typename null_socket_service<Protocol1>::implementation_type &)82 void converting_move_construct(implementation_type&, 83 null_socket_service<Protocol1>&, 84 typename null_socket_service<Protocol1>::implementation_type&) 85 { 86 } 87 88 // Destroy a socket implementation. destroy(implementation_type &)89 void destroy(implementation_type&) 90 { 91 } 92 93 // Open a new socket implementation. open(implementation_type &,const protocol_type &,asio::error_code & ec)94 asio::error_code open(implementation_type&, 95 const protocol_type&, asio::error_code& ec) 96 { 97 ec = asio::error::operation_not_supported; 98 return ec; 99 } 100 101 // Assign a native socket to a socket implementation. assign(implementation_type &,const protocol_type &,const native_handle_type &,asio::error_code & ec)102 asio::error_code assign(implementation_type&, const protocol_type&, 103 const native_handle_type&, asio::error_code& ec) 104 { 105 ec = asio::error::operation_not_supported; 106 return ec; 107 } 108 109 // Determine whether the socket is open. is_open(const implementation_type &) const110 bool is_open(const implementation_type&) const 111 { 112 return false; 113 } 114 115 // Destroy a socket implementation. close(implementation_type &,asio::error_code & ec)116 asio::error_code close(implementation_type&, 117 asio::error_code& ec) 118 { 119 ec = asio::error::operation_not_supported; 120 return ec; 121 } 122 123 // Release ownership of the socket. release(implementation_type &,asio::error_code & ec)124 native_handle_type release(implementation_type&, 125 asio::error_code& ec) 126 { 127 ec = asio::error::operation_not_supported; 128 return 0; 129 } 130 131 // Get the native socket representation. native_handle(implementation_type &)132 native_handle_type native_handle(implementation_type&) 133 { 134 return 0; 135 } 136 137 // Cancel all operations associated with the socket. cancel(implementation_type &,asio::error_code & ec)138 asio::error_code cancel(implementation_type&, 139 asio::error_code& ec) 140 { 141 ec = asio::error::operation_not_supported; 142 return ec; 143 } 144 145 // Determine whether the socket is at the out-of-band data mark. at_mark(const implementation_type &,asio::error_code & ec) const146 bool at_mark(const implementation_type&, 147 asio::error_code& ec) const 148 { 149 ec = asio::error::operation_not_supported; 150 return false; 151 } 152 153 // Determine the number of bytes available for reading. available(const implementation_type &,asio::error_code & ec) const154 std::size_t available(const implementation_type&, 155 asio::error_code& ec) const 156 { 157 ec = asio::error::operation_not_supported; 158 return 0; 159 } 160 161 // Place the socket into the state where it will listen for new connections. listen(implementation_type &,int,asio::error_code & ec)162 asio::error_code listen(implementation_type&, 163 int, asio::error_code& ec) 164 { 165 ec = asio::error::operation_not_supported; 166 return ec; 167 } 168 169 // Perform an IO control command on the socket. 170 template <typename IO_Control_Command> io_control(implementation_type &,IO_Control_Command &,asio::error_code & ec)171 asio::error_code io_control(implementation_type&, 172 IO_Control_Command&, asio::error_code& ec) 173 { 174 ec = asio::error::operation_not_supported; 175 return ec; 176 } 177 178 // Gets the non-blocking mode of the socket. non_blocking(const implementation_type &) const179 bool non_blocking(const implementation_type&) const 180 { 181 return false; 182 } 183 184 // Sets the non-blocking mode of the socket. non_blocking(implementation_type &,bool,asio::error_code & ec)185 asio::error_code non_blocking(implementation_type&, 186 bool, asio::error_code& ec) 187 { 188 ec = asio::error::operation_not_supported; 189 return ec; 190 } 191 192 // Gets the non-blocking mode of the native socket implementation. native_non_blocking(const implementation_type &) const193 bool native_non_blocking(const implementation_type&) const 194 { 195 return false; 196 } 197 198 // Sets the non-blocking mode of the native socket implementation. native_non_blocking(implementation_type &,bool,asio::error_code & ec)199 asio::error_code native_non_blocking(implementation_type&, 200 bool, asio::error_code& ec) 201 { 202 ec = asio::error::operation_not_supported; 203 return ec; 204 } 205 206 // Disable sends or receives on the socket. shutdown(implementation_type &,socket_base::shutdown_type,asio::error_code & ec)207 asio::error_code shutdown(implementation_type&, 208 socket_base::shutdown_type, asio::error_code& ec) 209 { 210 ec = asio::error::operation_not_supported; 211 return ec; 212 } 213 214 // Bind the socket to the specified local endpoint. bind(implementation_type &,const endpoint_type &,asio::error_code & ec)215 asio::error_code bind(implementation_type&, 216 const endpoint_type&, asio::error_code& ec) 217 { 218 ec = asio::error::operation_not_supported; 219 return ec; 220 } 221 222 // Set a socket option. 223 template <typename Option> set_option(implementation_type &,const Option &,asio::error_code & ec)224 asio::error_code set_option(implementation_type&, 225 const Option&, asio::error_code& ec) 226 { 227 ec = asio::error::operation_not_supported; 228 return ec; 229 } 230 231 // Set a socket option. 232 template <typename Option> get_option(const implementation_type &,Option &,asio::error_code & ec) const233 asio::error_code get_option(const implementation_type&, 234 Option&, asio::error_code& ec) const 235 { 236 ec = asio::error::operation_not_supported; 237 return ec; 238 } 239 240 // Get the local endpoint. local_endpoint(const implementation_type &,asio::error_code & ec) const241 endpoint_type local_endpoint(const implementation_type&, 242 asio::error_code& ec) const 243 { 244 ec = asio::error::operation_not_supported; 245 return endpoint_type(); 246 } 247 248 // Get the remote endpoint. remote_endpoint(const implementation_type &,asio::error_code & ec) const249 endpoint_type remote_endpoint(const implementation_type&, 250 asio::error_code& ec) const 251 { 252 ec = asio::error::operation_not_supported; 253 return endpoint_type(); 254 } 255 256 // Send the given data to the peer. 257 template <typename ConstBufferSequence> send(implementation_type &,const ConstBufferSequence &,socket_base::message_flags,asio::error_code & ec)258 std::size_t send(implementation_type&, const ConstBufferSequence&, 259 socket_base::message_flags, asio::error_code& ec) 260 { 261 ec = asio::error::operation_not_supported; 262 return 0; 263 } 264 265 // Wait until data can be sent without blocking. send(implementation_type &,const null_buffers &,socket_base::message_flags,asio::error_code & ec)266 std::size_t send(implementation_type&, const null_buffers&, 267 socket_base::message_flags, asio::error_code& ec) 268 { 269 ec = asio::error::operation_not_supported; 270 return 0; 271 } 272 273 // Start an asynchronous send. The data being sent must be valid for the 274 // lifetime of the asynchronous operation. 275 template <typename ConstBufferSequence, typename Handler, typename IoExecutor> async_send(implementation_type &,const ConstBufferSequence &,socket_base::message_flags,Handler & handler,const IoExecutor & io_ex)276 void async_send(implementation_type&, const ConstBufferSequence&, 277 socket_base::message_flags, Handler& handler, const IoExecutor& io_ex) 278 { 279 asio::error_code ec = asio::error::operation_not_supported; 280 const std::size_t bytes_transferred = 0; 281 asio::post(io_ex, detail::bind_handler( 282 handler, ec, bytes_transferred)); 283 } 284 285 // Start an asynchronous wait until data can be sent without blocking. 286 template <typename Handler, typename IoExecutor> async_send(implementation_type &,const null_buffers &,socket_base::message_flags,Handler & handler,const IoExecutor & io_ex)287 void async_send(implementation_type&, const null_buffers&, 288 socket_base::message_flags, Handler& handler, const IoExecutor& io_ex) 289 { 290 asio::error_code ec = asio::error::operation_not_supported; 291 const std::size_t bytes_transferred = 0; 292 asio::post(io_ex, detail::bind_handler( 293 handler, ec, bytes_transferred)); 294 } 295 296 // Receive some data from the peer. Returns the number of bytes received. 297 template <typename MutableBufferSequence> receive(implementation_type &,const MutableBufferSequence &,socket_base::message_flags,asio::error_code & ec)298 std::size_t receive(implementation_type&, const MutableBufferSequence&, 299 socket_base::message_flags, asio::error_code& ec) 300 { 301 ec = asio::error::operation_not_supported; 302 return 0; 303 } 304 305 // Wait until data can be received without blocking. receive(implementation_type &,const null_buffers &,socket_base::message_flags,asio::error_code & ec)306 std::size_t receive(implementation_type&, const null_buffers&, 307 socket_base::message_flags, asio::error_code& ec) 308 { 309 ec = asio::error::operation_not_supported; 310 return 0; 311 } 312 313 // Start an asynchronous receive. The buffer for the data being received 314 // must be valid for the lifetime of the asynchronous operation. 315 template <typename MutableBufferSequence, 316 typename Handler, typename IoExecutor> async_receive(implementation_type &,const MutableBufferSequence &,socket_base::message_flags,Handler & handler,const IoExecutor & io_ex)317 void async_receive(implementation_type&, const MutableBufferSequence&, 318 socket_base::message_flags, Handler& handler, const IoExecutor& io_ex) 319 { 320 asio::error_code ec = asio::error::operation_not_supported; 321 const std::size_t bytes_transferred = 0; 322 asio::post(io_ex, detail::bind_handler( 323 handler, ec, bytes_transferred)); 324 } 325 326 // Wait until data can be received without blocking. 327 template <typename Handler, typename IoExecutor> async_receive(implementation_type &,const null_buffers &,socket_base::message_flags,Handler & handler,const IoExecutor & io_ex)328 void async_receive(implementation_type&, const null_buffers&, 329 socket_base::message_flags, Handler& handler, const IoExecutor& io_ex) 330 { 331 asio::error_code ec = asio::error::operation_not_supported; 332 const std::size_t bytes_transferred = 0; 333 asio::post(io_ex, detail::bind_handler( 334 handler, ec, bytes_transferred)); 335 } 336 337 // Receive some data with associated flags. Returns the number of bytes 338 // received. 339 template <typename MutableBufferSequence> receive_with_flags(implementation_type &,const MutableBufferSequence &,socket_base::message_flags,socket_base::message_flags &,asio::error_code & ec)340 std::size_t receive_with_flags(implementation_type&, 341 const MutableBufferSequence&, socket_base::message_flags, 342 socket_base::message_flags&, asio::error_code& ec) 343 { 344 ec = asio::error::operation_not_supported; 345 return 0; 346 } 347 348 // Wait until data can be received without blocking. receive_with_flags(implementation_type &,const null_buffers &,socket_base::message_flags,socket_base::message_flags &,asio::error_code & ec)349 std::size_t receive_with_flags(implementation_type&, 350 const null_buffers&, socket_base::message_flags, 351 socket_base::message_flags&, asio::error_code& ec) 352 { 353 ec = asio::error::operation_not_supported; 354 return 0; 355 } 356 357 // Start an asynchronous receive. The buffer for the data being received 358 // must be valid for the lifetime of the asynchronous operation. 359 template <typename MutableBufferSequence, 360 typename Handler, typename IoExecutor> async_receive_with_flags(implementation_type &,const MutableBufferSequence &,socket_base::message_flags,socket_base::message_flags &,Handler & handler,const IoExecutor & io_ex)361 void async_receive_with_flags(implementation_type&, 362 const MutableBufferSequence&, socket_base::message_flags, 363 socket_base::message_flags&, Handler& handler, const IoExecutor& io_ex) 364 { 365 asio::error_code ec = asio::error::operation_not_supported; 366 const std::size_t bytes_transferred = 0; 367 asio::post(io_ex, detail::bind_handler( 368 handler, ec, bytes_transferred)); 369 } 370 371 // Wait until data can be received without blocking. 372 template <typename Handler, typename IoExecutor> async_receive_with_flags(implementation_type &,const null_buffers &,socket_base::message_flags,socket_base::message_flags &,Handler & handler,const IoExecutor & io_ex)373 void async_receive_with_flags(implementation_type&, const null_buffers&, 374 socket_base::message_flags, socket_base::message_flags&, 375 Handler& handler, const IoExecutor& io_ex) 376 { 377 asio::error_code ec = asio::error::operation_not_supported; 378 const std::size_t bytes_transferred = 0; 379 asio::post(io_ex, detail::bind_handler( 380 handler, ec, bytes_transferred)); 381 } 382 383 // Send a datagram to the specified endpoint. Returns the number of bytes 384 // sent. 385 template <typename ConstBufferSequence> send_to(implementation_type &,const ConstBufferSequence &,const endpoint_type &,socket_base::message_flags,asio::error_code & ec)386 std::size_t send_to(implementation_type&, const ConstBufferSequence&, 387 const endpoint_type&, socket_base::message_flags, 388 asio::error_code& ec) 389 { 390 ec = asio::error::operation_not_supported; 391 return 0; 392 } 393 394 // Wait until data can be sent without blocking. send_to(implementation_type &,const null_buffers &,const endpoint_type &,socket_base::message_flags,asio::error_code & ec)395 std::size_t send_to(implementation_type&, const null_buffers&, 396 const endpoint_type&, socket_base::message_flags, 397 asio::error_code& ec) 398 { 399 ec = asio::error::operation_not_supported; 400 return 0; 401 } 402 403 // Start an asynchronous send. The data being sent must be valid for the 404 // lifetime of the asynchronous operation. 405 template <typename ConstBufferSequence, typename Handler, typename IoExecutor> async_send_to(implementation_type &,const ConstBufferSequence &,const endpoint_type &,socket_base::message_flags,Handler & handler)406 void async_send_to(implementation_type&, const ConstBufferSequence&, 407 const endpoint_type&, socket_base::message_flags, 408 Handler& handler) 409 { 410 asio::error_code ec = asio::error::operation_not_supported; 411 const std::size_t bytes_transferred = 0; 412 asio::post(io_ex, detail::bind_handler( 413 handler, ec, bytes_transferred)); 414 } 415 416 // Start an asynchronous wait until data can be sent without blocking. 417 template <typename Handler, typename IoExecutor> async_send_to(implementation_type &,const null_buffers &,const endpoint_type &,socket_base::message_flags,Handler & handler,const IoExecutor & io_ex)418 void async_send_to(implementation_type&, const null_buffers&, 419 const endpoint_type&, socket_base::message_flags, 420 Handler& handler, const IoExecutor& io_ex) 421 { 422 asio::error_code ec = asio::error::operation_not_supported; 423 const std::size_t bytes_transferred = 0; 424 asio::post(io_ex, detail::bind_handler( 425 handler, ec, bytes_transferred)); 426 } 427 428 // Receive a datagram with the endpoint of the sender. Returns the number of 429 // bytes received. 430 template <typename MutableBufferSequence> receive_from(implementation_type &,const MutableBufferSequence &,endpoint_type &,socket_base::message_flags,asio::error_code & ec)431 std::size_t receive_from(implementation_type&, const MutableBufferSequence&, 432 endpoint_type&, socket_base::message_flags, 433 asio::error_code& ec) 434 { 435 ec = asio::error::operation_not_supported; 436 return 0; 437 } 438 439 // Wait until data can be received without blocking. receive_from(implementation_type &,const null_buffers &,endpoint_type &,socket_base::message_flags,asio::error_code & ec)440 std::size_t receive_from(implementation_type&, const null_buffers&, 441 endpoint_type&, socket_base::message_flags, 442 asio::error_code& ec) 443 { 444 ec = asio::error::operation_not_supported; 445 return 0; 446 } 447 448 // Start an asynchronous receive. The buffer for the data being received and 449 // the sender_endpoint object must both be valid for the lifetime of the 450 // asynchronous operation. 451 template <typename MutableBufferSequence, 452 typename Handler, typename IoExecutor> async_receive_from(implementation_type &,const MutableBufferSequence &,endpoint_type &,socket_base::message_flags,Handler & handler,const IoExecutor & io_ex)453 void async_receive_from(implementation_type&, const MutableBufferSequence&, 454 endpoint_type&, socket_base::message_flags, Handler& handler, 455 const IoExecutor& io_ex) 456 { 457 asio::error_code ec = asio::error::operation_not_supported; 458 const std::size_t bytes_transferred = 0; 459 asio::post(io_ex, detail::bind_handler( 460 handler, ec, bytes_transferred)); 461 } 462 463 // Wait until data can be received without blocking. 464 template <typename Handler, typename IoExecutor> async_receive_from(implementation_type &,const null_buffers &,endpoint_type &,socket_base::message_flags,Handler & handler,const IoExecutor & io_ex)465 void async_receive_from(implementation_type&, const null_buffers&, 466 endpoint_type&, socket_base::message_flags, Handler& handler, 467 const IoExecutor& io_ex) 468 { 469 asio::error_code ec = asio::error::operation_not_supported; 470 const std::size_t bytes_transferred = 0; 471 asio::post(io_ex, detail::bind_handler( 472 handler, ec, bytes_transferred)); 473 } 474 475 // Accept a new connection. 476 template <typename Socket> accept(implementation_type &,Socket &,endpoint_type *,asio::error_code & ec)477 asio::error_code accept(implementation_type&, 478 Socket&, endpoint_type*, asio::error_code& ec) 479 { 480 ec = asio::error::operation_not_supported; 481 return ec; 482 } 483 484 // Start an asynchronous accept. The peer and peer_endpoint objects 485 // must be valid until the accept's handler is invoked. 486 template <typename Socket, typename Handler, typename IoExecutor> async_accept(implementation_type &,Socket &,endpoint_type *,Handler & handler,const IoExecutor & io_ex)487 void async_accept(implementation_type&, Socket&, endpoint_type*, 488 Handler& handler, const IoExecutor& io_ex) 489 { 490 asio::error_code ec = asio::error::operation_not_supported; 491 asio::post(io_ex, detail::bind_handler(handler, ec)); 492 } 493 494 // Connect the socket to the specified endpoint. connect(implementation_type &,const endpoint_type &,asio::error_code & ec)495 asio::error_code connect(implementation_type&, 496 const endpoint_type&, asio::error_code& ec) 497 { 498 ec = asio::error::operation_not_supported; 499 return ec; 500 } 501 502 // Start an asynchronous connect. 503 template <typename Handler, typename IoExecutor> async_connect(implementation_type &,const endpoint_type &,Handler & handler,const IoExecutor & io_ex)504 void async_connect(implementation_type&, const endpoint_type&, 505 Handler& handler, const IoExecutor& io_ex) 506 { 507 asio::error_code ec = asio::error::operation_not_supported; 508 asio::post(io_ex, detail::bind_handler(handler, ec)); 509 } 510 }; 511 512 } // namespace detail 513 } // namespace asio 514 515 #include "asio/detail/pop_options.hpp" 516 517 #endif // defined(ASIO_WINDOWS_RUNTIME) 518 519 #endif // ASIO_DETAIL_NULL_SOCKET_SERVICE_HPP 520