url_impl.hpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. //
  2. // Copyright (c) 2022 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_URL_IMPL_HPP
  10. #define BOOST_URL_DETAIL_URL_IMPL_HPP
  11. #include <boost/url/host_type.hpp>
  12. #include <boost/url/pct_string_view.hpp>
  13. #include <boost/url/scheme.hpp>
  14. #include <boost/core/detail/string_view.hpp>
  15. #include <boost/url/detail/parts_base.hpp>
  16. #include <boost/assert.hpp>
  17. #include <cstdint>
  18. namespace boost {
  19. namespace urls {
  20. class url_view;
  21. class authority_view;
  22. namespace detail {
  23. constexpr char const* const empty_c_str_ = "";
  24. // This is the private 'guts' of a
  25. // url_view, exposed so different parts
  26. // of the implementation can work on it.
  27. // It stores the offsets and properties of
  28. // a URL string stored elsewhere and pointed
  29. // to by cs_.
  30. struct BOOST_URL_DECL url_impl : parts_base
  31. {
  32. static
  33. constexpr
  34. std::size_t const zero_ = 0;
  35. // never nullptr
  36. char const* cs_ = empty_c_str_;
  37. std::size_t offset_[id_end + 1] = {};
  38. std::size_t decoded_[id_end] = {};
  39. std::size_t nseg_ = 0;
  40. std::size_t nparam_ = 0;
  41. unsigned char ip_addr_[16] = {};
  42. // VFALCO don't we need a bool?
  43. std::uint16_t port_number_ = 0;
  44. host_type host_type_ =
  45. urls::host_type::none;
  46. scheme scheme_ =
  47. urls::scheme::none;
  48. from from_ = from::string;
  49. url_impl(
  50. from b) noexcept
  51. : from_(b)
  52. {
  53. }
  54. // in url_view.ipp
  55. url_view construct() const noexcept;
  56. // in authority_view.ipp
  57. authority_view
  58. construct_authority() const noexcept;
  59. std::size_t len(int, int) const noexcept;
  60. std::size_t len(int) const noexcept;
  61. std::size_t offset(int) const noexcept;
  62. core::string_view get(int) const noexcept;
  63. core::string_view get(int, int) const noexcept;
  64. pct_string_view pct_get(int) const noexcept;
  65. pct_string_view pct_get(int, int) const noexcept;
  66. void set_size(int, std::size_t) noexcept;
  67. void split(int, std::size_t) noexcept;
  68. void adjust_right(int first, int last, std::size_t n) noexcept;
  69. void adjust_left(int first, int last, std::size_t n) noexcept;
  70. void collapse(int, int, std::size_t) noexcept;
  71. void apply_scheme(core::string_view) noexcept;
  72. void apply_userinfo(pct_string_view const&,
  73. pct_string_view const*) noexcept;
  74. void apply_host(host_type, pct_string_view,
  75. unsigned char const*) noexcept;
  76. void apply_port(core::string_view, unsigned short) noexcept;
  77. void apply_authority(authority_view const&) noexcept;
  78. void apply_path(pct_string_view, std::size_t) noexcept;
  79. void apply_query(pct_string_view, std::size_t) noexcept;
  80. void apply_frag(pct_string_view) noexcept;
  81. };
  82. //------------------------------------------------
  83. // this allows a path to come from a
  84. // url_impl or a separate core::string_view
  85. class path_ref
  86. : private parts_base
  87. {
  88. url_impl const* impl_ = nullptr;
  89. char const* data_ = nullptr;
  90. std::size_t size_ = 0;
  91. std::size_t nseg_ = 0;
  92. std::size_t dn_ = 0;
  93. public:
  94. path_ref() = default;
  95. path_ref(url_impl const& impl) noexcept;
  96. path_ref(core::string_view,
  97. std::size_t, std::size_t) noexcept;
  98. pct_string_view buffer() const noexcept;
  99. std::size_t size() const noexcept;
  100. char const* data() const noexcept;
  101. char const* end() const noexcept;
  102. std::size_t nseg() const noexcept;
  103. std::size_t decoded_size() const noexcept;
  104. bool
  105. alias_of(
  106. url_impl const& impl) const noexcept
  107. {
  108. return impl_ == &impl;
  109. }
  110. bool
  111. alias_of(
  112. path_ref const& ref) const noexcept
  113. {
  114. if(impl_)
  115. return impl_ == ref.impl_;
  116. BOOST_ASSERT(data_ != ref.data_ || (
  117. size_ == ref.size_ &&
  118. nseg_ == ref.nseg_ &&
  119. dn_ == ref.dn_));
  120. return data_ == ref.data_;
  121. }
  122. };
  123. //------------------------------------------------
  124. // This class represents a query string, which
  125. // can originate from either an url_impl object
  126. // or an independent core::string_view.
  127. class BOOST_URL_DECL query_ref
  128. : private parts_base
  129. {
  130. url_impl const* impl_ = nullptr;
  131. char const* data_ = nullptr;
  132. std::size_t size_ = 0;
  133. std::size_t nparam_ = 0;
  134. std::size_t dn_ = 0;
  135. bool question_mark_ = false;
  136. public:
  137. query_ref(
  138. core::string_view s, // buffer, no '?'
  139. std::size_t dn, // decoded size
  140. std::size_t nparam
  141. ) noexcept;
  142. query_ref() = default;
  143. query_ref(url_impl const& impl) noexcept;
  144. pct_string_view buffer() const noexcept;
  145. std::size_t size() const noexcept; // with '?'
  146. char const* begin() const noexcept; // no '?'
  147. char const* end() const noexcept;
  148. std::size_t nparam() const noexcept;
  149. bool
  150. alias_of(
  151. url_impl const& impl) const noexcept
  152. {
  153. return impl_ == &impl;
  154. }
  155. bool
  156. alias_of(
  157. query_ref const& ref) const noexcept
  158. {
  159. if(impl_)
  160. return impl_ == ref.impl_;
  161. BOOST_ASSERT(data_ != ref.data_ || (
  162. size_ == ref.size_ &&
  163. nparam_ == ref.nparam_ &&
  164. dn_ == ref.dn_));
  165. return data_ == ref.data_;
  166. }
  167. };
  168. } // detail
  169. } // urls
  170. } // boost
  171. #endif