url.ipp 2.7 KB

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