// // Copyright (c) 2024 Klemens Morgenstern (klemens.morgenstern@gmx.net) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef BOOST_COBALT_IOSOCKET_HPP #define BOOST_COBALT_IOSOCKET_HPP #include #include #include #include #include namespace boost::cobalt::io { struct BOOST_SYMBOL_VISIBLE socket { [[nodiscard]] system::result open(protocol_type prot = protocol_type {}); [[nodiscard]] system::result close(); [[nodiscard]] system::result cancel(); [[nodiscard]] bool is_open() const; // asio acceptor compatibility template struct rebind_executor {using other = socket;}; using shutdown_type = asio::socket_base::shutdown_type; using wait_type = asio::socket_base::wait_type; using message_flags = asio::socket_base::message_flags; constexpr static int message_peek = asio::socket_base::message_peek; constexpr static int message_out_of_band = asio::socket_base::message_out_of_band; constexpr static int message_do_not_route = asio::socket_base::message_do_not_route; constexpr static int message_end_of_record = asio::socket_base::message_end_of_record; using native_handle_type = asio::basic_socket::native_handle_type; BOOST_COBALT_IO_DECL native_handle_type native_handle(); [[nodiscard]] BOOST_COBALT_IO_DECL system::result shutdown(shutdown_type = shutdown_type::shutdown_both); [[nodiscard]] BOOST_COBALT_IO_DECL system::result local_endpoint() const; [[nodiscard]] BOOST_COBALT_IO_DECL system::result remote_endpoint() const; BOOST_COBALT_IO_DECL system::result assign(protocol_type protocol, native_handle_type native_handle); BOOST_COBALT_IO_DECL system::result release(); /// copied from what asio does [[nodiscard]] BOOST_COBALT_IO_DECL system::result bytes_readable(); [[nodiscard]] BOOST_COBALT_IO_DECL system::result set_debug(bool debug); [[nodiscard]] BOOST_COBALT_IO_DECL system::result get_debug() const; [[nodiscard]] BOOST_COBALT_IO_DECL system::result set_do_not_route(bool do_not_route); [[nodiscard]] BOOST_COBALT_IO_DECL system::result get_do_not_route() const; [[nodiscard]] BOOST_COBALT_IO_DECL system::result set_enable_connection_aborted(bool enable_connection_aborted); [[nodiscard]] BOOST_COBALT_IO_DECL system::result get_enable_connection_aborted() const; [[nodiscard]] BOOST_COBALT_IO_DECL system::result set_keep_alive(bool keep_alive); [[nodiscard]] BOOST_COBALT_IO_DECL system::result get_keep_alive() const; [[nodiscard]] BOOST_COBALT_IO_DECL system::result set_linger(bool linger, int timeout); [[nodiscard]] BOOST_COBALT_IO_DECL system::result> get_linger() const; [[nodiscard]] BOOST_COBALT_IO_DECL system::result set_receive_buffer_size(int receive_buffer_size); [[nodiscard]] BOOST_COBALT_IO_DECL system::result get_receive_buffer_size() const; [[nodiscard]] BOOST_COBALT_IO_DECL system::result set_send_buffer_size(int send_buffer_size); [[nodiscard]] BOOST_COBALT_IO_DECL system::result get_send_buffer_size() const; [[nodiscard]] BOOST_COBALT_IO_DECL system::result set_receive_low_watermark(int receive_low_watermark); [[nodiscard]] BOOST_COBALT_IO_DECL system::result get_receive_low_watermark() const; [[nodiscard]] BOOST_COBALT_IO_DECL system::result set_send_low_watermark(int send_low_watermark); [[nodiscard]] BOOST_COBALT_IO_DECL system::result get_send_low_watermark() const; [[nodiscard]] BOOST_COBALT_IO_DECL system::result set_reuse_address(bool reuse_address); [[nodiscard]] BOOST_COBALT_IO_DECL system::result get_reuse_address() const; [[nodiscard]] BOOST_COBALT_IO_DECL system::result set_no_delay(bool reuse_address); [[nodiscard]] BOOST_COBALT_IO_DECL system::result get_no_delay() const; struct BOOST_COBALT_IO_DECL wait_op final : op { wait_type wt; void ready(boost::cobalt::handler) final; void initiate(boost::cobalt::completion_handler) final; wait_op(wait_type wt, socket & sock) : wt(wt), sock_(sock) {} ~wait_op() = default; private: socket & sock_; }; [[nodiscard]] wait_op wait(wait_type wt = wait_type::wait_read) { return {wt, *this}; } struct BOOST_COBALT_IO_DECL connect_op final : op { struct endpoint endpoint; void initiate(boost::cobalt::completion_handler) final; connect_op(struct endpoint endpoint, socket & socket) : endpoint(endpoint), sock_(socket) {} ~connect_op() = default; private: socket & sock_; }; [[nodiscard]] connect_op connect(endpoint ep) { return {ep, *this}; } struct BOOST_COBALT_IO_DECL ranged_connect_op final : op { endpoint_sequence endpoints; void initiate(boost::cobalt::completion_handler) final; ranged_connect_op(endpoint_sequence eps, socket & socket) : endpoints(eps), sock_(socket) {} ~ranged_connect_op() = default; private: socket & sock_; }; [[nodiscard]] ranged_connect_op connect(endpoint_sequence ep) { return {std::move(ep), *this}; } protected: virtual void adopt_endpoint_(endpoint & ) {} socket(asio::basic_socket & socket) : socket_(socket) {} private: friend struct acceptor; asio::basic_socket & socket_; }; BOOST_COBALT_IO_DECL system::result connect_pair(protocol_type protocol, socket & socket1, socket & socket2); } #endif //BOOST_COBALT_IOSOCKET_HPP