path.hpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. //
  2. // Copyright (c) 2019 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/boostorg/url
  8. //
  9. #ifndef BOOST_URL_DETAIL_PATH_HPP
  10. #define BOOST_URL_DETAIL_PATH_HPP
  11. #include <boost/core/detail/string_view.hpp>
  12. namespace boost {
  13. namespace urls {
  14. namespace detail {
  15. // Return the number of characters at
  16. // the front of the path that are reserved
  17. inline
  18. std::size_t
  19. path_prefix(
  20. char const* p,
  21. std::size_t n) noexcept
  22. {
  23. switch(n)
  24. {
  25. case 0:
  26. return 0;
  27. case 1:
  28. if(p[0] == '/')
  29. return 1;
  30. return 0;
  31. case 2:
  32. if(p[0] == '/')
  33. return 1;
  34. if( p[0] == '.' &&
  35. p[1] == '/')
  36. return 2;
  37. return 0;
  38. default:
  39. if(p[0] == '/')
  40. {
  41. if( p[1] == '.' &&
  42. p[2] == '/')
  43. return 3;
  44. return 1;
  45. }
  46. if( p[0] == '.' &&
  47. p[1] == '/')
  48. return 2;
  49. break;
  50. }
  51. return 0;
  52. }
  53. // VFALCO DEPRECATED
  54. inline
  55. std::size_t
  56. path_prefix(
  57. core::string_view s) noexcept
  58. {
  59. return path_prefix(
  60. s.data(), s.size());
  61. }
  62. // returns the number of adjusted
  63. // segments based on the malleable prefix.
  64. inline
  65. std::size_t
  66. path_segments(
  67. core::string_view s,
  68. std::size_t nseg) noexcept
  69. {
  70. switch(s.size())
  71. {
  72. case 0:
  73. BOOST_ASSERT(nseg == 0);
  74. return 0;
  75. case 1:
  76. BOOST_ASSERT(nseg == 1);
  77. if(s[0] == '/')
  78. return 0;
  79. return 1;
  80. case 2:
  81. if(s[0] == '/')
  82. return nseg;
  83. if( s[0] == '.' &&
  84. s[1] == '/')
  85. {
  86. BOOST_ASSERT(nseg > 1);
  87. return nseg - 1;
  88. }
  89. return nseg;
  90. default:
  91. if(s[0] == '/')
  92. {
  93. if( s[1] == '.' &&
  94. s[2] == '/')
  95. {
  96. BOOST_ASSERT(nseg > 1);
  97. return nseg - 1;
  98. }
  99. return nseg;
  100. }
  101. if( s[0] == '.' &&
  102. s[1] == '/')
  103. {
  104. BOOST_ASSERT(nseg > 1);
  105. return nseg - 1;
  106. }
  107. break;
  108. }
  109. return nseg;
  110. }
  111. // Trim reserved characters from
  112. // the front of the path.
  113. inline
  114. core::string_view
  115. clean_path(
  116. core::string_view s) noexcept
  117. {
  118. s.remove_prefix(
  119. path_prefix(s));
  120. return s;
  121. }
  122. } // detail
  123. } // urls
  124. } // boost
  125. #endif