include/boost/url/impl/url.hpp

97.4% Lines (76/78) 100.0% Functions (11/11)
include/boost/url/impl/url.hpp
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2019 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_IMPL_URL_HPP
12 #define BOOST_URL_IMPL_URL_HPP
13
14 #include <boost/url/detail/except.hpp>
15 #include <boost/assert.hpp>
16 #include <cstring>
17
18 namespace boost {
19 namespace urls {
20
21 //------------------------------------------------
22
23 inline
24 7220 url::
25 7220 ~url()
26 {
27 7220 if(s_)
28 {
29 5083 BOOST_ASSERT(
30 cap_ != 0);
31 5083 deallocate(s_);
32 }
33 7220 }
34
35 // construct empty
36 inline
37 1326 url::
38 url() noexcept = default;
39
40 inline
41 2345 url::
42 2345 url(core::string_view s)
43 2842 : url(parse_uri_reference(s
44 2345 ).value(BOOST_URL_POS))
45 {
46 1848 }
47
48 inline
49 1647 url::
50 1647 url(url&& u) noexcept
51 1647 : url_base(u.impl_)
52 {
53 1647 s_ = u.s_;
54 1647 cap_ = u.cap_;
55 1647 u.s_ = nullptr;
56 1647 u.cap_ = 0;
57 1647 u.impl_ = {from::url};
58 1647 }
59
60 inline
61 url&
62 659 url::
63 operator=(url&& u) noexcept
64 {
65 659 if(this == &u)
66 1 return *this;
67 658 if(s_)
68 3 deallocate(s_);
69 658 impl_ = u.impl_;
70 658 s_ = u.s_;
71 658 cap_ = u.cap_;
72 658 u.s_ = nullptr;
73 658 u.cap_ = 0;
74 658 u.impl_ = {from::url};
75 658 return *this;
76 }
77
78 //------------------------------------------------
79
80 inline
81 char*
82 7647 url::
83 allocate(std::size_t n)
84 {
85 7647 auto s = new char[n + 1];
86 7647 cap_ = n;
87 7647 return s;
88 }
89
90 inline
91 void
92 7647 url::
93 deallocate(char* s)
94 {
95 7647 delete[] s;
96 7647 }
97
98 inline
99 void
100 272 url::
101 clear_impl() noexcept
102 {
103 272 if(s_)
104 {
105 // preserve capacity
106 139 impl_ = {from::url};
107 139 s_[0] = '\0';
108 139 impl_.cs_ = s_;
109 }
110 else
111 {
112 133 BOOST_ASSERT(impl_.cs_[0] == 0);
113 }
114 272 }
115
116 inline
117 void
118 12751 url::
119 reserve_impl(
120 std::size_t n,
121 op_t& op)
122 {
123 12751 if(n > max_size())
124 detail::throw_length_error();
125 12751 if(n <= cap_)
126 5104 return;
127 char* s;
128 7647 if(s_ != nullptr)
129 {
130 // 50% growth policy
131 2561 auto const h = cap_ / 2;
132 std::size_t new_cap;
133 2561 if(cap_ <= max_size() - h)
134 2561 new_cap = cap_ + h;
135 else
136 new_cap = max_size();
137 2561 if( new_cap < n)
138 1171 new_cap = n;
139 2561 s = allocate(new_cap);
140 2561 std::memcpy(s, s_, size() + 1);
141 2561 BOOST_ASSERT(! op.old);
142 2561 op.old = s_;
143 2561 s_ = s;
144 }
145 else
146 {
147 5086 s_ = allocate(n);
148 5086 s_[0] = '\0';
149 }
150 7647 impl_.cs_ = s_;
151 }
152
153 inline
154 void
155 2561 url::
156 cleanup(
157 op_t& op)
158 {
159 2561 if(op.old)
160 2561 deallocate(op.old);
161 2561 }
162
163 //------------------------------------------------
164
165 inline
166 void
167 2 url::
168 swap(url& other) noexcept
169 {
170 2 if (this == &other)
171 1 return;
172 1 std::swap(s_, other.s_);
173 1 std::swap(cap_, other.cap_);
174 1 std::swap(impl_, other.impl_);
175 1 std::swap(external_impl_, other.external_impl_);
176 }
177
178 } // urls
179 } // boost
180
181 #endif
182