include/boost/url/detail/url_impl.hpp

100.0% Lines (27/27) 100.0% Functions (9/9)
include/boost/url/detail/url_impl.hpp
Line TLA 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 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 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
227