Line data Source code
1 : //
2 : // Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.com)
3 : // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
4 : //
5 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 : //
8 : // Official repository: https://github.com/boostorg/url
9 : //
10 :
11 : #ifndef BOOST_URL_DETAIL_URL_IMPL_HPP
12 : #define BOOST_URL_DETAIL_URL_IMPL_HPP
13 :
14 : #include <boost/url/host_type.hpp>
15 : #include <boost/url/pct_string_view.hpp>
16 : #include <boost/url/scheme.hpp>
17 : #include <boost/core/detail/string_view.hpp>
18 : #include <boost/url/detail/parts_base.hpp>
19 : #include <boost/assert.hpp>
20 : #include <cstddef>
21 : #include <cstdint>
22 :
23 : namespace boost {
24 : namespace urls {
25 :
26 : class url_view;
27 : class authority_view;
28 :
29 : namespace detail {
30 :
31 : constexpr char const* const empty_c_str_ = "";
32 :
33 : // This is the private 'guts' of a
34 : // url_view, exposed so different parts
35 : // of the implementation can work on it.
36 : // It stores the offsets and properties of
37 : // a URL string stored elsewhere and pointed
38 : // to by cs_.
39 : struct url_impl : parts_base
40 : {
41 : using size_type = std::uint32_t;
42 :
43 : static_assert(
44 : BOOST_URL_MAX_SIZE <= UINT32_MAX,
45 : "BOOST_URL_MAX_SIZE exceeds 32-bit url_impl capacity");
46 :
47 : static
48 : constexpr
49 : std::size_t const zero_ = 0;
50 :
51 : // never nullptr
52 : char const* cs_ = empty_c_str_;
53 :
54 : size_type offset_[id_end + 1] = {};
55 : size_type decoded_[id_end] = {};
56 : size_type nseg_ = 0;
57 : size_type nparam_ = 0;
58 : unsigned char ip_addr_[16] = {};
59 : // VFALCO don't we need a bool?
60 : std::uint16_t port_number_ = 0;
61 : host_type host_type_ =
62 : urls::host_type::none;
63 : scheme scheme_ =
64 : urls::scheme::none;
65 :
66 : from from_ = from::string;
67 :
68 : BOOST_URL_CXX14_CONSTEXPR
69 17411 : url_impl(
70 : from b) noexcept
71 17411 : : from_(b)
72 : {
73 17411 : }
74 :
75 : BOOST_URL_CXX14_CONSTEXPR
76 : url_view construct() const noexcept;
77 :
78 : BOOST_URL_CXX20_CONSTEXPR
79 : authority_view
80 : construct_authority() const noexcept;
81 :
82 : BOOST_URL_CXX20_CONSTEXPR std::size_t len(int, int) const noexcept;
83 : BOOST_URL_CXX20_CONSTEXPR std::size_t len(int) const noexcept;
84 : BOOST_URL_CXX20_CONSTEXPR std::size_t offset(int) const noexcept;
85 : BOOST_URL_CXX20_CONSTEXPR core::string_view get(int) const noexcept;
86 : BOOST_URL_CXX20_CONSTEXPR core::string_view get(int, int) const noexcept;
87 : BOOST_URL_CXX20_CONSTEXPR pct_string_view pct_get(int) const noexcept;
88 : BOOST_URL_CXX20_CONSTEXPR pct_string_view pct_get(int, int) const noexcept;
89 : BOOST_URL_CXX20_CONSTEXPR void set_size(int, std::size_t) noexcept;
90 : BOOST_URL_CXX20_CONSTEXPR void split(int, std::size_t) noexcept;
91 : BOOST_URL_CXX20_CONSTEXPR void adjust_right(int first, int last, std::size_t n) noexcept;
92 : BOOST_URL_CXX20_CONSTEXPR void adjust_left(int first, int last, std::size_t n) noexcept;
93 : BOOST_URL_CXX20_CONSTEXPR void collapse(int, int, std::size_t) noexcept;
94 :
95 : BOOST_URL_CXX20_CONSTEXPR void apply_scheme(core::string_view) noexcept;
96 : BOOST_URL_CXX20_CONSTEXPR void apply_userinfo(pct_string_view const&,
97 : pct_string_view const*) noexcept;
98 : BOOST_URL_CXX20_CONSTEXPR void apply_host(host_type, pct_string_view,
99 : unsigned char const*) noexcept;
100 : BOOST_URL_CXX20_CONSTEXPR void apply_port(core::string_view, unsigned short) noexcept;
101 : BOOST_URL_CXX20_CONSTEXPR void apply_authority(authority_view const&) noexcept;
102 : BOOST_URL_CXX20_CONSTEXPR void apply_path(pct_string_view, std::size_t) noexcept;
103 : BOOST_URL_CXX20_CONSTEXPR void apply_query(pct_string_view, std::size_t) noexcept;
104 : BOOST_URL_CXX20_CONSTEXPR void apply_frag(pct_string_view) noexcept;
105 : };
106 :
107 : // url_impl stores 32-bit sizes; centralize narrowing with checks.
108 : inline
109 : BOOST_URL_CXX14_CONSTEXPR
110 : url_impl::size_type
111 128420 : to_size_type(std::size_t n) noexcept
112 : {
113 128420 : BOOST_ASSERT(n <= BOOST_URL_MAX_SIZE);
114 128420 : BOOST_ASSERT(n <= UINT32_MAX);
115 128420 : return static_cast<url_impl::size_type>(n);
116 : }
117 :
118 : inline
119 : BOOST_URL_CXX14_CONSTEXPR
120 : url_impl::size_type
121 1269 : to_size_type(std::ptrdiff_t n) noexcept
122 : {
123 1269 : BOOST_ASSERT(n >= 0);
124 1269 : return to_size_type(
125 1269 : static_cast<std::size_t>(n));
126 : }
127 :
128 : //------------------------------------------------
129 :
130 : // this allows a path to come from a
131 : // url_impl or a separate core::string_view
132 : //
133 : // Exported (BOOST_URL_DECL) so that public classes
134 : // like segments_base and segments_encoded_base can
135 : // hold a path_ref member without triggering C4251.
136 : class BOOST_URL_DECL path_ref
137 : : private parts_base
138 : {
139 : url_impl const* impl_ = nullptr;
140 : char const* data_ = nullptr;
141 : std::size_t size_ = 0;
142 : std::size_t nseg_ = 0;
143 : std::size_t dn_ = 0;
144 :
145 : public:
146 : path_ref() noexcept;
147 : path_ref(url_impl const& impl) noexcept;
148 : path_ref(core::string_view,
149 : std::size_t, std::size_t) noexcept;
150 : pct_string_view buffer() const noexcept;
151 : std::size_t size() const noexcept;
152 : char const* data() const noexcept;
153 : char const* end() const noexcept;
154 : std::size_t nseg() const noexcept;
155 : std::size_t decoded_size() const noexcept;
156 :
157 : bool
158 1196 : alias_of(
159 : url_impl const& impl) const noexcept
160 : {
161 1196 : return impl_ == &impl;
162 : }
163 :
164 : bool
165 5276 : alias_of(
166 : path_ref const& ref) const noexcept
167 : {
168 5276 : if(impl_)
169 2511 : return impl_ == ref.impl_;
170 2765 : BOOST_ASSERT(data_ != ref.data_ || (
171 : size_ == ref.size_ &&
172 : nseg_ == ref.nseg_ &&
173 : dn_ == ref.dn_));
174 2765 : return data_ == ref.data_;
175 : }
176 : };
177 :
178 : //------------------------------------------------
179 :
180 : // This class represents a query string, which
181 : // can originate from either an url_impl object
182 : // or an independent core::string_view.
183 : class BOOST_URL_DECL query_ref
184 : : private parts_base
185 : {
186 : url_impl const* impl_ = nullptr;
187 : char const* data_ = nullptr;
188 : std::size_t size_ = 0;
189 : std::size_t nparam_ = 0;
190 : std::size_t dn_ = 0;
191 : bool question_mark_ = false;
192 :
193 : public:
194 : query_ref(
195 : core::string_view s, // buffer, no '?'
196 : std::size_t dn, // decoded size
197 : std::size_t nparam
198 : ) noexcept;
199 9 : query_ref() = default;
200 : query_ref(url_impl const& impl) noexcept;
201 : pct_string_view buffer() const noexcept;
202 : std::size_t size() const noexcept; // with '?'
203 : char const* begin() const noexcept; // no '?'
204 : char const* end() const noexcept;
205 : std::size_t nparam() const noexcept;
206 :
207 : bool
208 294 : alias_of(
209 : url_impl const& impl) const noexcept
210 : {
211 294 : return impl_ == &impl;
212 : }
213 :
214 : bool
215 2570 : alias_of(
216 : query_ref const& ref) const noexcept
217 : {
218 2570 : if(impl_)
219 721 : return impl_ == ref.impl_;
220 1849 : BOOST_ASSERT(data_ != ref.data_ || (
221 : size_ == ref.size_ &&
222 : nparam_ == ref.nparam_ &&
223 : dn_ == ref.dn_));
224 1849 : return data_ == ref.data_;
225 : }
226 : };
227 :
228 : } // detail
229 :
230 : } // urls
231 : } // boost
232 :
233 : // url_impl member definitions live in detail/impl/url_impl.hpp.
234 : // Some of those definitions (construct_authority, apply_authority)
235 : // need the complete authority_view type, and authority_view.hpp
236 : // includes this header — creating a circular dependency.
237 : // When authority_view.hpp is the includer, it defers this
238 : // include until after authority_view is fully defined.
239 : #ifndef BOOST_URL_AUTHORITY_VIEW_HPP
240 : #include <boost/url/detail/impl/url_impl.hpp>
241 : #endif
242 :
243 : #endif
|