Line data Source code
1 : //
2 : // Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.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 : // Official repository: https://github.com/cppalliance/http_proto
8 : //
9 :
10 : #include <boost/http_proto/rfc/quoted_token_rule.hpp>
11 : #include <boost/http_proto/rfc/token_rule.hpp>
12 : #include <boost/url/grammar/charset.hpp>
13 : #include <boost/url/grammar/error.hpp>
14 : #include <boost/url/grammar/lut_chars.hpp>
15 : #include <boost/url/grammar/parse.hpp>
16 : #include <boost/url/grammar/vchars.hpp>
17 :
18 : namespace boost {
19 : namespace http_proto {
20 :
21 : namespace detail {
22 :
23 : struct obs_text
24 : {
25 : constexpr
26 : bool
27 : operator()(char ch) const noexcept
28 : {
29 : return static_cast<
30 : unsigned char>(ch) >= 0x80;
31 : }
32 : };
33 :
34 : struct qdtext
35 : {
36 : constexpr
37 : bool
38 : operator()(char ch) const noexcept
39 : {
40 : return
41 : ch == '\t' ||
42 : ch == ' ' ||
43 : ch == 0x21 ||
44 : (ch >= 0x23 && ch <= 0x5b) ||
45 : (ch >= 0x5d && ch <= 0x7e) ||
46 : static_cast<unsigned char>(ch) >= 0x80;
47 : }
48 : };
49 :
50 : // qdtext = HTAB / SP /%x21 / %x23-5B / %x5D-7E / obs-text
51 : constexpr grammar::lut_chars qdtext_chars(qdtext{});
52 :
53 : // qpchars = ( HTAB / SP / VCHAR / obs-text )
54 : constexpr auto qpchars =
55 : grammar::lut_chars(grammar::vchars) +
56 : grammar::lut_chars(obs_text{}) + '\t' + ' ';
57 :
58 : } // detail
59 :
60 : //------------------------------------------------
61 :
62 : auto
63 22 : quoted_token_rule_t::
64 : parse(
65 : char const*& it,
66 : char const* end) const noexcept ->
67 : system::result<value_type>
68 : {
69 22 : if(it == end)
70 : {
71 1 : BOOST_HTTP_PROTO_RETURN_EC(
72 : grammar::error::need_more);
73 : }
74 21 : if(*it != '\"')
75 : {
76 : // token
77 15 : auto rv = grammar::parse(
78 : it, end, token_rule);
79 15 : if(rv.has_value())
80 15 : return quoted_token_view(*rv);
81 0 : return rv.error();
82 : }
83 : // quoted-string
84 6 : auto const it0 = it++;
85 6 : std::size_t n = 0;
86 : for(;;)
87 : {
88 10 : auto it1 = it;
89 10 : it = grammar::find_if_not(
90 : it, end, detail::qdtext_chars);
91 10 : if(it == end)
92 : {
93 0 : BOOST_HTTP_PROTO_RETURN_EC(
94 : grammar::error::need_more);
95 : }
96 10 : n += static_cast<std::size_t>(it - it1);
97 10 : if(*it == '\"')
98 6 : break;
99 4 : if(*it != '\\')
100 : {
101 0 : BOOST_HTTP_PROTO_RETURN_EC(
102 : grammar::error::syntax);
103 : }
104 4 : ++it;
105 4 : if(it == end)
106 : {
107 0 : BOOST_HTTP_PROTO_RETURN_EC(
108 : grammar::error::need_more);
109 : }
110 4 : if(! detail::qpchars(*it))
111 : {
112 0 : BOOST_HTTP_PROTO_RETURN_EC(
113 : grammar::error::syntax);
114 : }
115 4 : ++it;
116 4 : ++n;
117 4 : }
118 12 : return value_type(core::string_view(
119 12 : it0, ++it - it0), n);
120 : }
121 :
122 : } // http_proto
123 : } // boost
|