static_buffer.hpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  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_STATIC_BUFFER_HPP
  10. #define BOOST_BEAST_STATIC_BUFFER_HPP
  11. #include <boost/beast/core/detail/config.hpp>
  12. #include <boost/beast/core/detail/buffers_pair.hpp>
  13. #include <boost/asio/buffer.hpp>
  14. #include <cstddef>
  15. namespace boost {
  16. namespace beast {
  17. /** A dynamic buffer providing a fixed size, circular buffer.
  18. A dynamic buffer encapsulates memory storage that may be
  19. automatically resized as required, where the memory is
  20. divided into two regions: readable bytes followed by
  21. writable bytes. These memory regions are internal to
  22. the dynamic buffer, but direct access to the elements
  23. is provided to permit them to be efficiently used with
  24. I/O operations.
  25. Objects of this type meet the requirements of <em>DynamicBuffer</em>
  26. and have the following additional properties:
  27. @li A mutable buffer sequence representing the readable
  28. bytes is returned by @ref data when `this` is non-const.
  29. @li Buffer sequences representing the readable and writable
  30. bytes, returned by @ref data and @ref prepare, may have
  31. length up to two.
  32. @li All operations execute in constant time.
  33. @li Ownership of the underlying storage belongs to the
  34. derived class.
  35. @note Variables are usually declared using the template class
  36. @ref static_buffer; however, to reduce the number of template
  37. instantiations, objects should be passed `static_buffer_base&`.
  38. @see static_buffer
  39. */
  40. class static_buffer_base
  41. {
  42. char* begin_;
  43. std::size_t in_off_ = 0;
  44. std::size_t in_size_ = 0;
  45. std::size_t out_size_ = 0;
  46. std::size_t capacity_;
  47. static_buffer_base(static_buffer_base const& other) = delete;
  48. static_buffer_base& operator=(static_buffer_base const&) = delete;
  49. public:
  50. /** Constructor
  51. This creates a dynamic buffer using the provided storage area.
  52. @param p A pointer to valid storage of at least `n` bytes.
  53. @param size The number of valid bytes pointed to by `p`.
  54. */
  55. BOOST_BEAST_DECL
  56. static_buffer_base(void* p, std::size_t size) noexcept;
  57. /** Clear the readable and writable bytes to zero.
  58. This function causes the readable and writable bytes
  59. to become empty. The capacity is not changed.
  60. Buffer sequences previously obtained using @ref data or
  61. @ref prepare become invalid.
  62. @esafe
  63. No-throw guarantee.
  64. */
  65. BOOST_BEAST_DECL
  66. void
  67. clear() noexcept;
  68. //--------------------------------------------------------------------------
  69. #if BOOST_BEAST_DOXYGEN
  70. /// The ConstBufferSequence used to represent the readable bytes.
  71. using const_buffers_type = __implementation_defined__;
  72. /// The MutableBufferSequence used to represent the writable bytes.
  73. using mutable_buffers_type = __implementation_defined__;
  74. #else
  75. using const_buffers_type = detail::buffers_pair<false>;
  76. using mutable_buffers_type = detail::buffers_pair<true>;
  77. #endif
  78. /// Returns the number of readable bytes.
  79. std::size_t
  80. size() const noexcept
  81. {
  82. return in_size_;
  83. }
  84. /// Return the maximum number of bytes, both readable and writable, that can ever be held.
  85. std::size_t
  86. max_size() const noexcept
  87. {
  88. return capacity_;
  89. }
  90. /// Return the maximum number of bytes, both readable and writable, that can be held without requiring an allocation.
  91. std::size_t
  92. capacity() const noexcept
  93. {
  94. return capacity_;
  95. }
  96. /// Returns a constant buffer sequence representing the readable bytes
  97. BOOST_BEAST_DECL
  98. const_buffers_type
  99. data() const noexcept;
  100. /// Returns a constant buffer sequence representing the readable bytes
  101. const_buffers_type
  102. cdata() const noexcept
  103. {
  104. return data();
  105. }
  106. /// Returns a mutable buffer sequence representing the readable bytes
  107. BOOST_BEAST_DECL
  108. mutable_buffers_type
  109. data() noexcept;
  110. /** Returns a mutable buffer sequence representing writable bytes.
  111. Returns a mutable buffer sequence representing the writable
  112. bytes containing exactly `n` bytes of storage.
  113. All buffers sequences previously obtained using
  114. @ref data or @ref prepare may be invalidated.
  115. @param n The desired number of bytes in the returned buffer
  116. sequence.
  117. @throws std::length_error if `size() + n` exceeds `max_size()`.
  118. @esafe
  119. Strong guarantee.
  120. */
  121. BOOST_BEAST_DECL
  122. mutable_buffers_type
  123. prepare(std::size_t n);
  124. /** Append writable bytes to the readable bytes.
  125. Appends n bytes from the start of the writable bytes to the
  126. end of the readable bytes. The remainder of the writable bytes
  127. are discarded. If n is greater than the number of writable
  128. bytes, all writable bytes are appended to the readable bytes.
  129. All buffers sequences previously obtained using
  130. @ref data or @ref prepare are invalidated.
  131. @param n The number of bytes to append. If this number
  132. is greater than the number of writable bytes, all
  133. writable bytes are appended.
  134. @esafe
  135. No-throw guarantee.
  136. */
  137. BOOST_BEAST_DECL
  138. void
  139. commit(std::size_t n) noexcept;
  140. /** Remove bytes from beginning of the readable bytes.
  141. Removes n bytes from the beginning of the readable bytes.
  142. All buffers sequences previously obtained using
  143. @ref data or @ref prepare are invalidated.
  144. @param n The number of bytes to remove. If this number
  145. is greater than the number of readable bytes, all
  146. readable bytes are removed.
  147. @esafe
  148. No-throw guarantee.
  149. */
  150. BOOST_BEAST_DECL
  151. void
  152. consume(std::size_t n) noexcept;
  153. };
  154. //------------------------------------------------------------------------------
  155. /** A dynamic buffer providing a fixed size, circular buffer.
  156. A dynamic buffer encapsulates memory storage that may be
  157. automatically resized as required, where the memory is
  158. divided into two regions: readable bytes followed by
  159. writable bytes. These memory regions are internal to
  160. the dynamic buffer, but direct access to the elements
  161. is provided to permit them to be efficiently used with
  162. I/O operations.
  163. Objects of this type meet the requirements of <em>DynamicBuffer</em>
  164. and have the following additional properties:
  165. @li A mutable buffer sequence representing the readable
  166. bytes is returned by @ref data when `this` is non-const.
  167. @li Buffer sequences representing the readable and writable
  168. bytes, returned by @ref data and @ref prepare, may have
  169. length up to two.
  170. @li All operations execute in constant time.
  171. @tparam N The number of bytes in the internal buffer.
  172. @note To reduce the number of template instantiations when passing
  173. objects of this type in a deduced context, the signature of the
  174. receiving function should use @ref static_buffer_base instead.
  175. @see static_buffer_base
  176. */
  177. template<std::size_t N>
  178. class static_buffer : public static_buffer_base
  179. {
  180. char buf_[N];
  181. public:
  182. /// Constructor
  183. static_buffer() noexcept
  184. : static_buffer_base(buf_, N)
  185. {
  186. }
  187. /// Constructor
  188. static_buffer(static_buffer const&) noexcept;
  189. /// Assignment
  190. static_buffer& operator=(static_buffer const&) noexcept;
  191. /// Returns the @ref static_buffer_base portion of this object
  192. static_buffer_base&
  193. base() noexcept
  194. {
  195. return *this;
  196. }
  197. /// Returns the @ref static_buffer_base portion of this object
  198. static_buffer_base const&
  199. base() const noexcept
  200. {
  201. return *this;
  202. }
  203. /// Return the maximum sum of the input and output sequence sizes.
  204. std::size_t constexpr
  205. max_size() const noexcept
  206. {
  207. return N;
  208. }
  209. /// Return the maximum sum of input and output sizes that can be held without an allocation.
  210. std::size_t constexpr
  211. capacity() const noexcept
  212. {
  213. return N;
  214. }
  215. };
  216. } // beast
  217. } // boost
  218. #include <boost/beast/core/impl/static_buffer.hpp>
  219. #ifdef BOOST_BEAST_HEADER_ONLY
  220. #include <boost/beast/core/impl/static_buffer.ipp>
  221. #endif
  222. #endif