2#include <ossia/detail/pod_vector.hpp> 
    3#include <ossia/network/sockets/writers.hpp> 
    5#include <boost/asio/error.hpp> 
    6#include <boost/asio/read.hpp> 
    7#include <boost/asio/streambuf.hpp> 
    8#include <boost/asio/write.hpp> 
   14  static const constexpr uint8_t eot = 192;
 
   15  static const constexpr uint8_t esc = 219;
 
   16  static const constexpr uint8_t esc_end = 220;
 
   17  static const constexpr uint8_t esc_esc = 221;
 
   20template <
typename Socket>
 
   24  boost::asio::streambuf m_data;
 
   25  ossia::pod_vector<char> m_decoded;
 
   33  explicit slip_decoder(Socket& socket)
 
   41    socket.async_read_some(
 
   42        boost::asio::mutable_buffer(m_data.prepare(1024)),
 
   43        [
this, f = std::move(f)](boost::system::error_code ec, std::size_t sz) 
mutable {
 
   44      if(!f.validate_stream(ec))
 
   52      receive(std::move(f));
 
   57  void process_bytes(
const F& f, std::size_t sz)
 
   59    auto begin = (
const uint8_t*)m_data.data().data();
 
   60    for(std::size_t i = 0; i < sz; i++)
 
   62      const uint8_t next_char = *begin;
 
   63      process_byte(f, next_char);
 
   70  void process_byte(
const F& f, 
const uint8_t next_char)
 
   79            m_status = reading_char;
 
   96            if(m_decoded.size() > 0)
 
   98              f((
const unsigned char*)m_decoded.data(), m_decoded.size());
 
  105            m_status = reading_esc;
 
  110            m_decoded.push_back(next_char);
 
  120            m_status = reading_char;
 
  121            m_decoded.push_back(slip::eot);
 
  125            m_status = reading_char;
 
  126            m_decoded.push_back(slip::esc);
 
  142template <
typename Socket>
 
  148  void write(
const char* data, std::size_t sz)
 
  150    this->write(socket, boost::asio::buffer(&slip::eot, 1));
 
  152    const uint8_t* begin = 
reinterpret_cast<const uint8_t*
>(data);
 
  153    const uint8_t* end = begin + sz;
 
  156      std::size_t written = this->write(begin, end);
 
  159    this->write(socket, boost::asio::buffer(&slip::eot, 1));
 
  162  std::size_t write(
const uint8_t* begin, 
const uint8_t* end)
 
  164    const uint8_t 
byte = *begin;
 
  168        const uint8_t data[2] = {slip::esc, slip::esc_end};
 
  169        this->write(socket, boost::asio::buffer(data, 2));
 
  173        const uint8_t data[2] = {slip::esc, slip::esc_esc};
 
  174        this->write(socket, boost::asio::buffer(data, 2));
 
  178        auto sub_end = begin + 1;
 
  179        while(sub_end != end && *sub_end != slip::eot && *sub_end != slip::esc)
 
  182        this->write(socket, boost::asio::buffer(begin, sub_end - begin));
 
  183        return sub_end - begin;
 
  188  template <
typename T>
 
  189  void write(T& sock, 
const boost::asio::const_buffer& buf)
 
  191    boost::asio::write(sock, buf);
 
  194  template <
typename T>
 
  195  void write(multi_socket_writer<T>& sock, 
const boost::asio::const_buffer& buf)
 
  203  template <
typename Socket>
 
  204  using encoder = slip_encoder<Socket>;
 
  205  template <
typename Socket>
 
  206  using decoder = slip_decoder<Socket>;