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 <cstdint>
20 :
21 : namespace boost {
22 : namespace urls {
23 :
24 : class url_view;
25 : class authority_view;
26 :
27 : namespace detail {
28 :
29 : constexpr char const* const empty_c_str_ = "";
30 :
31 : // This is the private 'guts' of a
32 : // url_view, exposed so different parts
33 : // of the implementation can work on it.
34 : // It stores the offsets and properties of
35 : // a URL string stored elsewhere and pointed
36 : // to by cs_.
37 : struct BOOST_URL_DECL url_impl : parts_base
38 : {
39 : static
40 : constexpr
41 : std::size_t const zero_ = 0;
42 :
43 : // never nullptr
44 : char const* cs_ = empty_c_str_;
45 :
46 : std::size_t offset_[id_end + 1] = {};
47 : std::size_t decoded_[id_end] = {};
48 : std::size_t nseg_ = 0;
49 : std::size_t nparam_ = 0;
50 : unsigned char ip_addr_[16] = {};
51 : // VFALCO don't we need a bool?
52 : std::uint16_t port_number_ = 0;
53 : host_type host_type_ =
54 : urls::host_type::none;
55 : scheme scheme_ =
56 : urls::scheme::none;
57 :
58 : from from_ = from::string;
59 :
60 16876 : url_impl(
61 : from b) noexcept
62 16876 : : from_(b)
63 : {
64 16876 : }
65 :
66 : // in url_view.ipp
67 : url_view construct() const noexcept;
68 :
69 : // in authority_view.ipp
70 : authority_view
71 : construct_authority() const noexcept;
72 :
73 : std::size_t len(int, int) const noexcept;
74 : std::size_t len(int) const noexcept;
75 : std::size_t offset(int) const noexcept;
76 : core::string_view get(int) const noexcept;
77 : core::string_view get(int, int) const noexcept;
78 : pct_string_view pct_get(int) const noexcept;
79 : pct_string_view pct_get(int, int) const noexcept;
80 : void set_size(int, std::size_t) noexcept;
81 : void split(int, std::size_t) noexcept;
82 : void adjust_right(int first, int last, std::size_t n) noexcept;
83 : void adjust_left(int first, int last, std::size_t n) noexcept;
84 : void collapse(int, int, std::size_t) noexcept;
85 :
86 : void apply_scheme(core::string_view) noexcept;
87 : void apply_userinfo(pct_string_view const&,
88 : pct_string_view const*) noexcept;
89 : void apply_host(host_type, pct_string_view,
90 : unsigned char const*) noexcept;
91 : void apply_port(core::string_view, unsigned short) noexcept;
92 : void apply_authority(authority_view const&) noexcept;
93 : void apply_path(pct_string_view, std::size_t) noexcept;
94 : void apply_query(pct_string_view, std::size_t) noexcept;
95 : void apply_frag(pct_string_view) noexcept;
96 : };
97 :
98 : //------------------------------------------------
99 :
100 : // this allows a path to come from a
101 : // url_impl or a separate core::string_view
102 : class path_ref
103 : : private parts_base
104 : {
105 : url_impl const* impl_ = nullptr;
106 : char const* data_ = nullptr;
107 : std::size_t size_ = 0;
108 : std::size_t nseg_ = 0;
109 : std::size_t dn_ = 0;
110 :
111 : public:
112 : path_ref() = default;
113 : path_ref(url_impl const& impl) noexcept;
114 : path_ref(core::string_view,
115 : std::size_t, std::size_t) noexcept;
116 : pct_string_view buffer() const noexcept;
117 : std::size_t size() const noexcept;
118 : char const* data() const noexcept;
119 : char const* end() const noexcept;
120 : std::size_t nseg() const noexcept;
121 :
122 : bool
123 1194 : alias_of(
124 : url_impl const& impl) const noexcept
125 : {
126 1194 : return impl_ == &impl;
127 : }
128 :
129 : bool
130 5158 : alias_of(
131 : path_ref const& ref) const noexcept
132 : {
133 5158 : if(impl_)
134 2511 : return impl_ == ref.impl_;
135 2647 : BOOST_ASSERT(data_ != ref.data_ || (
136 : size_ == ref.size_ &&
137 : nseg_ == ref.nseg_ &&
138 : dn_ == ref.dn_));
139 2647 : return data_ == ref.data_;
140 : }
141 : };
142 :
143 : //------------------------------------------------
144 :
145 : // This class represents a query string, which
146 : // can originate from either an url_impl object
147 : // or an independent core::string_view.
148 : class BOOST_URL_DECL query_ref
149 : : private parts_base
150 : {
151 : url_impl const* impl_ = nullptr;
152 : char const* data_ = nullptr;
153 : std::size_t size_ = 0;
154 : std::size_t nparam_ = 0;
155 : std::size_t dn_ = 0;
156 : bool question_mark_ = false;
157 :
158 : public:
159 : query_ref(
160 : core::string_view s, // buffer, no '?'
161 : std::size_t dn, // decoded size
162 : std::size_t nparam
163 : ) noexcept;
164 9 : query_ref() = default;
165 : query_ref(url_impl const& impl) noexcept;
166 : pct_string_view buffer() const noexcept;
167 : std::size_t size() const noexcept; // with '?'
168 : char const* begin() const noexcept; // no '?'
169 : char const* end() const noexcept;
170 : std::size_t nparam() const noexcept;
171 :
172 : bool
173 286 : alias_of(
174 : url_impl const& impl) const noexcept
175 : {
176 286 : return impl_ == &impl;
177 : }
178 :
179 : bool
180 2463 : alias_of(
181 : query_ref const& ref) const noexcept
182 : {
183 2463 : if(impl_)
184 718 : return impl_ == ref.impl_;
185 1745 : BOOST_ASSERT(data_ != ref.data_ || (
186 : size_ == ref.size_ &&
187 : nparam_ == ref.nparam_ &&
188 : dn_ == ref.dn_));
189 1745 : return data_ == ref.data_;
190 : }
191 : };
192 :
193 : } // detail
194 :
195 : } // urls
196 : } // boost
197 :
198 : #endif
|