LCOV - code coverage report
Current view: top level - boost/capy/buffers - circular_dynamic_buffer.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 17 17
Test Date: 2026-01-30 23:43:15 Functions: 100.0 % 5 5

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

Generated by: LCOV version 2.3