[英]Boost ASIO ForwardIterator for streambuf
I am using boost::asio::async_read_until
to read the \\n
-ended line from the TCP socket. 我正在使用
boost::asio::async_read_until
从TCP套接字读取\\n
-ended行。 Let me please recall that async_read_until
signature is the following: 我请记住,
async_read_until
签名如下:
http://www.boost.org/doc/libs/1_63_0/doc/html/boost_asio/reference.html#boost_asio.reference.async_read_until http://www.boost.org/doc/libs/1_63_0/doc/html/boost_asio/reference.html#boost_asio.reference.async_read_until
void-or-deduced async_read_until(
AsyncReadStream & s,
boost::asio::basic_streambuf< Allocator > & b,
char delim,
ReadHandler handler);
Here 这里
boost::asio::streambuf b;
is auto resized object to store received data. 是自动调整大小的对象来存储接收的数据。
As far as I understand, it internally consists of buffer sequence, a list of boost::asio buffers. 据我所知,它内部由缓冲序列,一个boost :: asio缓冲区列表组成。 However, there is no easy way to obtain ForwardIterator to iterate over this internal buffer that consists of multiple contiguous regions.
但是,没有简单的方法可以获得ForwardIterator来迭代这个由多个连续区域组成的内部缓冲区。
I find the following usage pattern: 我找到了以下用法模式:
std::istream stream(&b);
std::istream_iterator<char> end;
std::istream_iterator<char> begin(stream);
However, here end
and begin
are InputIterators. 但是,这里
end
并begin
是InputIterators。
At the same time, boost::spirit::phrase_parse(begin, end, grammar, space, obj)
parser that could be used to parse obtained from socked line requires begin
and end
be ForwardIterators: 与此同时,
boost::spirit::phrase_parse(begin, end, grammar, space, obj)
可以用来解析狠狠地从线上获取解析器需要begin
和end
是ForwardIterators:
http://www.boost.org/doc/libs/1_63_0/libs/spirit/doc/html/spirit/support/multi_pass.html http://www.boost.org/doc/libs/1_63_0/libs/spirit/doc/html/spirit/support/multi_pass.html
This is required for backtracking. 这是回溯所必需的。 However, the data are actually already stored in the memory buffer in
boost::asio::streambuf b
object, nothing prevents iterator from being dereferenced more than once. 但是,数据实际上已经存储在
boost::asio::streambuf b
对象的内存缓冲区中,没有什么能阻止迭代器被多次解除引用。
Boost has buffers_begin()
and buffers_end()
which you can use on streambuf
's data()
: Boost有
buffers_begin()
和buffers_end()
,你可以在streambuf
的data()
:
#include <boost/asio.hpp>
#include <boost/spirit/include/qi.hpp>
namespace a = boost::asio;
namespace qi = boost::spirit::qi;
#include <iostream>
int main()
{
a::streambuf input;
std::ostream(&input) << "123, 4, 5; 78, 8, 9;\n888, 8, 8;";
auto f = a::buffers_begin(input.data()), l = a::buffers_end(input.data());
//std::copy(f, l, std::ostream_iterator<char>(std::cout));
std::vector<std::vector<int> > parsed;
bool ok = qi::phrase_parse(f, l, *(qi::int_ % ',' >> ';'), qi::space, parsed);
if (ok) {
std::cout << "parsed: \n";
for (auto& row : parsed) {
for (auto& v : row) { std::cout << v << " "; }
std::cout << ";\n";
}
}
else
std::cout << "parse failed\n";
if (f!=l)
std::cout << "remaining unparsed input: '" << std::string(f,l) << "'\n";
}
Prints (as expected): 打印(如预期):
parsed:
123 4 5 ;
78 8 9 ;
888 8 8 ;
Note don't forget to consume()
the parsed portion of the input! 注意不要忘记
consume()
解析的输入部分!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.