LCOV - code coverage report
Current view: top level - capy/buffers - circular_dynamic_buffer.hpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 17 17
Test Date: 2026-05-14 20:50:55 Functions: 100.0 % 5 5

           TLA  Line data    Source code
       1                 : //
       2                 : // Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.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/cppalliance/capy
       8                 : //
       9                 : 
      10                 : #ifndef BOOST_CAPY_BUFFERS_CIRCULAR_DYNAMIC_BUFFER_HPP
      11                 : #define BOOST_CAPY_BUFFERS_CIRCULAR_DYNAMIC_BUFFER_HPP
      12                 : 
      13                 : #include <boost/capy/detail/config.hpp>
      14                 : #include <boost/capy/buffers.hpp>
      15                 : #include <boost/capy/detail/except.hpp>
      16                 : 
      17                 : #include <array>
      18                 : 
      19                 : namespace boost {
      20                 : namespace capy {
      21                 : 
      22                 : /** A fixed-capacity circular buffer satisfying DynamicBuffer.
      23                 : 
      24                 :     This class implements a circular ( ring ) buffer with
      25                 :     fixed capacity determined at construction. Unlike linear
      26                 :     buffers, data can wrap around from the end to the beginning,
      27                 :     enabling efficient FIFO operations without memory copies.
      28                 : 
      29                 :     Buffer sequences returned from @ref data and @ref prepare
      30                 :     may contain up to two elements to represent wrapped regions.
      31                 : 
      32                 :     @par Example
      33                 :     @code
      34                 :     char storage[1024];
      35                 :     circular_dynamic_buffer cb( storage, sizeof( storage ) );
      36                 : 
      37                 :     // Write data
      38                 :     auto mb = cb.prepare( 100 );
      39                 :     std::memcpy( mb.data(), "hello", 5 );
      40                 :     cb.commit( 5 );
      41                 : 
      42                 :     // Read data
      43                 :     auto cb_data = cb.data();
      44                 :     // process cb_data...
      45                 :     cb.consume( 5 );
      46                 :     @endcode
      47                 : 
      48                 :     @par Thread Safety
      49                 :     Distinct objects: Safe.
      50                 :     Shared objects: Unsafe.
      51                 : 
      52                 :     @see flat_dynamic_buffer, string_dynamic_buffer
      53                 : */
      54                 : class circular_dynamic_buffer
      55                 : {
      56                 :     unsigned char* base_ = nullptr;
      57                 :     std::size_t cap_ = 0;
      58                 :     std::size_t in_pos_ = 0;
      59                 :     std::size_t in_len_ = 0;
      60                 :     std::size_t out_size_ = 0;
      61                 : 
      62                 : public:
      63                 :     /// Indicates this is a DynamicBuffer adapter over external storage.
      64                 :     using is_dynamic_buffer_adapter = void;
      65                 : 
      66                 :     /// The ConstBufferSequence type for readable bytes.
      67                 :     using const_buffers_type = std::array<const_buffer, 2>;
      68                 : 
      69                 :     /// The MutableBufferSequence type for writable bytes.
      70                 :     using mutable_buffers_type = std::array<mutable_buffer, 2>;
      71                 : 
      72                 :     /// Construct an empty circular buffer with zero capacity.
      73                 :     circular_dynamic_buffer() = default;
      74                 : 
      75                 :     /** Construct a copy.
      76                 : 
      77                 :         Copies the adapter state (position and length) but does
      78                 :         not deep-copy the backing storage. Both objects alias the
      79                 :         same external buffer.
      80                 : 
      81                 :         @note The underlying storage must outlive all copies.
      82                 :     */
      83                 :     circular_dynamic_buffer(
      84                 :         circular_dynamic_buffer const&) = default;
      85                 : 
      86                 :     /** Construct a circular buffer over existing storage.
      87                 : 
      88                 :         @param base Pointer to the storage.
      89                 :         @param capacity Size of the storage in bytes.
      90                 :     */
      91 HIT         327 :     circular_dynamic_buffer(
      92                 :         void* base,
      93                 :         std::size_t capacity) noexcept
      94             327 :         : base_(static_cast<
      95                 :             unsigned char*>(base))
      96             327 :         , cap_(capacity)
      97                 :     {
      98             327 :     }
      99                 : 
     100                 :     /** Construct a circular buffer with initial readable bytes.
     101                 : 
     102                 :         @param base Pointer to the storage.
     103                 :         @param capacity Size of the storage in bytes.
     104                 :         @param initial_size Number of bytes already present as
     105                 :             readable. Must not exceed @p capacity.
     106                 : 
     107                 :         @throws std::invalid_argument if initial_size > capacity.
     108                 :     */
     109               2 :     circular_dynamic_buffer(
     110                 :         void* base,
     111                 :         std::size_t capacity,
     112                 :         std::size_t initial_size)
     113               2 :         : base_(static_cast<
     114                 :             unsigned char*>(base))
     115               2 :         , cap_(capacity)
     116               2 :         , in_len_(initial_size)
     117                 :     {
     118               2 :         if(in_len_ > capacity)
     119               1 :             detail::throw_invalid_argument();
     120               1 :     }
     121                 : 
     122                 :     /** Assign by copying.
     123                 : 
     124                 :         Copies the adapter state but does not deep-copy the
     125                 :         backing storage. Both objects alias the same external
     126                 :         buffer afterward.
     127                 : 
     128                 :         @note The underlying storage must outlive all copies.
     129                 :     */
     130                 :     circular_dynamic_buffer& operator=(
     131                 :         circular_dynamic_buffer const&) = default;
     132                 : 
     133                 :     /// Return the number of readable bytes.
     134                 :     std::size_t
     135            1520 :     size() const noexcept
     136                 :     {
     137            1520 :         return in_len_;
     138                 :     }
     139                 : 
     140                 :     /// Return the maximum number of bytes the buffer can hold.
     141                 :     std::size_t
     142               7 :     max_size() const noexcept
     143                 :     {
     144               7 :         return cap_;
     145                 :     }
     146                 : 
     147                 :     /// Return the number of writable bytes without reallocation.
     148                 :     std::size_t
     149               7 :     capacity() const noexcept
     150                 :     {
     151               7 :         return cap_ - in_len_;
     152                 :     }
     153                 : 
     154                 :     /// Return a buffer sequence representing the readable bytes.
     155                 :     BOOST_CAPY_DECL
     156                 :     const_buffers_type
     157                 :     data() const noexcept;
     158                 : 
     159                 :     /** Return a buffer sequence for writing.
     160                 : 
     161                 :         Invalidates buffer sequences previously obtained
     162                 :         from @ref prepare.
     163                 : 
     164                 :         @param n The desired number of writable bytes.
     165                 : 
     166                 :         @return A mutable buffer sequence of size @p n.
     167                 : 
     168                 :         @throws std::length_error if `size() + n > max_size()`.
     169                 :     */
     170                 :     BOOST_CAPY_DECL
     171                 :     mutable_buffers_type
     172                 :     prepare(std::size_t n);
     173                 : 
     174                 :     /** Move bytes from the output to the input sequence.
     175                 : 
     176                 :         Invalidates buffer sequences previously obtained
     177                 :         from @ref prepare. Buffer sequences from @ref data
     178                 :         remain valid.
     179                 : 
     180                 :         @param n The number of bytes to commit. If greater
     181                 :             than the prepared size, all prepared bytes
     182                 :             are committed.
     183                 :     */
     184                 :     BOOST_CAPY_DECL
     185                 :     void
     186                 :     commit(std::size_t n) noexcept;
     187                 : 
     188                 :     /** Remove bytes from the beginning of the input sequence.
     189                 : 
     190                 :         Invalidates buffer sequences previously obtained
     191                 :         from @ref data. Buffer sequences from @ref prepare
     192                 :         remain valid.
     193                 : 
     194                 :         @param n The number of bytes to consume. If greater
     195                 :             than @ref size(), all readable bytes are consumed.
     196                 :     */
     197                 :     BOOST_CAPY_DECL
     198                 :     void
     199                 :     consume(std::size_t n) noexcept;
     200                 : };
     201                 : 
     202                 : } // capy
     203                 : } // boost
     204                 : 
     205                 : #endif
        

Generated by: LCOV version 2.3