14 #include <restinio/impl/string_caseless_compare.hpp> 16 #include <restinio/helpers/easy_parser.hpp> 18 #include <restinio/expected.hpp> 58 constexpr auto get()
const noexcept {
return m_value; }
71 if( m_value > maximum )
72 throw exception_t(
"invalid value for " 73 "http_field_parser::rfc::qvalue_t" );
76 auto get()
const noexcept {
return m_value; }
163 underlying_char_array_t result;
164 if( qvalue_details::maximum == m_value )
166 static constexpr char fixed_value[]{
"1.000" };
167 std::copy( std::begin(fixed_value), std::end(fixed_value),
168 std::begin(result) );
175 result[2] =
'0' +
static_cast<
char>(m_value / 100u);
176 const auto d2 = m_value % 100u;
177 result[3] =
'0' +
static_cast<
char>(d2 / 10u);
178 const auto d3 = d2 % 10u;
179 result[4] =
'0' +
static_cast<
char>(d3);
206 constexpr auto as_uint()
const noexcept {
return m_value; }
210 return std::string{ &make_char_array().front() };
216 return (to << &what.make_char_array().front());
224 return a.as_uint() == b.as_uint();
231 return a.as_uint() != b.as_uint();
238 return a.as_uint() < b.as_uint();
245 return a.as_uint() <= b.as_uint();
264 inline constexpr bool 267 return (ch >=
'\x41' && ch <=
'\x5A') ||
268 (ch >=
'\x61' && ch <=
'\x7A');
305 return is_alpha(actual) || is_digit(actual);
320 inline constexpr bool 323 return (ch >=
'\x21' && ch <=
'\x7E');
356 inline constexpr bool 359 constexpr unsigned short left = 0x80u;
360 constexpr unsigned short right = 0xFFu;
362 const unsigned short t =
static_cast<
unsigned short>(
363 static_cast<
unsigned char>(ch));
365 return (t >= left && t <= right);
379 inline constexpr bool 385 (ch >=
'\x23' && ch <=
'\x5B') ||
386 (ch >=
'\x5D' && ch <=
'\x7E') ||
401 inline constexpr bool 406 (ch >=
'\x21' && ch <=
'\x27') ||
407 (ch >=
'\x2A' && ch <=
'\x5B') ||
408 (ch >=
'\x5D' && ch <=
'\x7E') ||
427 return is_ctext(actual);
441 static constexpr bool 444 return is_alpha(ch) || is_digit(ch) ||
466 return is_token_char(actual);
491 std::size_t extracted_spaces{};
493 for( ch = from.getch();
494 !ch.m_eof && is_space(ch.m_ch);
504 if( extracted_spaces > 0u )
505 return result_type{
' ' };
507 return result_type{ std::nullopt };
530 error_reason_t reason = error_reason_t::pattern_not_found;
534 const auto ch = from.getch();
537 reason = error_reason_t::unexpected_eof;
541 if( !is_token_char(ch.m_ch) )
544 reason = error_reason_t::unexpected_character;
548 accumulator += ch.m_ch;
552 if( accumulator.empty() )
554 return parse_error_t{ from.current_position(), reason };
561 static constexpr bool 564 return is_token_char_predicate_t::is_token_char( ch );
573 const auto try_result = try_parse_value( from, value );
575 return { std::move(value) };
577 return make_unexpected( *try_result );
600 error_reason_t reason = error_reason_t::pattern_not_found;
602 bool second_quote_extracted{
false };
605 const auto ch = from.getch();
608 reason = error_reason_t::unexpected_eof;
613 second_quote_extracted =
true;
614 else if(
'\\' == ch.m_ch )
616 const auto next = from.getch();
619 reason = error_reason_t::unexpected_eof;
622 else if( SP == next.m_ch || HTAB == next.m_ch ||
623 is_vchar( next.m_ch ) ||
624 is_obs_text( next.m_ch ) )
626 accumulator += next.m_ch;
630 reason = error_reason_t::unexpected_character;
635 else if( is_qdtext( ch.m_ch ) )
636 accumulator += ch.m_ch;
639 reason = error_reason_t::unexpected_character;
644 while( !second_quote_extracted );
646 if( !second_quote_extracted )
647 return parse_error_t{ from.current_position(), reason };
657 source_t::content_consumer_t consumer{ from };
659 const auto ch = from.getch();
665 const auto try_result = try_parse_value( from, value );
669 return { std::move(value) };
672 return make_unexpected( *try_result );
676 return make_unexpected( parse_error_t{
677 consumer.started_at(),
678 error_reason_t::unexpected_character
683 return make_unexpected( parse_error_t{
684 consumer.started_at(),
685 error_reason_t::unexpected_eof
710 source_t::content_consumer_t consumer{ from };
712 error_reason_t reason = error_reason_t::unexpected_eof;
714 const auto ch = from.getch();
717 if(
'\\' == ch.m_ch )
719 const auto next = from.getch();
722 if( SP == next.m_ch || HTAB == next.m_ch ||
723 is_vchar( next.m_ch ) ||
724 is_obs_text( next.m_ch ) )
730 reason = error_reason_t::unexpected_character;
734 reason = error_reason_t::unexpected_character;
737 return make_unexpected( parse_error_t{
738 from.current_position(),
792 return restinio::easy_parser::impl::symbol_producer_template_t<
793 impl::is_alpha_predicate_t >{};
814 return restinio::easy_parser::impl::symbol_producer_template_t<
815 impl::is_alphanum_predicate_t >{};
836 return restinio::easy_parser::impl::symbol_producer_template_t<
837 impl::is_vchar_predicate_t >{};
858 return restinio::easy_parser::impl::symbol_producer_template_t<
859 impl::is_ctext_predicate_t >{};
941 ows()
noexcept {
return ows_p() >> skip(); }
961 return restinio::easy_parser::impl::symbol_producer_template_t<
962 impl::is_token_char_predicate_t >{};
1077 return produce<
bool >(
1078 exact_p( token ) >> as_result(),
1079 not_clause( token_symbol_p() >> skip() ) );
1116 return produce<
bool >(
1117 caseless_exact_p( token ) >> as_result(),
1118 not_clause( token_symbol_p() >> skip() ) );
1131 return produce< std::string >(
1136 ctext_symbol_p() >> to_container(),
1137 quoted_pair_p() >> to_container(),
1138 comment_p() >> custom_consumer(
1139 []( std::string & dest, std::string && what ) {
1144 ).try_parse( from );
1187 dest.m_value += m_multiplier *
1188 static_cast< qvalue_t::underlying_uint_t >(digit -
'0');
1197 const auto parse_result = produce< zero_initialized_unit_t >(
1203 maybe( digit_p() >> digit_consumer_t{100},
1204 maybe( digit_p() >> digit_consumer_t{10},
1205 maybe( digit_p() >> digit_consumer_t{1} )
1211 symbol_p(
'1') >> digit_consumer_t{1000},
1216 maybe( symbol(
'0') )
1222 ).try_parse( from );
1225 return qvalue_t{ qvalue_t::trusted{ parse_result->m_value } };
1227 return make_unexpected( parse_result.error() );
1281 return produce< qvalue_t >(
1285 caseless_symbol(
'q'),
1287 qvalue_p() >> as_result()
1317 typename Element_Producer >
1322 "Element_Producer should be a value producer type" );
1330 Element_Producer && element )
1381 typename Element_Producer >
1386 "Element_Producer should be a value producer type" );
1394 Element_Producer && element )
1456 typename Element_Producer >
1461 static_assert( impl::is_producer_v<Element_Producer>,
1462 "Element_Producer should be a value producer type" );
1464 return impl::non_empty_comma_separated_list_producer_t<
1466 Element_Producer >{ std::move(element) };
1502 typename Element_Producer >
1507 static_assert( impl::is_producer_v<Element_Producer>,
1508 "Element_Producer should be a value producer type" );
1510 return impl::maybe_empty_comma_separated_list_producer_t<
1512 Element_Producer >{ std::move(element) };
1574 const auto it = std::find_if( where.begin(), where.end(),
1575 [&what](
const auto & pair ) {
1576 return restinio::impl::is_equal_caseless( pair.first, what );
1578 if( it != where.end() )
1579 return string_view_t{ it->second };
1581 return make_unexpected( not_found_t{} );
1603 return produce< parameter_with_mandatory_value_container_t >(
1605 produce< parameter_with_mandatory_value_t >(
1609 token_p() >> to_lower()
1610 >> ¶meter_with_mandatory_value_t::first,
1614 >> ¶meter_with_mandatory_value_t::second,
1616 >> ¶meter_with_mandatory_value_t::second
1650 return m_producer.try_parse( from );
1779 return produce< parameter_with_optional_value_container_t >(
1781 produce< parameter_with_optional_value_t >(
1785 token_p() >> to_lower()
1786 >> ¶meter_with_optional_value_t::first,
1791 >> ¶meter_with_optional_value_t::second,
1793 >> ¶meter_with_optional_value_t::second
1828 return m_producer.try_parse( from );
non_empty_comma_separated_list_producer_t(Element_Producer &&element)
expected_t< result_type, parse_error_t > try_parse(source_t &from) const noexcept
expected_t< std::optional< string_view_t >, not_found_t > find_first(const parameter_with_optional_value_container_t &where, string_view_t what)
A helper function to find the first occurence of a parameter with the specified value.
auto vchar_symbol_p()
A factory for producer of VCHAR symbols.
expected_t< result_type, parse_error_t > try_parse(source_t &from) const
auto ctext_symbol_p()
A factory for producer of ctext symbols.
auto make_parser()
Helper function that creates an instance of producer of parameter_with_optional_value_container.
constexpr bool is_qdtext(const char ch) noexcept
Is a character a qdtext?
const qvalue_t::underlying_uint_t m_multiplier
bool operator()(const char actual) const noexcept
A helper wrapper to indicate that value hasn't been checked yet and should be checked in the construc...
constexpr underlying_uint_t zero
The minimal allowed value for a qvalue.
params_with_opt_value_producer_t()=default
auto comment_p()
A factory for producer of comment token.
constexpr qvalue_t()=default
constexpr bool is_obs_text(const char ch) noexcept
Is a character an obs_text?
auto quoted_string_p() noexcept
A factory function to create a quoted_string_producer.
impl::params_with_opt_value_producer_t params_with_opt_value_p()
A factory of producer of parameter_with_optional_value_container.
constexpr underlying_uint_t maximum
The maximal allowed value for a qvalue.
auto get() const noexcept
bool operator()(const char actual) const noexcept
bool operator()(const char actual) const noexcept
params_with_value_producer_t()=default
bool operator<(const qvalue_t &a, const qvalue_t &b) noexcept
A preducate for symbol_producer_template that checks that a symbol is an alpha.
Element_Producer m_element
qvalue_t::underlying_uint_t m_value
A producer for quoted_string.
auto non_empty_comma_separated_list_p(Element_Producer element)
A factory for a producer that handles non-empty list of comma-separated values.
static constexpr bool is_token_char(const char ch) noexcept
constexpr bool is_ctext(const char ch) noexcept
Is a character a ctext?
auto try_parse(source_t &from)
A class for holding the parsed value of qvalue from RFC7231.
bool operator!=(const qvalue_t &a, const qvalue_t &b) noexcept
An implementation of producer of qvalue.
auto qvalue_p() noexcept
A factory function to create a qvalue_producer.
Element_Producer m_element
std::enable_if< std::is_same< Parameter_Container, query_string_params_t >::value||std::is_same< Parameter_Container, router::route_params_t >::value, std::optional< Value_Type > >::type opt_value(const Parameter_Container ¶ms, string_view_t key)
Gets the value of a parameter specified by key wrapped in std::optional<Value_Type> if parameter exis...
A preducate for symbol_producer_template that checks that a symbol is a ctext.
constexpr auto get() const noexcept
actual_producer_t m_producer
static std::optional< parse_error_t > try_parse_value(source_t &from, std::string &accumulator)
underlying_uint_t m_value
constexpr trusted(underlying_uint_t value) noexcept
constexpr qvalue_t(trusted val) noexcept
constexpr bool is_alpha(const char ch) noexcept
Is a character an ALPHA?
actual_producer_t m_producer
auto maybe_empty_comma_separated_list_p(Element_Producer element)
A factory for a producer that handles possibly empty list of comma-separated values.
auto expected_caseless_token_p(string_view_t token)
A factory function to create a producer that expect a token with specific value.
untrusted(underlying_uint_t value)
auto token_symbol_p() noexcept
A factory for producer of symbols than can be used in tokens.
expected_t< result_type, parse_error_t > try_parse(source_t &from) const
underlying_uint_t m_value
static constexpr qvalue_details::extremum_max_t maximum
The indicator that tells that new qvalue object should have the maximal allowed value.
A template for a producer that handles non-empty list of comma-separated values.
expected_t< result_type, parse_error_t > try_parse(source_t &from) const
A preducate for symbol_producer_template that checks that a symbol is a VCHAR.
constexpr qvalue_t(qvalue_details::extremum_min_t) noexcept
static constexpr bool is_token_char(const char ch) noexcept
auto alphanum_symbol_p()
A factory for producer of symbol that an ALPHA or DIGIT.
A type of producer that produces instances of parameter_with_optional_value_container.
auto make_parser()
Helper function that creates an instance of producer of parameter_with_mandatory_value_container.
expected_t< result_type, parse_error_t > try_parse(source_t &from)
A predicate for symbol_producer_template that checks that a symbol can be used inside a token...
const underlying_uint_t m_value
impl::params_with_value_producer_t params_with_value_p()
A factory of producer of parameter_with_mandatory_value_container.
A producer for quoted_pair.
A template for a producer that handles possibly empty list of comma-separated values.
constexpr digit_consumer_t(qvalue_t::underlying_uint_t m)
expected_t< string_view_t, not_found_t > find_first(const parameter_with_mandatory_value_container_t &where, string_view_t what)
A helper function to find the first occurence of a parameter with the specified value.
A helper class to be used to accumulate actual integer while when the next digit is extracted from th...
qvalue_t(untrusted val) noexcept
constexpr qvalue_t(qvalue_details::extremum_max_t) noexcept
friend std::ostream & operator<<(std::ostream &to, const qvalue_t &what)
auto quoted_pair_p() noexcept
A factory function to create a quoted_pair_producer.
auto ows() noexcept
A factory function to create an OWS clause.
constexpr bool is_vchar(const char ch) noexcept
Is a character a VCHAR?
auto ows_p() noexcept
A factory function to create an ows_producer.
bool operator()(const char actual) const noexcept
maybe_empty_comma_separated_list_producer_t(Element_Producer &&element)
underlying_char_array_t make_char_array() const noexcept
An empty type to be used as indicator of negative search result.
A type of producer that produces instances of parameter_with_mandatory_value_container.
auto weight_p() noexcept
A factory function to create a producer for weight parameter.
expected_t< result_type, parse_error_t > try_parse(source_t &from) const noexcept
auto token_p() noexcept
A factory function to create a token_producer.
A preducate for symbol_producer_template that checks that a symbol is an alpha or numeric...
bool operator()(const char actual) const noexcept
void consume(zero_initialized_unit_t &dest, char &&digit)
static constexpr qvalue_details::extremum_min_t zero
The indicator that tells that new qvalue object should have the minimal allowed value.
constexpr auto as_uint() const noexcept
auto expected_token_p(string_view_t token)
A factory function to create a producer that expect a token with specific value.
auto alpha_symbol_p()
A factory for producer of ALPHA symbols.
expected_t< result_type, parse_error_t > try_parse(source_t &from)
A helper wrapper to indicate that value is already checked and shouldn't be checked again...
auto try_parse(source_t &from)
bool operator<=(const qvalue_t &a, const qvalue_t &b) noexcept
bool operator==(const qvalue_t &a, const qvalue_t &b) noexcept
static std::optional< parse_error_t > try_parse_value(source_t &from, std::string &accumulator)