2014-12-05 207 views
9

我試圖瞭解boost::asio::streambuf::consume()boost::asio::streambuf::commit()調用。在文檔中,我們有例子,何時調用boost :: asio :: streambuf :: consume()和boost :: asio :: streambuf :: commit()?

boost::asio::streambuf b; 
std::ostream os(&b); 
os << "Hello, World!\n"; 

// try sending some data in input sequence 
size_t n = sock.send(b.data()); 

b.consume(n); // sent data is removed from input sequence 

boost::asio::streambuf b; 

// reserve 512 bytes in output sequence 
boost::asio::streambuf::mutable_buffers_type bufs = b.prepare(512); 

size_t n = sock.receive(bufs); 

// received data is "committed" from output sequence to input sequence 
b.commit(n); 

std::istream is(&b); 
std::string s; 
is >> s; 

我理解這兩個電話,就像我明白什麼文件說,對他們 - 通話consume()從輸入序列中刪除角色在boost::asio::streambuf的內部,並調用commit()將字符從boost::asio::streambuf的輸出序列移動到其輸入序列。很公平。

我何時居然打電話給這些?縱觀boost::asio::read_until()源,我們有

template <typename SyncReadStream, typename Allocator> 
std::size_t read_until(SyncReadStream& s, 
    boost::asio::basic_streambuf<Allocator>& b, char delim, 
    boost::system::error_code& ec) 
{ 
    std::size_t search_position = 0; 
    for (;;) 
    { 
    // Determine the range of the data to be searched. 
    typedef typename boost::asio::basic_streambuf< 
     Allocator>::const_buffers_type const_buffers_type; 
    typedef boost::asio::buffers_iterator<const_buffers_type> iterator; 
    const_buffers_type buffers = b.data(); 
    iterator begin = iterator::begin(buffers); 
    iterator start_pos = begin + search_position; 
    iterator end = iterator::end(buffers); 

    // Look for a match. 
    iterator iter = std::find(start_pos, end, delim); 
    if (iter != end) 
    { 
     // Found a match. We're done. 
     ec = boost::system::error_code(); 
     return iter - begin + 1; 
    } 
    else 
    { 
     // No match. Next search can start with the new data. 
     search_position = end - begin; 
    } 

    // Check if buffer is full. 
    if (b.size() == b.max_size()) 
    { 
     ec = error::not_found; 
     return 0; 
    } 

    // Need more data. 
    std::size_t bytes_to_read = read_size_helper(b, 65536); 
    b.commit(s.read_some(b.prepare(bytes_to_read), ec)); 
    if (ec) 
     return 0; 
    } 
} 

你可以看到,作爲文檔中說,boost::asio::read_until()SyncReadStreamread_some()方面來實現。

對我來說,說

  1. SyncReadStream::read_some()不叫boost::asio::streambuf::commit()
  2. boost::asio::read_until()不會調用boost::asio::streambuf::commit()
  3. 這些都不似乎證明 - 無論是在boost::asio::read_until()的文件,也沒有在SyncReadStream「 s文檔。
  4. 我不知道我是否應該調用boost::asio::streambuf::commit()

與我的同步代碼我當然似乎並不需要它,而不是當我打電話免費功能boost::asio::read()boost::asio::read_until()。我在我的處理程序中使用異步代碼,主要是因爲我使用的示例有它,但是我不確定是否要調用它。當我嘗試使用boost::asio::streambufstringstreamstd::string時,commit()似乎沒有起作用 - 沒有任何事情會在streambuf上調用commit()而停止或停止。

任何人都可以爲我解決這個問題嗎?

+0

我希望看到一些關於此的明確文件。我找不到任何東西。 – EML 2017-04-11 15:30:53

回答

1

read_until在他的實施中使用read_some。因此,read_some調用streambuf::commitread_until不(直接)。

通常情況下,您不需要撥打commitconsume,但是如果您想對緩衝區數據執行某些操作,則可以這樣做。例如,如果您使用二進制協議,無法通過read_until進行正確檢查。

4

Asio定義了一個auxiliary free functions (read_xxx),它接受asio::streambuf,他們關心preparecommit它。

在另一方面,如果你想使用asio::streambuflower-level functions接受的MutableBufferSequence concept模型,你必須調用streambuf::prepare(),它返回滿足MutableBufferSequence概念的對象,通過這個對象作爲一個緩衝區,並經過該函數填充它 - 調用commit()。

在這兩種情況下,當您讀取streambufn字節的數據後,您必須調用consume(n) - 以消耗輸入序列。