Line data 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 17376 : url_impl(
68 : from b) noexcept
69 17376 : : from_(b)
70 : {
71 17376 : }
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 127872 : to_size_type(std::size_t n) noexcept
109 : {
110 127872 : BOOST_ASSERT(n <= BOOST_URL_MAX_SIZE);
111 127872 : BOOST_ASSERT(n <= UINT32_MAX);
112 127872 : 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 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 5276 : if(impl_)
161 2511 : return impl_ == ref.impl_;
162 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 2570 : if(impl_)
211 721 : return impl_ == ref.impl_;
212 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
|