diff options
Diffstat (limited to '3rdparty/asio/src/doc/overview/line_based.qbk')
-rw-r--r-- | 3rdparty/asio/src/doc/overview/line_based.qbk | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/3rdparty/asio/src/doc/overview/line_based.qbk b/3rdparty/asio/src/doc/overview/line_based.qbk new file mode 100644 index 00000000000..df007adc3f8 --- /dev/null +++ b/3rdparty/asio/src/doc/overview/line_based.qbk @@ -0,0 +1,118 @@ +[/ + / Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com) + / + / Distributed under the Boost Software License, Version 1.0. (See accompanying + / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + /] + +[section:line_based Line-Based Operations] + +Many commonly-used internet protocols are line-based, which means that they +have protocol elements that are delimited by the character sequence `"\r\n"`. +Examples include HTTP, SMTP and FTP. To more easily permit the implementation +of line-based protocols, as well as other protocols that use delimiters, Asio +includes the functions `read_until()` and `async_read_until()`. + +The following example illustrates the use of `async_read_until()` in an HTTP +server, to receive the first line of an HTTP request from a client: + + class http_connection + { + ... + + void start() + { + asio::async_read_until(socket_, data_, "\r\n", + boost::bind(&http_connection::handle_request_line, this, _1)); + } + + void handle_request_line(asio::error_code ec) + { + if (!ec) + { + std::string method, uri, version; + char sp1, sp2, cr, lf; + std::istream is(&data_); + is.unsetf(std::ios_base::skipws); + is >> method >> sp1 >> uri >> sp2 >> version >> cr >> lf; + ... + } + } + + ... + + asio::ip::tcp::socket socket_; + asio::streambuf data_; + }; + +The `streambuf` data member serves as a place to store the data that has been +read from the socket before it is searched for the delimiter. It is important +to remember that there may be additional data ['after] the delimiter. This +surplus data should be left in the `streambuf` so that it may be inspected by a +subsequent call to `read_until()` or `async_read_until()`. + +The delimiters may be specified as a single `char`, a `std::string` or a +`boost::regex`. The `read_until()` and `async_read_until()` functions also +include overloads that accept a user-defined function object called a match +condition. For example, to read data into a streambuf until whitespace is +encountered: + + typedef asio::buffers_iterator< + asio::streambuf::const_buffers_type> 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); + } + ... + asio::streambuf b; + asio::read_until(s, b, match_whitespace); + +To read data into a streambuf 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 + ... + asio::streambuf b; + asio::read_until(s, b, match_char('a')); + +The `is_match_condition<>` type trait automatically evaluates to true for +functions, and for function objects with a nested `result_type` typedef. For +other types the trait must be explicitly specialised, as shown above. + +[heading See Also] + +[link asio.reference.async_read_until async_read_until()], +[link asio.reference.is_match_condition is_match_condition], +[link asio.reference.read_until read_until()], +[link asio.reference.streambuf streambuf], +[link asio.examples.cpp03_examples.http_client HTTP client example]. + +[endsect] |