TLA Line data 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 HIT 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 MIS 0 : detail::throw_length_error();
125 HIT 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 MIS 0 : new_cap = max_size();
137 HIT 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
|