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 -
url::
 
23 -
~url()
 
24 -
{
 
25 -
    if(s_)
 
26 -
    {
 
27 -
        BOOST_ASSERT(
 
28 -
            cap_ != 0);
 
29 -
        deallocate(s_);
 
30 -
    }
 
31 -
}
 
32 -

 
33 -
// construct empty
 
34 -
url::
 
35 -
url() noexcept = default;
 
36 -

 
37 -
url::
 
38 -
url(core::string_view s)
 
39 -
    : url(parse_uri_reference(s
 
40 -
        ).value(BOOST_URL_POS))
 
41 -
{
 
42 -
}
 
43 -

 
44 -
url::
 
45 -
url(url&& u) noexcept
 
46 -
    : url_base(u.impl_)
 
47 -
{
 
48 -
    s_ = u.s_;
 
49 -
    cap_ = u.cap_;
 
50 -
    u.s_ = nullptr;
 
51 -
    u.cap_ = 0;
 
52 -
    u.impl_ = {from::url};
 
53 -
}
 
54 -

 
55 -
url&
 
56 -
url::
 
57 -
operator=(url&& u) noexcept
 
58 -
{
 
59 -
    if(s_)
 
60 -
        deallocate(s_);
 
61 -
    impl_ = u.impl_;
 
62 -
    s_ = u.s_;
 
63 -
    cap_ = u.cap_;
 
64 -
    u.s_ = nullptr;
 
65 -
    u.cap_ = 0;
 
66 -
    u.impl_ = {from::url};
 
67 -
    return *this;
 
68 -
}
 
69 -

 
70 -
//------------------------------------------------
 
71 -

 
72 -
char*
 
73 -
url::
 
74 -
allocate(std::size_t n)
 
75 -
{
 
76 -
    auto s = new char[n + 1];
 
77 -
    cap_ = n;
 
78 -
    return s;
 
79 -
}
 
80 -

 
81 -
void
 
82 -
url::
 
83 -
deallocate(char* s)
 
84 -
{
 
85 -
    delete[] s;
 
86 -
}
 
87 -

 
88 -
void
 
89 -
url::
 
90 -
clear_impl() noexcept
 
91 -
{
 
92 -
    if(s_)
 
93 -
    {
 
94 -
        // preserve capacity
 
95 -
        impl_ = {from::url};
 
96 -
        s_[0] = '\0';
 
97 -
        impl_.cs_ = s_;
 
98 -
    }
 
99 -
    else
 
100 -
    {
 
101 -
        BOOST_ASSERT(impl_.cs_[0] == 0);
 
102 -
    }
 
103 -
}
 
104 -

 
105 -
void
 
106 -
url::
 
107 -
reserve_impl(
 
108 -
    std::size_t n,
 
109 -
    op_t& op)
 
110 -
{
 
111 -
    if(n > max_size())
 
112 -
        detail::throw_length_error();
 
113 -
    if(n <= cap_)
 
114 -
        return;
 
115 -
    char* s;
 
116 -
    if(s_ != nullptr)
 
117 -
    {
 
118 -
        // 50% growth policy
 
119 -
        auto const h = cap_ / 2;
 
120 -
        std::size_t new_cap;
 
121 -
        if(cap_ <= max_size() - h)
 
122 -
            new_cap = cap_ + h;
 
123 -
        else
 
124 -
            new_cap = max_size();
 
125 -
        if( new_cap < n)
 
126 -
            new_cap = n;
 
127 -
        s = allocate(new_cap);
 
128 -
        std::memcpy(s, s_, size() + 1);
 
129 -
        BOOST_ASSERT(! op.old);
 
130 -
        op.old = s_;
 
131 -
        s_ = s;
 
132 -
    }
 
133 -
    else
 
134 -
    {
 
135 -
        s_ = allocate(n);
 
136 -
        s_[0] = '\0';
 
137 -
    }
 
138 -
    impl_.cs_ = s_;
 
139 -
}
 
140 -

 
141 -
void
 
142 -
url::
 
143 -
cleanup(
 
144 -
    op_t& op)
 
145 -
{
 
146 -
    if(op.old)
 
147 -
        deallocate(op.old);
 
148 -
}
 
149 -

 
150 -
//------------------------------------------------
 
151 -

 
152 -
void
 
153 -
url::
 
154 -
swap(url& other) noexcept
 
155 -
{
 
156 -
    if (this == &other)
 
157 -
        return;
 
158 -
    std::swap(s_, other.s_);
 
159 -
    std::swap(cap_, other.cap_);
 
160 -
    std::swap(impl_, other.impl_);
 
161 -
    std::swap(pi_, other.pi_);
 
162 -
    if (pi_ == &other.impl_)
 
163 -
        pi_ = &impl_;
 
164 -
    if (other.pi_ == &impl_)
 
165 -
        other.pi_ = &other.impl_;
 
166 -
}
 
167 -

 
168 -
} // urls
 
169 -
} // boost
 
170 -