$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [Boost-users] Buffering and ASIO
From: Vadim Shmelev (vadim.shmelev_at_[hidden])
Date: 2008-12-15 06:44:33
Good day.I'm trying to read video data transferred by HTTP. I use the 
following function in order to read HTTP 
header:boost::asio::async_read_until(m_socket, m_headerBuffer, "\r\n\r\n", 
boost::bind(&CAXISParser::read_header, this, 
boost::asio::placeholders::error, 
boost::asio::placeholders::bytes_transferred));, where m_headerBuffer is 
asio::streambuf object. During header parsing i can get video sample length. 
Now I want to read all video data in one function call, for 
example:boost::asio::async_read(m_socket, 
boost::asio::buffer(pSample->GetBody(), m_currentSampleLength), 
boost::bind(&CAXISParser::read_body, this, pSample, 
boost::asio::placeholders::error, 
boost::asio::placeholders::bytes_transferred));, where pSample is object 
with buffer for video data. There is problem that async_read_until captures 
some data from video data, and that call's behavior is incorrect. How can i 
fight that problem? For example, how can i figure out number of bytes left 
in streambuf and copy them to my buffer, and then read rest with async_read? 
I'm will very appreciate for any advices.> It's not clear to me exactly what 
you're asking here.  From what I can
> tell, you have created a buffer of size m_currentSampleLength, and
> asked ASIO to call CAXISParser::read_body when it has received this
> many bytes.  Is that what you intended to do?  Is that what boost is
> doing?  Or is the problem something else?
>
> -----Scott.
Hello, Scott.
Sorry for bad english, i'm will try explain.
Yep, there is problem. When i'm read HTTP header with acync_read_until, it
consume header and some bytes from video data (i think). After i'm
calculate video data length from header and trying read data with
async_read. But it works incorrect as previous call async_read_until
captures some bytes from video data and video data readed with async_read
have wrong offset.
How can i understand, the problem that async_read_until and async_read
used different buffers for reading (asio::streambuf and custom buffer),
and some video data consumed by streambuf.
Question: how to get video data captured with async_read_until and read
rest from tcp buffer?There is is code sample:void read_header(PSample 
pSample,     const boost::system::error_code& error, size_t 
bytes_transferred){    // Calculate data length with regex 
boost::asio::const_buffer data = m_headerBuffer.data();    const char* beg = 
boost::asio::buffer_cast<const char*>(data);    const char* end = beg + 
bytes_transferred;    CalculateDataLength(beg, end);    // Clear buffer 
std::vector<char> vec(bytes_transferred);    m_headerBuffer.sgetn(&vec[0], 
bytes_transferred);    ReadBody();}Before ReadBody call, i reject streambuf 
content with sgetn. But i think there ismore data in streambuf that is video 
data. How can i get it? Below non working sample, but it describe my 
wishes:// Add before read bodysize_t restBytes = m_headerBuffer.size() - 
bytes_transferred;if (0 != restBytes){ 
m_headerBuffer.sgetn(pSample->GetBody(), restBytes);}Then in ReadBody i can 
to read rest video data with single async_readcall. There is implementation 
sample:void ReadBody(NMMSS::PSample& 
pSample){1)//boost::asio::async_read(m_socket, 
m_headerBuffer.prepare(m_currentSampleLength),2)//boost::asio::async_read_until(m_socket, 
m_headerBuffer, "\r\n",3)//boost::asio::async_read(m_socket, 
boost::asio::buffer(pSample->GetBody(), m_currentSampleLength), 
boost::bind(&CAXISParser::read_body, this,        pSample, 
boost::asio::placeholders::error, 
boost::asio::placeholders::bytes_transferred));}I trying use 3 variants 
there:1) Trying read to buffer all video data (dont understand why it 
doesn't work)2) Very slow variant, as video data is big.3) Preferrable 
variant
P.S. One question more: how can i correctly reject data consumed by
streambuf? Now i used the following strategy:
streambuf buf;
.....
std::vector<char> vec(size);
buf.sgetn(&vec[0], size);
Is there another strategy for that? For example, commit and consume 
strategy? I dont need streambuf content in some
cases.
Best regards,
Vadim