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 : auto rv = grammar::parse( 78 15 : 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