3#include <ossia/network/context.hpp> 
    4#include <ossia/network/sockets/configuration.hpp> 
    6#include <boost/asio/io_context.hpp> 
    7#include <boost/asio/ip/udp.hpp> 
    8#include <boost/asio/local/datagram_protocol.hpp> 
    9#include <boost/asio/local/stream_protocol.hpp> 
   10#include <boost/asio/placeholders.hpp> 
   11#include <boost/asio/strand.hpp> 
   12#include <boost/asio/write.hpp> 
   14#include <nano_signal_slot.hpp> 
   18#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) 
   19class unix_datagram_socket
 
   21  using proto = boost::asio::local::datagram_protocol;
 
   24  unix_datagram_socket(
const fd_configuration& conf, boost::asio::io_context& ctx)
 
   27      , m_socket{boost::asio::make_strand(ctx)}
 
   33    ::unlink(m_endpoint.path().data());
 
   35    m_socket.bind(m_endpoint);
 
   46    if(m_socket.is_open())
 
   48      boost::asio::post(m_context, [
this] {
 
   51          m_socket.shutdown(boost::asio::ip::udp::socket::shutdown_both);
 
   65    m_socket.async_receive_from(
 
   66        boost::asio::mutable_buffer(&m_data[0], std::size(m_data)), m_endpoint,
 
   67        [
this, f](boost::system::error_code ec, std::size_t sz) {
 
   68      if(ec == boost::asio::error::operation_aborted)
 
   84  void write(
const char* data, std::size_t sz)
 
   86    m_socket.send_to(boost::asio::buffer(data, sz), m_endpoint);
 
   89  Nano::Signal<void()> on_close;
 
   91  boost::asio::io_context& m_context;
 
   92  proto::endpoint m_endpoint;
 
   93  proto::socket m_socket;
 
   94  alignas(16) 
char m_data[65535];
 
   97class unix_stream_listener
 
  100  using proto = boost::asio::local::stream_protocol;
 
  101  unix_stream_listener() = 
delete;
 
  102  unix_stream_listener(
const unix_stream_listener&) = 
delete;
 
  103  unix_stream_listener& operator=(
const unix_stream_listener&) = 
delete;
 
  104  unix_stream_listener(unix_stream_listener&&) = 
default;
 
  105  unix_stream_listener& operator=(unix_stream_listener&&) = 
default;
 
  106  explicit unix_stream_listener(proto::socket sock)
 
  107      : m_socket{std::move(sock)}
 
  116      m_socket.shutdown(boost::asio::ip::udp::socket::shutdown_both);
 
  124  void write(
const boost::asio::const_buffer& buf) { boost::asio::write(m_socket, buf); }
 
  130  proto::socket m_socket;
 
  133class unix_stream_server
 
  136  using proto = boost::asio::local::stream_protocol;
 
  137  using listener = unix_stream_listener;
 
  138  [[no_unique_address]] 
struct ensure_reuse
 
  140    explicit ensure_reuse(
const proto::endpoint& endpoint)
 
  142      ::unlink(endpoint.path().data());
 
  146  unix_stream_server(
const fd_configuration& conf, boost::asio::io_context& ctx)
 
  147      : m_ensure_reuse{conf.fd}
 
  149      , m_acceptor{boost::asio::make_strand(ctx), conf.fd}
 
  153  unix_stream_server(
const fd_configuration& conf, ossia::net::network_context_ptr ctx)
 
  154      : unix_stream_server{conf, ctx->context}
 
  158  boost::asio::io_context& m_context;
 
  159  proto::acceptor m_acceptor;
 
  162class unix_stream_client
 
  165  using proto = boost::asio::local::stream_protocol;
 
  166  using socket = 
typename proto::socket;
 
  168  unix_stream_client(
const fd_configuration& conf, boost::asio::io_context& ctx)
 
  170      , m_endpoint{conf.fd}
 
  171      , m_socket{boost::asio::make_strand(ctx)}
 
  177    m_socket.connect(m_endpoint);
 
  181  bool connected()
 const { 
return m_connected; }
 
  185    boost::asio::post(m_context, [
this] {
 
  188        m_socket.shutdown(boost::asio::ip::udp::socket::shutdown_both);
 
  198  void write(
const char* data, std::size_t sz)
 
  200    boost::asio::write(m_socket, boost::asio::buffer(data, sz));
 
  203  Nano::Signal<void()> on_open;
 
  204  Nano::Signal<void()> on_close;
 
  205  Nano::Signal<void()> on_fail;
 
  207  boost::asio::io_context& m_context;
 
  208  proto::endpoint m_endpoint;
 
  209  proto::socket m_socket;
 
  210  bool m_connected{
false};