src/rfc/quoted_token_rule.cpp

82.8% Lines (24/0/29) 100.0% List of functions (1/0/1)
quoted_token_rule.cpp
f(x) Functions (1)
Line TLA Hits 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
8 //
9
10 #include <boost/http/rfc/quoted_token_rule.hpp>
11 #include <boost/http/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 {
20
21 namespace {
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 } // namespace
59
60
61 namespace implementation_defined {
62 auto
63 22x quoted_token_rule_t::
64 parse(
65 char const*& it,
66 char const* end) const noexcept ->
67 system::result<value_type>
68 {
69 22x if(it == end)
70 {
71 1x return grammar::error::need_more;
72 }
73 21x if(*it != '\"')
74 {
75 // token
76 15x auto rv = grammar::parse(
77 it, end, token_rule);
78 15x if(rv.has_value())
79 15x return quoted_token_view(*rv);
80 return rv.error();
81 }
82 // quoted-string
83 6x auto const it0 = it++;
84 6x std::size_t n = 0;
85 for(;;)
86 {
87 10x auto it1 = it;
88 10x it = grammar::find_if_not(
89 it, end, qdtext_chars);
90 10x if(it == end)
91 {
92 return grammar::error::need_more;
93 }
94 10x n += static_cast<std::size_t>(it - it1);
95 10x if(*it == '\"')
96 6x break;
97 4x if(*it != '\\')
98 {
99 return grammar::error::syntax;
100 }
101 4x ++it;
102 4x if(it == end)
103 {
104 return grammar::error::need_more;
105 }
106 4x if(! qpchars(*it))
107 {
108 return grammar::error::syntax;
109 }
110 4x ++it;
111 4x ++n;
112 4x }
113 12x return value_type(core::string_view(
114 12x it0, ++it - it0), n);
115 }
116
117 } // implementation_defined
118 } // http
119 } // boost
120