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