include/boost/url/detail/url_impl.hpp

100.0% Lines (26/26) 100.0% Functions (8/8) 57.7% Branches (15/26)
include/boost/url/detail/url_impl.hpp
Line Branch Hits 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
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 128420 times.
128420 BOOST_ASSERT(n <= BOOST_URL_MAX_SIZE);
114
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 128420 times.
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
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1269 times.
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
2/2
✓ Branch 0 taken 2511 times.
✓ Branch 1 taken 2765 times.
5276 if(impl_)
169 2511 return impl_ == ref.impl_;
170
4/8
✓ Branch 0 taken 2765 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2765 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2765 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2765 times.
✗ Branch 7 not taken.
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
2/2
✓ Branch 0 taken 721 times.
✓ Branch 1 taken 1849 times.
2570 if(impl_)
219 721 return impl_ == ref.impl_;
220
4/8
✓ Branch 0 taken 1849 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1849 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1849 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1849 times.
✗ Branch 7 not taken.
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
244