2011-10-07 26 views
1

async_read_until预计将读取数据的basic_streambuf。我不想分配额外的内存,但使用内存地址(来自指定接口,我不允许更改)作为目标缓冲区。如何使用boost :: asio :: async_read_until并将外部存储器地址用作缓冲区

是否有可能创建一个带有外部存储器地址的streambuf或者是否需要编写一个包装类?

+0

正在使用'async_read_until()'一个需求,或者您可以使用'async_read()'? –

+0

@Sam Miller - 不幸的是,使用'async_read_until()'似乎是一个需求。我需要读取可变数量的字节,直到我收到一个特定的分隔符。 – 0xbadf00d

回答

1

最后通过编写我自己的async_read_until_delim类来解决这个问题,该类需要一个内存指针和最大的字节数来读取。它尽可能接近原来的boost实现,但有一些调整应该导致更高性能的执行。

namespace { 

template<typename read_handler> 
class async_read_until_delim 
{ 
public: 
    async_read_until_delim(tcp::socket& socket, void* buffer, std::size_t max_read_size_in_bytes, 
     char delim, read_handler& handler) 
      : m_socket(socket), m_cur(static_cast<char*>(buffer)), 
       m_end(static_cast<char*>(buffer) + max_read_size_in_bytes), m_delim(delim), 
       m_handler(handler), m_pos(0) 
     { 
      read_some(); 
     } 
    async_read_until_delim(async_read_until_delim const& other) 
     : m_socket(other.m_socket), m_cur(other.m_cur), m_end(other.m_end), m_delim(other.m_delim), 
      m_handler(other.m_handler), m_pos(other.m_pos) 
     { 
     } 

    void operator()(boost::system::error_code const& error, std::size_t bytes_transferred) 
     { 
      if (!error) 
      {  
       if (std::find(m_cur, m_end, m_delim) != m_end) 
       { 
        m_handler(error, m_pos + bytes_transferred); 
        return; 
       } 
       else if (m_cur == m_end) 
       { 
        m_handler(boost::asio::error::not_found, -1); 
        return; 
       } 

       m_cur += bytes_transferred; 
       m_pos += bytes_transferred; 

       read_some(); 
      } 
      else 
       m_handler(error, m_pos); 
     } 

private: 
    void read_some() 
     { 
      m_socket.async_read_some(
       boost::asio::buffer(m_cur, m_end - m_cur), async_read_until_delim(*this)); 
     } 

    tcp::socket& m_socket; 
    char   *m_cur, 
       *m_end; 
    char   m_delim; 
    read_handler m_handler; 
    std::size_t m_pos; 
}; 

template<typename read_handler> 
inline void do_async_read_until_delim(tcp::socket& socket, void* buffer, std::size_t max_read_size_in_bytes, 
    char delim, read_handler& handler) 
{ 
    async_read_until_delim<read_handler>(socket, buffer, max_read_size_in_bytes, delim, handler); 
} 

} /* anonymous namespace */ 

所以,我希望它对于某人也是有用的。

相关问题