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