Я использую boost::asio::async_read_until
, чтобы прочитать \n
исправленную строку из сокета TCP. Позвольте мне, пожалуйста, помните, что async_read_until
подпись следующее:Boost ASIO ForwardIterator для streambuf
void-or-deduced async_read_until(
AsyncReadStream & s,
boost::asio::basic_streambuf<Allocator> & b,
char delim,
ReadHandler handler);
Здесь
boost::asio::streambuf b;
является автоматическое изменения размера объекта для хранения полученных данных.
Насколько я понимаю, он внутренне состоит из последовательности буфера, списка буферов boost :: asio. Однако нет простого способа получить ForwardIterator для перебора этого внутреннего буфера, который состоит из нескольких смежных областей.
Я нахожу следующую схему использования:
std::istream stream(&b);
std::istream_iterator<char> end;
std::istream_iterator<char> begin(stream);
Однако здесь end
и begin
являются InputIterators.
В то же время, 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
Это требуется для возвратов. Однако данные на самом деле уже хранятся в буфере памяти в объекте boost::asio::streambuf b
, ничто не мешает итератору разыменоваться более одного раза.
Я мог бы написать свой собственный итератор (итерации по BufferSequenced элементам один за другим) и использовать b.data() для итерации по нему. Но, я думаю, должен быть стандартный способ ... – 0x2207
@Nim вы можете просто выполнить многопроходную адаптацию streambuf_iterator (точно так же boost :: spirit :: istream_iterator адаптирует istream_iterator). Но даже это не нужно. Буферные итераторы буфера Asio отвечают требованиям, см. Мой ответ. – sehe