]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/asio/doc/overview/line_based.qbk
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / asio / doc / overview / line_based.qbk
CommitLineData
7c673cae
FG
1[/
2 / Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com)
3 /
4 / Distributed under the Boost Software License, Version 1.0. (See accompanying
5 / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 /]
7
8[section:line_based Line-Based Operations]
9
10Many commonly-used internet protocols are line-based, which means that they
11have protocol elements that are delimited by the character sequence `"\r\n"`.
12Examples include HTTP, SMTP and FTP. To more easily permit the implementation
13of line-based protocols, as well as other protocols that use delimiters, Boost.Asio
14includes the functions `read_until()` and `async_read_until()`.
15
16The following example illustrates the use of `async_read_until()` in an HTTP
17server, to receive the first line of an HTTP request from a client:
18
19 class http_connection
20 {
21 ...
22
23 void start()
24 {
25 boost::asio::async_read_until(socket_, data_, "\r\n",
26 boost::bind(&http_connection::handle_request_line, this, _1));
27 }
28
29 void handle_request_line(boost::system::error_code ec)
30 {
31 if (!ec)
32 {
33 std::string method, uri, version;
34 char sp1, sp2, cr, lf;
35 std::istream is(&data_);
36 is.unsetf(std::ios_base::skipws);
37 is >> method >> sp1 >> uri >> sp2 >> version >> cr >> lf;
38 ...
39 }
40 }
41
42 ...
43
44 boost::asio::ip::tcp::socket socket_;
45 boost::asio::streambuf data_;
46 };
47
48The `streambuf` data member serves as a place to store the data that has been
49read from the socket before it is searched for the delimiter. It is important
50to remember that there may be additional data ['after] the delimiter. This
51surplus data should be left in the `streambuf` so that it may be inspected by a
52subsequent call to `read_until()` or `async_read_until()`.
53
54The delimiters may be specified as a single `char`, a `std::string` or a
55`boost::regex`. The `read_until()` and `async_read_until()` functions also
56include overloads that accept a user-defined function object called a match
57condition. For example, to read data into a streambuf until whitespace is
58encountered:
59
60 typedef boost::asio::buffers_iterator<
61 boost::asio::streambuf::const_buffers_type> iterator;
62
63 std::pair<iterator, bool>
64 match_whitespace(iterator begin, iterator end)
65 {
66 iterator i = begin;
67 while (i != end)
68 if (std::isspace(*i++))
69 return std::make_pair(i, true);
70 return std::make_pair(i, false);
71 }
72 ...
73 boost::asio::streambuf b;
74 boost::asio::read_until(s, b, match_whitespace);
75
76To read data into a streambuf until a matching character is found:
77
78 class match_char
79 {
80 public:
81 explicit match_char(char c) : c_(c) {}
82
83 template <typename Iterator>
84 std::pair<Iterator, bool> operator()(
85 Iterator begin, Iterator end) const
86 {
87 Iterator i = begin;
88 while (i != end)
89 if (c_ == *i++)
90 return std::make_pair(i, true);
91 return std::make_pair(i, false);
92 }
93
94 private:
95 char c_;
96 };
97
98 namespace boost { namespace asio {
99 template <> struct is_match_condition<match_char>
100 : public boost::true_type {};
101 } } // namespace boost::asio
102 ...
103 boost::asio::streambuf b;
104 boost::asio::read_until(s, b, match_char('a'));
105
106The `is_match_condition<>` type trait automatically evaluates to true for
107functions, and for function objects with a nested `result_type` typedef. For
108other types the trait must be explicitly specialised, as shown above.
109
110[heading See Also]
111
112[link boost_asio.reference.async_read_until async_read_until()],
113[link boost_asio.reference.is_match_condition is_match_condition],
114[link boost_asio.reference.read_until read_until()],
115[link boost_asio.reference.streambuf streambuf],
116[link boost_asio.examples.cpp03_examples.http_client HTTP client example].
117
118[endsect]