#### read_until (21 of 24 overloads)

Read data into a dynamic buffer sequence until some part of the data it contains matches a regular expression.

    template<
        typename SyncReadStream,
        typename DynamicBuffer_v2,
        typename Traits>
    std::size_t read_until(
        SyncReadStream & s,
        DynamicBuffer_v2 buffers,
        const boost::basic_regex< char, Traits > & expr,
        constraint_t< is_dynamic_buffer_v2< DynamicBuffer_v2 >::value >  = 0);

This function is used to read data into the specified dynamic buffer sequence until the dynamic buffer sequence's get area contains some data that matches a regular expression. The call will block until one of the following conditions is true:

- A substring of the dynamic buffer sequence's get area matches the regular expression.
- An error occurred.

This operation is implemented in terms of zero or more calls to the stream's read_some function. If the dynamic buffer sequence's get area already contains data that matches the regular expression, the function returns immediately.

###### Parameters

s

  The stream from which the data is to be read. The type must support the SyncReadStream concept.

buffers

  A dynamic buffer sequence into which the data will be read.

expr

  The regular expression.

###### Return Value

The number of bytes in the dynamic buffer sequence's get area up to and including the substring that matches the regular expression.

###### Exceptions

asio::system_error

  Thrown on failure.

###### Remarks

After a successful read_until operation, the dynamic buffer sequence may contain additional data beyond that which matched the regular expression. An application will typically leave that data in the dynamic buffer sequence for a subsequent read_until operation to examine.

###### Example

To read data into a `std::string` until a CR-LF sequence is encountered:

    std::string data;
    std::size_t n = asio::read_until(s,
        asio::dynamic_buffer(data), boost::regex("\r\n"));
    std::string line = data.substr(0, n);
    data.erase(0, n);

After the `read_until` operation completes successfully, the string `data` contains the delimiter:

    { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... }

The call to `substr` then extracts the data up to and including the delimiter, so that the string `line` contains:

    { 'a', 'b', ..., 'c', '\r', '\n' }

After the call to `erase`, the remaining data is left in the buffer `b` as follows:

    { 'd', 'e', ... }

This data may be the start of a new line, to be extracted by a subsequent `read_until` operation.