pct_encoded_rule.hpp 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. //
  2. // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot 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/boostorg/url
  8. //
  9. #ifndef BOOST_URL_RFC_IMPL_PCT_ENCODED_RULE_HPP
  10. #define BOOST_URL_RFC_IMPL_PCT_ENCODED_RULE_HPP
  11. #include <boost/url/grammar/charset.hpp>
  12. #include <boost/url/grammar/error.hpp>
  13. #include <boost/url/grammar/hexdig_chars.hpp>
  14. namespace boost {
  15. namespace urls {
  16. namespace detail {
  17. template<class CharSet>
  18. auto
  19. parse_encoded(
  20. char const*& it,
  21. char const* end,
  22. CharSet const& cs) noexcept ->
  23. system::result<pct_string_view>
  24. {
  25. auto const start = it;
  26. std::size_t n = 0;
  27. char const* it0;
  28. skip:
  29. it0 = it;
  30. it = grammar::find_if_not(
  31. it0, end, cs);
  32. n += it - it0;
  33. if(it == end)
  34. goto finish;
  35. if(*it != '%')
  36. goto finish;
  37. for(;;)
  38. {
  39. ++it;
  40. if(it == end)
  41. {
  42. // expected HEXDIG
  43. BOOST_URL_RETURN_EC(
  44. grammar::error::invalid);
  45. }
  46. auto r = grammar::hexdig_value(*it);
  47. if(r < 0)
  48. {
  49. // expected HEXDIG
  50. BOOST_URL_RETURN_EC(
  51. grammar::error::invalid);
  52. }
  53. ++it;
  54. if(it == end)
  55. {
  56. // expected HEXDIG
  57. BOOST_URL_RETURN_EC(
  58. grammar::error::invalid);
  59. }
  60. r = grammar::hexdig_value(*it);
  61. if(r < 0)
  62. {
  63. // expected HEXDIG
  64. BOOST_URL_RETURN_EC(
  65. grammar::error::invalid);
  66. }
  67. ++n;
  68. ++it;
  69. if(it == end)
  70. break;
  71. if(*it != '%')
  72. goto skip;
  73. }
  74. finish:
  75. return make_pct_string_view_unsafe(
  76. start, it - start, n);
  77. }
  78. } // detail
  79. //------------------------------------------------
  80. template<class CharSet>
  81. auto
  82. pct_encoded_rule_t<CharSet>::
  83. parse(
  84. char const*& it,
  85. char const* end) const noexcept ->
  86. system::result<value_type>
  87. {
  88. return detail::parse_encoded(
  89. it, end, cs_);
  90. }
  91. } // urls
  92. } // boost
  93. #endif