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 : std::size_t decoded_size() const noexcept;
122 :
123 : bool
124 1194 : alias_of(
125 : url_impl const& impl) const noexcept
126 : {
127 1194 : return impl_ == &impl;
128 : }
129 :
130 : bool
131 5162 : alias_of(
132 : path_ref const& ref) const noexcept
133 : {
134 5162 : if(impl_)
135 2511 : return impl_ == ref.impl_;
136 2651 : BOOST_ASSERT(data_ != ref.data_ || (
137 : size_ == ref.size_ &&
138 : nseg_ == ref.nseg_ &&
139 : dn_ == ref.dn_));
140 2651 : return data_ == ref.data_;
141 : }
142 : };
143 :
144 : //------------------------------------------------
145 :
146 : // This class represents a query string, which
147 : // can originate from either an url_impl object
148 : // or an independent core::string_view.
149 : class BOOST_URL_DECL query_ref
150 : : private parts_base
151 : {
152 : url_impl const* impl_ = nullptr;
153 : char const* data_ = nullptr;
154 : std::size_t size_ = 0;
155 : std::size_t nparam_ = 0;
156 : std::size_t dn_ = 0;
157 : bool question_mark_ = false;
158 :
159 : public:
160 : query_ref(
161 : core::string_view s, // buffer, no '?'
162 : std::size_t dn, // decoded size
163 : std::size_t nparam
164 : ) noexcept;
165 9 : query_ref() = default;
166 : query_ref(url_impl const& impl) noexcept;
167 : pct_string_view buffer() const noexcept;
168 : std::size_t size() const noexcept; // with '?'
169 : char const* begin() const noexcept; // no '?'
170 : char const* end() const noexcept;
171 : std::size_t nparam() const noexcept;
172 :
173 : bool
174 286 : alias_of(
175 : url_impl const& impl) const noexcept
176 : {
177 286 : return impl_ == &impl;
178 : }
179 :
180 : bool
181 2463 : alias_of(
182 : query_ref const& ref) const noexcept
183 : {
184 2463 : if(impl_)
185 718 : return impl_ == ref.impl_;
186 1745 : BOOST_ASSERT(data_ != ref.data_ || (
187 : size_ == ref.size_ &&
188 : nparam_ == ref.nparam_ &&
189 : dn_ == ref.dn_));
190 1745 : return data_ == ref.data_;
191 : }
192 : };
193 :
194 : } // detail
195 :
196 : } // urls
197 : } // boost
198 :
199 : #endif
|