启动一个异步操作,将数据读取到动态缓冲区序列中,直到函数对象指示匹配为止。
template< typename AsyncReadStream, typename DynamicBuffer_v1, typename MatchCondition, typename ReadToken = default_completion_token_t< typename AsyncReadStream::executor_type>> DEDUCED async_read_until( AsyncReadStream & s, DynamicBuffer_v1 && buffers, MatchCondition match_condition, ReadToken && token = default_completion_token_t< typename AsyncReadStream::executor_type >(), constraint_t< is_match_condition< MatchCondition >::value > = 0, constraint_t< is_dynamic_buffer_v1< decay_t< DynamicBuffer_v1 > >::value > = 0, constraint_t< !is_dynamic_buffer_v2< decay_t< DynamicBuffer_v1 > >::value > = 0);
此函数用于异步地将数据读取到指定的动态缓冲区序列中,直到用户定义的匹配条件函数对象应用于动态缓冲区序列中包含的数据时,指示成功匹配。 它是 异步操作 的启动函数,并始终立即返回。 异步操作将继续,直到以下条件之一为真
此操作通过零次或多次调用流的 async_read_some 函数来实现,被称为 组合操作。 如果匹配条件函数对象已指示匹配,则此异步操作立即完成。 程序必须确保流在操作完成之前不执行其他读取操作(例如 async_read、async_read_until、流的 async_read_some 函数或任何其他执行读取的组合操作)。
要从中读取数据的流。 类型必须支持 AsyncReadStream 概念。
数据将要读取到的动态缓冲区序列。 虽然 buffers 对象可能会根据需要复制,但底层内存块的所有权由调用者保留,调用者必须保证它们在完成处理程序被调用之前保持有效。
要调用的函数对象,以确定是否存在匹配。 函数对象的签名必须是
pair<iterator, bool> match_condition(iterator begin, iterator end);
其中 iterator
表示类型
buffers_iterator<typename DynamicBuffer_v1::const_buffers_type>
迭代器参数 begin
和 end
定义了要扫描的字节范围,以确定是否存在匹配。 返回值的 first
成员是一个迭代器,标记匹配函数已消耗的字节的末尾。 此迭代器用于计算后续调用匹配条件的 begin
参数。 如果找到匹配项,则返回值的 second
成员为 true,否则为 false。
将用于生成完成处理程序的 完成令牌,该处理程序将在读取完成时被调用。 可能的完成令牌包括 use_future
、 use_awaitable
、 yield_context
或具有正确完成签名的函数对象。 完成处理程序的函数签名必须是
void handler( // Result of operation. const boost::system::error_code& error, // The number of bytes in the dynamic buffer sequence's // get area that have been fully consumed by the match // function. O if an error occurred. std::size_t bytes_transferred );
无论异步操作是否立即完成,完成处理程序都不会在此函数内部调用。 在立即完成时,处理程序的调用将以等效于使用 async_immediate
的方式执行。
在成功的 async_read_until 操作之后,动态缓冲区序列可能包含超出与函数对象匹配的数据之外的额外数据。 应用程序通常会将该数据保留在动态缓冲区序列中,以供后续的 async_read_until 操作检查。
void(boost::system::error_code, std::size_t)
is_match_condition 类型特征的默认实现对于具有 result_type typedef 的函数指针和函数对象评估为 true。 对于其他用户定义的函数对象,必须对其进行特化。
异步地将数据读取到 std::string
中,直到遇到空白字符
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); } ... void handler(const boost::system::error_code& e, std::size_t size); ... std::string data; boost::asio::async_read_until(s, data, match_whitespace, handler);
异步地将数据读取到 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 ... void handler(const boost::system::error_code& e, std::size_t size); ... std::string data; boost::asio::async_read_until(s, data, match_char('a'), handler);
此异步操作支持以下 cancellation_type
值的取消
cancellation_type::terminal
cancellation_type::partial
如果 AsyncReadStream 类型的 async_read_some
操作也支持它们。