#### read_until (23 of 24 overloads)

Read data into a dynamic buffer sequence until a function object indicates a match.

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

This function is used to read data into the specified dynamic buffer sequence until a user-defined match condition function object, when applied to the data contained in the dynamic buffer sequence, indicates a successful match. The call will block until one of the following conditions is true:

- The match condition function object returns a std::pair where the second element evaluates to true.
- An error occurred.

This operation is implemented in terms of zero or more calls to the stream's read_some function. If the match condition function object already indicates a match, 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.

match_condition

  The function object to be called to determine whether a match exists. The signature of the function object must be:

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

  where `iterator` represents the type:

      buffers_iterator<typename DynamicBuffer_v2::const_buffers_type>

  The iterator parameters `begin` and `end` define the range of bytes to be scanned to determine whether there is a match. The `first` member of the return value is an iterator marking one-past-the-end of the bytes that have been consumed by the match function. This iterator is used to calculate the `begin` parameter for any subsequent invocation of the match condition. The `second` member of the return value is true if a match has been found, false otherwise.

###### Return Value

The number of bytes in the dynamic_buffer's get area that have been fully consumed by the match function.

###### 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 function object. An application will typically leave that data in the dynamic buffer sequence for a subsequent read_until operation to examine.

The default implementation of the `is_match_condition` type trait evaluates to true for function pointers and function objects with a `result_type` typedef. It must be specialised for other user-defined function objects.

###### Examples

To read data into a dynamic buffer sequence until whitespace is encountered:

    typedef asio::buffers_iterator<
        asio::const_buffers_1> 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;
    asio::read_until(s, data, match_whitespace);

To read data into a `std::string` until a matching character is found:

    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;
    asio::read_until(s, data, match_char('a'));