2011-10-07 20 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クラスを作成することで問題を解決しました。できるだけ元のブーストの実装にできるだけ近いですが、よりパフォーマンスの高い実行につながるいくつかの調整があります。

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 */ 

だから、私はそれが誰かにとっても役立つことを願っています。

関連する問題