Boost C++ 库

…是全球最受尊敬、设计最精良的 C++ 库项目之一。 Herb SutterAndrei AlexandrescuC++ Coding Standards

read_until (24 个重载中的第 23 个) - Boost C++ 函数库
PrevUpHomeNext

将数据读取到动态缓冲区序列中,直到函数对象指示匹配。

template<
    typename SyncReadStream,
    typename DynamicBuffer_v2,
    typename MatchCondition>
std::size_t read_until(
    SyncReadStream & s,
    DynamicBuffer_v2 buffers,
    MatchCondition match_condition,
    constraint_t< is_match_condition< MatchCondition >::value >  = 0,
    constraint_t< is_dynamic_buffer_v2< DynamicBuffer_v2 >::value >  = 0);

此函数用于将数据读取到指定的动态缓冲区序列中,直到用户定义的匹配条件函数对象应用到动态缓冲区序列中包含的数据时指示成功匹配。调用将阻塞,直到以下任一条件为真:

  • 匹配条件函数对象返回一个 `std::pair`,其中第二个元素求值为 true。
  • 发生错误。

此操作通过零次或多次调用流的 read_some 函数来实现。如果匹配条件函数对象已指示匹配,则函数会立即返回。

参数

s

要从中读取数据的流。类型必须支持 SyncReadStream 概念。

缓冲区

将读取数据的动态缓冲区序列。

match_condition

将要调用的函数对象,用于确定是否存在匹配。函数对象的签名必须为:

pair<iterator, bool> match_condition(iterator begin, iterator end);

其中 iterator 代表类型

buffers_iterator<typename DynamicBuffer_v2::const_buffers_type>

迭代器参数 beginend 定义了用于确定是否存在匹配的字节范围。返回值中的 first 成员是一个迭代器,标记了匹配函数已消耗的字节的末尾之后一个位置。此迭代器用于计算匹配条件后续调用的 begin 参数。second 成员为 true,表示已找到匹配;否则为 false。

返回值

在 dynamic_buffer 的 get 区域中,已被匹配函数完全消耗的字节数。

异常

boost::system::system_error

失败时抛出。

备注

在成功的 read_until 操作之后,动态缓冲区序列可能包含超出函数对象匹配部分的数据。应用程序通常会将这些额外数据保留在动态缓冲区序列中,供后续的 read_until 操作进行检查。

备注

is_match_condition 类型特征的默认实现对具有 result_type typedef 的函数指针和函数对象评估为 true。它必须为其他用户定义的函数对象进行特化。

示例

读取数据到动态缓冲区序列中,直到遇到空白字符

typedef boost::asio::buffers_iterator<
    boost::asio::const_buffer> iterator;

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::string data;
boost::asio::read_until(s, data, match_whitespace);

读取数据到 std::string 中,直到找到匹配的字符

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_;
};

namespace asio {
  template <> struct is_match_condition<match_char>
    : public boost::true_type {};
} // namespace asio
...
std::string data;
boost::asio::read_until(s, data, match_char('a'));

PrevUpHomeNext