Самый простой способ реализовать настоящий импульс :: asio :: async_read_until - PullRequest
0 голосов
/ 27 марта 2012

Какой самый простой способ реализовать версию boost :: asio :: async_read_until, которая читает только до тех пор, пока не найден разделитель? Могу ли я реализовать специальное условие сопоставления, которое знает, как использовать правильное количество байтов? Если нет, то как мне написать асинхронный ридер, который проверяет каждый байт?

Мне нужно, чтобы предоставляемый streambuf не использовал байты за разделителем.

Ответы [ 3 ]

1 голос
/ 27 марта 2012

В документации вы можете найти простую функцию сопоставления:

std::pair<iterator, bool>
match_whitespace(iterator begin, iterator end)
{
  iterator i = begin;
  while (i != end)
    if (std::isspace(*i++))
      return std::make_pair(i, true);
  return std::make_pair(i, false);
}

В этом случае он соответствует любому пробелу (измените std :: isspace в соответствии с тем, что вы хотите). Опять же, в этой документации вы можете увидеть более сложное событие, оно потребляет поток, пока не найдет определенный символ:

class match_char
{
public:
  explicit match_char(char c) : c_(c) {}

  template <typename Iterator>
  std::pair<Iterator, bool> operator()(
      Iterator begin, Iterator end) const
  {
    Iterator i = begin;
    while (i != end)
      if (c_ == *i++)
        return std::make_pair(i, true);
    return std::make_pair(i, false);
  }

private:
  char c_;
};

И код для использования этого класса:

// Function used for error handling
void handler(const boost::system::error_code& e, std::size_t size)
{
 // Do something
}

// Example of call, it reads from inputStream to outputStreamBuff
// until the specified delimiter (";") is found
boost::asio::async_read_until(inputStream, outputStreamBuff,
   match_char(';'), handler);
0 голосов
/ 09 ноября 2017

Я хотел бы отметить, что ЗАМЕЧАНИЕ в этом документе на самом деле неверно, независимо от того, сколько раз я его проверял.

Замечания После успешной операции async_read_untilпотоковый буфер может содержать дополнительные данные, помимо тех, которые соответствуют объекту функции.Приложение обычно оставляет эти данные в streambuf для последующей операции async_read_until для проверки.

Функтор MatchCondition должен потреблять все, что есть в streambuf, не оставляя неиспользованные байты для следующего async_read_until ()вызов или ваше приложение может ждать вечно.

ps настройка тестирования: x86-64 centos4.3 kernel-2.6.32 gcc4.8

0 голосов
/ 27 марта 2012

Мне нужно, чтобы предоставляемый потоковый буфер не потреблял байты за пределами разделителя.

Единственный способ сделать это - (неэффективно) читать по одному байту за раз из потока,Я бы не предложил этот подход, документация легко описывает, как обрабатывать этот сценарий

После успешной операции async_read_until, streambuf может содержать дополнительные данные помимо разделителя.Приложение обычно оставляет эти данные в streambuf для последующей операции async_read_until для проверки.

, именно это и делает асинхронный http-клиент пример .

...