include/boost/url/impl/url.hpp

97.4% Lines (74/76) 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 5609 url::
25 5609 ~url()
26 {
27 5609 if(s_)
28 {
29 3663 BOOST_ASSERT(
30 cap_ != 0);
31 3663 deallocate(s_);
32 }
33 5609 }
34
35 // construct empty
36 inline
37 1108 url::
38 url() noexcept = default;
39
40 inline
41 636 url::
42 636 url(core::string_view s)
43 636 : url(parse_uri_reference(s
44 636 ).value(BOOST_URL_POS))
45 {
46 636 }
47
48 inline
49 1503 url::
50 1503 url(url&& u) noexcept
51 1503 : url_base(u.impl_)
52 {
53 1503 s_ = u.s_;
54 1503 cap_ = u.cap_;
55 1503 u.s_ = nullptr;
56 1503 u.cap_ = 0;
57 1503 u.impl_ = {from::url};
58 1503 }
59
60 inline
61 url&
62 383 url::
63 operator=(url&& u) noexcept
64 {
65 383 if(s_)
66 2 deallocate(s_);
67 383 impl_ = u.impl_;
68 383 s_ = u.s_;
69 383 cap_ = u.cap_;
70 383 u.s_ = nullptr;
71 383 u.cap_ = 0;
72 383 u.impl_ = {from::url};
73 383 return *this;
74 }
75
76 //------------------------------------------------
77
78 inline
79 char*
80 4697 url::
81 allocate(std::size_t n)
82 {
83 4697 auto s = new char[n + 1];
84 4697 cap_ = n;
85 4697 return s;
86 }
87
88 inline
89 void
90 4697 url::
91 deallocate(char* s)
92 {
93 4697 delete[] s;
94 4697 }
95
96 inline
97 void
98 119 url::
99 clear_impl() noexcept
100 {
101 119 if(s_)
102 {
103 // preserve capacity
104 2 impl_ = {from::url};
105 2 s_[0] = '\0';
106 2 impl_.cs_ = s_;
107 }
108 else
109 {
110 117 BOOST_ASSERT(impl_.cs_[0] == 0);
111 }
112 119 }
113
114 inline
115 void
116 5907 url::
117 reserve_impl(
118 std::size_t n,
119 op_t& op)
120 {
121 5907 if(n > max_size())
122 detail::throw_length_error();
123 5907 if(n <= cap_)
124 1210 return;
125 char* s;
126 4697 if(s_ != nullptr)
127 {
128 // 50% growth policy
129 1032 auto const h = cap_ / 2;
130 std::size_t new_cap;
131 1032 if(cap_ <= max_size() - h)
132 1032 new_cap = cap_ + h;
133 else
134 new_cap = max_size();
135 1032 if( new_cap < n)
136 495 new_cap = n;
137 1032 s = allocate(new_cap);
138 1032 std::memcpy(s, s_, size() + 1);
139 1032 BOOST_ASSERT(! op.old);
140 1032 op.old = s_;
141 1032 s_ = s;
142 }
143 else
144 {
145 3665 s_ = allocate(n);
146 3665 s_[0] = '\0';
147 }
148 4697 impl_.cs_ = s_;
149 }
150
151 inline
152 void
153 1032 url::
154 cleanup(
155 op_t& op)
156 {
157 1032 if(op.old)
158 1032 deallocate(op.old);
159 1032 }
160
161 //------------------------------------------------
162
163 inline
164 void
165 2 url::
166 swap(url& other) noexcept
167 {
168 2 if (this == &other)
169 1 return;
170 1 std::swap(s_, other.s_);
171 1 std::swap(cap_, other.cap_);
172 1 std::swap(impl_, other.impl_);
173 1 std::swap(external_impl_, other.external_impl_);
174 }
175
176 } // urls
177 } // boost
178
179 #endif
180