TLA 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 BOOST_SYMBOL_VISIBLE 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 HIT 17467 : url_impl(
70 : from b) noexcept
71 17467 : : from_(b)
72 : {
73 17467 : }
74 :
75 : BOOST_URL_CXX20_CONSTEXPR std::size_t len(int, int) const noexcept;
76 : BOOST_URL_CXX20_CONSTEXPR std::size_t len(int) const noexcept;
77 : BOOST_URL_CXX20_CONSTEXPR std::size_t offset(int) const noexcept;
78 : BOOST_URL_CXX20_CONSTEXPR core::string_view get(int) const noexcept;
79 : BOOST_URL_CXX20_CONSTEXPR core::string_view get(int, int) const noexcept;
80 : BOOST_URL_CXX20_CONSTEXPR pct_string_view pct_get(int) const noexcept;
81 : BOOST_URL_CXX20_CONSTEXPR pct_string_view pct_get(int, int) const noexcept;
82 : BOOST_URL_CXX20_CONSTEXPR void set_size(int, std::size_t) noexcept;
83 : BOOST_URL_CXX20_CONSTEXPR void split(int, std::size_t) noexcept;
84 : BOOST_URL_CXX20_CONSTEXPR void adjust_right(int first, int last, std::size_t n) noexcept;
85 : BOOST_URL_CXX20_CONSTEXPR void adjust_left(int first, int last, std::size_t n) noexcept;
86 : BOOST_URL_CXX20_CONSTEXPR void collapse(int, int, std::size_t) noexcept;
87 :
88 : BOOST_URL_CXX20_CONSTEXPR void apply_scheme(core::string_view) noexcept;
89 : BOOST_URL_CXX20_CONSTEXPR void apply_userinfo(pct_string_view const&,
90 : pct_string_view const*) noexcept;
91 : BOOST_URL_CXX20_CONSTEXPR void apply_host(host_type, pct_string_view,
92 : unsigned char const*) noexcept;
93 : BOOST_URL_CXX20_CONSTEXPR void apply_port(core::string_view, unsigned short) noexcept;
94 : BOOST_URL_CXX20_CONSTEXPR void apply_authority(url_impl const&) noexcept;
95 : BOOST_URL_CXX20_CONSTEXPR void apply_path(pct_string_view, std::size_t) noexcept;
96 : BOOST_URL_CXX20_CONSTEXPR void apply_query(pct_string_view, std::size_t) noexcept;
97 : BOOST_URL_CXX20_CONSTEXPR void apply_frag(pct_string_view) noexcept;
98 : };
99 :
100 : // url_impl stores 32-bit sizes; centralize narrowing with checks.
101 : BOOST_URL_CXX14_CONSTEXPR_OR_INLINE
102 : url_impl::size_type
103 128627 : to_size_type(std::size_t n) noexcept
104 : {
105 128627 : BOOST_ASSERT(n <= BOOST_URL_MAX_SIZE);
106 128627 : BOOST_ASSERT(n <= UINT32_MAX);
107 128627 : return static_cast<url_impl::size_type>(n);
108 : }
109 :
110 : BOOST_URL_CXX14_CONSTEXPR_OR_INLINE
111 : url_impl::size_type
112 1269 : to_size_type(std::ptrdiff_t n) noexcept
113 : {
114 1269 : BOOST_ASSERT(n >= 0);
115 1269 : return to_size_type(
116 1269 : static_cast<std::size_t>(n));
117 : }
118 :
119 : //------------------------------------------------
120 :
121 : // this allows a path to come from a
122 : // url_impl or a separate core::string_view
123 : //
124 : // Header-only and BOOST_SYMBOL_VISIBLE since all
125 : // members are inline. Containing classes must also be
126 : // BOOST_SYMBOL_VISIBLE to avoid C4251 on MSVC.
127 : class BOOST_SYMBOL_VISIBLE path_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 nseg_ = 0;
134 : std::size_t dn_ = 0;
135 :
136 : public:
137 2 : path_ref() noexcept = default;
138 : path_ref(url_impl const& impl) noexcept;
139 : path_ref(core::string_view,
140 : std::size_t, std::size_t) noexcept;
141 : pct_string_view buffer() const noexcept;
142 : std::size_t size() const noexcept;
143 : char const* data() const noexcept;
144 : char const* end() const noexcept;
145 : std::size_t nseg() const noexcept;
146 : std::size_t decoded_size() const noexcept;
147 :
148 : bool
149 1196 : alias_of(
150 : url_impl const& impl) const noexcept
151 : {
152 1196 : return impl_ == &impl;
153 : }
154 :
155 : bool
156 5276 : alias_of(
157 : path_ref const& ref) const noexcept
158 : {
159 5276 : if(impl_)
160 2511 : return impl_ == ref.impl_;
161 2765 : BOOST_ASSERT(data_ != ref.data_ || (
162 : size_ == ref.size_ &&
163 : nseg_ == ref.nseg_ &&
164 : dn_ == ref.dn_));
165 2765 : return data_ == ref.data_;
166 : }
167 : };
168 :
169 : //------------------------------------------------
170 :
171 : // This class represents a query string, which
172 : // can originate from either an url_impl object
173 : // or an independent core::string_view.
174 : class BOOST_SYMBOL_VISIBLE query_ref
175 : : private parts_base
176 : {
177 : url_impl const* impl_ = nullptr;
178 : char const* data_ = nullptr;
179 : std::size_t size_ = 0;
180 : std::size_t nparam_ = 0;
181 : std::size_t dn_ = 0;
182 : bool question_mark_ = false;
183 :
184 : public:
185 : query_ref(
186 : core::string_view s, // buffer, no '?'
187 : std::size_t dn, // decoded size
188 : std::size_t nparam
189 : ) noexcept;
190 9 : query_ref() = default;
191 : query_ref(url_impl const& impl) noexcept;
192 : pct_string_view buffer() const noexcept;
193 : std::size_t size() const noexcept; // with '?'
194 : char const* begin() const noexcept; // no '?'
195 : char const* end() const noexcept;
196 : std::size_t nparam() const noexcept;
197 :
198 : bool
199 294 : alias_of(
200 : url_impl const& impl) const noexcept
201 : {
202 294 : return impl_ == &impl;
203 : }
204 :
205 : bool
206 2614 : alias_of(
207 : query_ref const& ref) const noexcept
208 : {
209 2614 : if(impl_)
210 721 : return impl_ == ref.impl_;
211 1893 : BOOST_ASSERT(data_ != ref.data_ || (
212 : size_ == ref.size_ &&
213 : nparam_ == ref.nparam_ &&
214 : dn_ == ref.dn_));
215 1893 : return data_ == ref.data_;
216 : }
217 : };
218 :
219 : } // detail
220 :
221 : } // urls
222 : } // boost
223 :
224 : #include <boost/url/detail/impl/url_impl.hpp>
225 :
226 : #endif
|