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