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