static_buffer.ipp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. //
  2. // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // Official repository: https://github.com/boostorg/beast
  8. //
  9. #ifndef BOOST_BEAST_IMPL_STATIC_BUFFER_IPP
  10. #define BOOST_BEAST_IMPL_STATIC_BUFFER_IPP
  11. #include <boost/beast/core/static_buffer.hpp>
  12. #include <boost/asio/buffer.hpp>
  13. #include <boost/throw_exception.hpp>
  14. #include <stdexcept>
  15. namespace boost {
  16. namespace beast {
  17. static_buffer_base::
  18. static_buffer_base(
  19. void* p, std::size_t size) noexcept
  20. : begin_(static_cast<char*>(p))
  21. , capacity_(size)
  22. {
  23. }
  24. void
  25. static_buffer_base::
  26. clear() noexcept
  27. {
  28. in_off_ = 0;
  29. in_size_ = 0;
  30. out_size_ = 0;
  31. }
  32. auto
  33. static_buffer_base::
  34. data() const noexcept ->
  35. const_buffers_type
  36. {
  37. if(in_off_ + in_size_ <= capacity_)
  38. return {
  39. net::const_buffer{
  40. begin_ + in_off_, in_size_},
  41. net::const_buffer{
  42. begin_, 0}};
  43. return {
  44. net::const_buffer{
  45. begin_ + in_off_, capacity_ - in_off_},
  46. net::const_buffer{
  47. begin_, in_size_ - (capacity_ - in_off_)}};
  48. }
  49. auto
  50. static_buffer_base::
  51. data() noexcept ->
  52. mutable_data_type
  53. {
  54. if(in_off_ + in_size_ <= capacity_)
  55. return {
  56. net::mutable_buffer{
  57. begin_ + in_off_, in_size_},
  58. net::mutable_buffer{
  59. begin_, 0}};
  60. return {
  61. net::mutable_buffer{
  62. begin_ + in_off_, capacity_ - in_off_},
  63. net::mutable_buffer{
  64. begin_, in_size_ - (capacity_ - in_off_)}};
  65. }
  66. auto
  67. static_buffer_base::
  68. prepare(std::size_t n) ->
  69. mutable_buffers_type
  70. {
  71. using net::mutable_buffer;
  72. if(n > capacity_ - in_size_)
  73. BOOST_THROW_EXCEPTION(std::length_error{
  74. "static_buffer overflow"});
  75. out_size_ = n;
  76. auto const out_off =
  77. (in_off_ + in_size_) % capacity_;
  78. if(out_off + out_size_ <= capacity_ )
  79. return {
  80. net::mutable_buffer{
  81. begin_ + out_off, out_size_},
  82. net::mutable_buffer{
  83. begin_, 0}};
  84. return {
  85. net::mutable_buffer{
  86. begin_ + out_off, capacity_ - out_off},
  87. net::mutable_buffer{
  88. begin_, out_size_ - (capacity_ - out_off)}};
  89. }
  90. void
  91. static_buffer_base::
  92. commit(std::size_t n) noexcept
  93. {
  94. in_size_ += (std::min)(n, out_size_);
  95. out_size_ = 0;
  96. }
  97. void
  98. static_buffer_base::
  99. consume(std::size_t n) noexcept
  100. {
  101. if(n < in_size_)
  102. {
  103. in_off_ = (in_off_ + n) % capacity_;
  104. in_size_ -= n;
  105. }
  106. else
  107. {
  108. // rewind the offset, so the next call to prepare
  109. // can have a longer contiguous segment. this helps
  110. // algorithms optimized for larger buffers.
  111. in_off_ = 0;
  112. in_size_ = 0;
  113. }
  114. }
  115. } // beast
  116. } // boost
  117. #endif