template<class SyncReadStream, class DynamicBuffer>
size_t read_until(SyncReadStream& s, DynamicBuffer&& b, char delim);
template<class SyncReadStream, class DynamicBuffer>
size_t read_until(SyncReadStream& s, DynamicBuffer&& b,
char delim, error_code& ec);
template<class SyncReadStream, class DynamicBuffer>
size_t read_until(SyncReadStream& s, DynamicBuffer&& b, string_view delim);
template<class SyncReadStream, class DynamicBuffer>
size_t read_until(SyncReadStream& s, DynamicBuffer&& b,
string_view delim, error_code& ec);
Effects: Reads data from the buffer-oriented synchronous read stream ([buffer.stream.reqmts.syncreadstream]) object stream by performing zero or more calls to the stream's read_some member function, until the readable bytes of the dynamic buffer ([buffer.reqmts.dynamicbuffer]) object b contains the specified delimiter delim.
Data is placed into the dynamic buffer object b. A mutable buffer sequence ([buffer.reqmts.mutablebuffersequence]) is obtained prior to each read_some call using b.prepare(N), where N is an unspecified value such that N <= max_size() - size(). [ Note: Implementations can use b.capacity() when determining N, to minimize the number of read_some calls performed on the stream. — end note ] After each read_some call, the implementation performs b.commit(n), where n is the return value from read_some.
On exit, if the readable bytes of b contains the delimiter, ec is set such that !ec is true. Otherwise, if b.size() == b.max_size(), ec is set such that ec == stream_errc::not_found. If b.size() < b.max_size(), ec contains the error_code from the most recent read_some call.
Returns: The number of bytes in the readable bytes of b up to and including the delimiter, if present. [ Note: On completion, the buffer can contain additional bytes following the delimiter. — end note ] Otherwise returns 0.