libs/url/include/boost/url/detail/url_impl.hpp

100.0% Lines (26/26) 100.0% Functions (8/8) 57.7% Branches (15/26)
libs/url/include/boost/url/detail/url_impl.hpp
Line Branch Hits Source Code
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
10 #ifndef BOOST_URL_DETAIL_URL_IMPL_HPP
11 #define BOOST_URL_DETAIL_URL_IMPL_HPP
12
13 #include <boost/url/host_type.hpp>
14 #include <boost/url/pct_string_view.hpp>
15 #include <boost/url/scheme.hpp>
16 #include <boost/core/detail/string_view.hpp>
17 #include <boost/url/detail/parts_base.hpp>
18 #include <boost/assert.hpp>
19 #include <cstddef>
20 #include <cstdint>
21
22 namespace boost {
23 namespace urls {
24
25 class url_view;
26 class authority_view;
27
28 namespace detail {
29
30 constexpr char const* const empty_c_str_ = "";
31
32 // This is the private 'guts' of a
33 // url_view, exposed so different parts
34 // of the implementation can work on it.
35 // It stores the offsets and properties of
36 // a URL string stored elsewhere and pointed
37 // to by cs_.
38 struct BOOST_URL_DECL url_impl : parts_base
39 {
40 using size_type = std::uint32_t;
41
42 static_assert(
43 BOOST_URL_MAX_SIZE <= UINT32_MAX,
44 "BOOST_URL_MAX_SIZE exceeds 32-bit url_impl capacity");
45
46 static
47 constexpr
48 std::size_t const zero_ = 0;
49
50 // never nullptr
51 char const* cs_ = empty_c_str_;
52
53 size_type offset_[id_end + 1] = {};
54 size_type decoded_[id_end] = {};
55 size_type nseg_ = 0;
56 size_type nparam_ = 0;
57 unsigned char ip_addr_[16] = {};
58 // VFALCO don't we need a bool?
59 std::uint16_t port_number_ = 0;
60 host_type host_type_ =
61 urls::host_type::none;
62 scheme scheme_ =
63 urls::scheme::none;
64
65 from from_ = from::string;
66
67 17388 url_impl(
68 from b) noexcept
69 17388 : from_(b)
70 {
71 17388 }
72
73 // in url_view.ipp
74 url_view construct() const noexcept;
75
76 // in authority_view.ipp
77 authority_view
78 construct_authority() const noexcept;
79
80 std::size_t len(int, int) const noexcept;
81 std::size_t len(int) const noexcept;
82 std::size_t offset(int) const noexcept;
83 core::string_view get(int) const noexcept;
84 core::string_view get(int, int) const noexcept;
85 pct_string_view pct_get(int) const noexcept;
86 pct_string_view pct_get(int, int) const noexcept;
87 void set_size(int, std::size_t) noexcept;
88 void split(int, std::size_t) noexcept;
89 void adjust_right(int first, int last, std::size_t n) noexcept;
90 void adjust_left(int first, int last, std::size_t n) noexcept;
91 void collapse(int, int, std::size_t) noexcept;
92
93 void apply_scheme(core::string_view) noexcept;
94 void apply_userinfo(pct_string_view const&,
95 pct_string_view const*) noexcept;
96 void apply_host(host_type, pct_string_view,
97 unsigned char const*) noexcept;
98 void apply_port(core::string_view, unsigned short) noexcept;
99 void apply_authority(authority_view const&) noexcept;
100 void apply_path(pct_string_view, std::size_t) noexcept;
101 void apply_query(pct_string_view, std::size_t) noexcept;
102 void apply_frag(pct_string_view) noexcept;
103 };
104
105 // url_impl stores 32-bit sizes; centralize narrowing with checks.
106 inline
107 url_impl::size_type
108 128036 to_size_type(std::size_t n) noexcept
109 {
110
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 128036 times.
128036 BOOST_ASSERT(n <= BOOST_URL_MAX_SIZE);
111
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 128036 times.
128036 BOOST_ASSERT(n <= UINT32_MAX);
112 128036 return static_cast<url_impl::size_type>(n);
113 }
114
115 inline
116 url_impl::size_type
117 1263 to_size_type(std::ptrdiff_t n) noexcept
118 {
119
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1263 times.
1263 BOOST_ASSERT(n >= 0);
120 1263 return to_size_type(
121 1263 static_cast<std::size_t>(n));
122 }
123
124 //------------------------------------------------
125
126 // this allows a path to come from a
127 // url_impl or a separate core::string_view
128 class path_ref
129 : private parts_base
130 {
131 url_impl const* impl_ = nullptr;
132 char const* data_ = nullptr;
133 std::size_t size_ = 0;
134 std::size_t nseg_ = 0;
135 std::size_t dn_ = 0;
136
137 public:
138 path_ref() = default;
139 path_ref(url_impl const& impl) noexcept;
140 path_ref(core::string_view,
141 std::size_t, std::size_t) noexcept;
142 pct_string_view buffer() const noexcept;
143 std::size_t size() const noexcept;
144 char const* data() const noexcept;
145 char const* end() const noexcept;
146 std::size_t nseg() const noexcept;
147 std::size_t decoded_size() const noexcept;
148
149 bool
150 1196 alias_of(
151 url_impl const& impl) const noexcept
152 {
153 1196 return impl_ == &impl;
154 }
155
156 bool
157 5276 alias_of(
158 path_ref const& ref) const noexcept
159 {
160
2/2
✓ Branch 0 taken 2511 times.
✓ Branch 1 taken 2765 times.
5276 if(impl_)
161 2511 return impl_ == ref.impl_;
162
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_ || (
163 size_ == ref.size_ &&
164 nseg_ == ref.nseg_ &&
165 dn_ == ref.dn_));
166 2765 return data_ == ref.data_;
167 }
168 };
169
170 //------------------------------------------------
171
172 // This class represents a query string, which
173 // can originate from either an url_impl object
174 // or an independent core::string_view.
175 class BOOST_URL_DECL query_ref
176 : private parts_base
177 {
178 url_impl const* impl_ = nullptr;
179 char const* data_ = nullptr;
180 std::size_t size_ = 0;
181 std::size_t nparam_ = 0;
182 std::size_t dn_ = 0;
183 bool question_mark_ = false;
184
185 public:
186 query_ref(
187 core::string_view s, // buffer, no '?'
188 std::size_t dn, // decoded size
189 std::size_t nparam
190 ) noexcept;
191 9 query_ref() = default;
192 query_ref(url_impl const& impl) noexcept;
193 pct_string_view buffer() const noexcept;
194 std::size_t size() const noexcept; // with '?'
195 char const* begin() const noexcept; // no '?'
196 char const* end() const noexcept;
197 std::size_t nparam() const noexcept;
198
199 bool
200 294 alias_of(
201 url_impl const& impl) const noexcept
202 {
203 294 return impl_ == &impl;
204 }
205
206 bool
207 2570 alias_of(
208 query_ref const& ref) const noexcept
209 {
210
2/2
✓ Branch 0 taken 721 times.
✓ Branch 1 taken 1849 times.
2570 if(impl_)
211 721 return impl_ == ref.impl_;
212
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_ || (
213 size_ == ref.size_ &&
214 nparam_ == ref.nparam_ &&
215 dn_ == ref.dn_));
216 1849 return data_ == ref.data_;
217 }
218 };
219
220 } // detail
221
222 } // urls
223 } // boost
224
225 #endif
226