static_buffer.hpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  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 readable bytes.
  73. using mutable_data_type = __implementation_defined__;
  74. /// The MutableBufferSequence used to represent the writable bytes.
  75. using mutable_buffers_type = __implementation_defined__;
  76. #else
  77. using const_buffers_type = detail::buffers_pair<false>;
  78. using mutable_data_type = detail::buffers_pair<true>;
  79. using mutable_buffers_type = detail::buffers_pair<true>;
  80. #endif
  81. /// Returns the number of readable bytes.
  82. std::size_t
  83. size() const noexcept
  84. {
  85. return in_size_;
  86. }
  87. /// Return the maximum number of bytes, both readable and writable, that can ever be held.
  88. std::size_t
  89. max_size() const noexcept
  90. {
  91. return capacity_;
  92. }
  93. /// Return the maximum number of bytes, both readable and writable, that can be held without requiring an allocation.
  94. std::size_t
  95. capacity() const noexcept
  96. {
  97. return capacity_;
  98. }
  99. /// Returns a constant buffer sequence representing the readable bytes
  100. BOOST_BEAST_DECL
  101. const_buffers_type
  102. data() const noexcept;
  103. /// Returns a constant buffer sequence representing the readable bytes
  104. const_buffers_type
  105. cdata() const noexcept
  106. {
  107. return data();
  108. }
  109. /// Returns a mutable buffer sequence representing the readable bytes
  110. BOOST_BEAST_DECL
  111. mutable_data_type
  112. data() noexcept;
  113. /** Returns a mutable buffer sequence representing writable bytes.
  114. Returns a mutable buffer sequence representing the writable
  115. bytes containing exactly `n` bytes of storage. Memory may be
  116. reallocated as needed.
  117. All buffers sequences previously obtained using
  118. @ref data or @ref prepare are invalidated.
  119. @param n The desired number of bytes in the returned buffer
  120. sequence.
  121. @throws std::length_error if `size() + n` exceeds `max_size()`.
  122. @esafe
  123. Strong guarantee.
  124. */
  125. BOOST_BEAST_DECL
  126. mutable_buffers_type
  127. prepare(std::size_t n);
  128. /** Append writable bytes to the readable bytes.
  129. Appends n bytes from the start of the writable bytes to the
  130. end of the readable bytes. The remainder of the writable bytes
  131. are discarded. If n is greater than the number of writable
  132. bytes, all writable bytes are appended to the readable bytes.
  133. All buffers sequences previously obtained using
  134. @ref data or @ref prepare are invalidated.
  135. @param n The number of bytes to append. If this number
  136. is greater than the number of writable bytes, all
  137. writable bytes are appended.
  138. @esafe
  139. No-throw guarantee.
  140. */
  141. BOOST_BEAST_DECL
  142. void
  143. commit(std::size_t n) noexcept;
  144. /** Remove bytes from beginning of the readable bytes.
  145. Removes n bytes from the beginning of the readable bytes.
  146. All buffers sequences previously obtained using
  147. @ref data or @ref prepare are invalidated.
  148. @param n The number of bytes to remove. If this number
  149. is greater than the number of readable bytes, all
  150. readable bytes are removed.
  151. @esafe
  152. No-throw guarantee.
  153. */
  154. BOOST_BEAST_DECL
  155. void
  156. consume(std::size_t n) noexcept;
  157. };
  158. //------------------------------------------------------------------------------
  159. /** A dynamic buffer providing a fixed size, circular buffer.
  160. A dynamic buffer encapsulates memory storage that may be
  161. automatically resized as required, where the memory is
  162. divided into two regions: readable bytes followed by
  163. writable bytes. These memory regions are internal to
  164. the dynamic buffer, but direct access to the elements
  165. is provided to permit them to be efficiently used with
  166. I/O operations.
  167. Objects of this type meet the requirements of <em>DynamicBuffer</em>
  168. and have the following additional properties:
  169. @li A mutable buffer sequence representing the readable
  170. bytes is returned by @ref data when `this` is non-const.
  171. @li Buffer sequences representing the readable and writable
  172. bytes, returned by @ref data and @ref prepare, may have
  173. length up to two.
  174. @li All operations execute in constant time.
  175. @tparam N The number of bytes in the internal buffer.
  176. @note To reduce the number of template instantiations when passing
  177. objects of this type in a deduced context, the signature of the
  178. receiving function should use @ref static_buffer_base instead.
  179. @see static_buffer_base
  180. */
  181. template<std::size_t N>
  182. class static_buffer : public static_buffer_base
  183. {
  184. char buf_[N];
  185. public:
  186. /// Constructor
  187. static_buffer() noexcept
  188. : static_buffer_base(buf_, N)
  189. {
  190. }
  191. /// Constructor
  192. static_buffer(static_buffer const&) noexcept;
  193. /// Assignment
  194. static_buffer& operator=(static_buffer const&) noexcept;
  195. /// Returns the @ref static_buffer_base portion of this object
  196. static_buffer_base&
  197. base() noexcept
  198. {
  199. return *this;
  200. }
  201. /// Returns the @ref static_buffer_base portion of this object
  202. static_buffer_base const&
  203. base() const noexcept
  204. {
  205. return *this;
  206. }
  207. /// Return the maximum sum of the input and output sequence sizes.
  208. std::size_t constexpr
  209. max_size() const noexcept
  210. {
  211. return N;
  212. }
  213. /// Return the maximum sum of input and output sizes that can be held without an allocation.
  214. std::size_t constexpr
  215. capacity() const noexcept
  216. {
  217. return N;
  218. }
  219. };
  220. } // beast
  221. } // boost
  222. #include <boost/beast/core/impl/static_buffer.hpp>
  223. #ifdef BOOST_BEAST_HEADER_ONLY
  224. #include <boost/beast/core/impl/static_buffer.ipp>
  225. #endif
  226. #endif