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 : 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 :