LCOV - code coverage report
Current view: top level - capy/buffers - flat_dynamic_buffer.hpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 35 35
Test Date: 2026-02-17 18:14:47 Functions: 100.0 % 8 8

           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_FLAT_DYNAMIC_BUFFER_HPP
      11                 : #define BOOST_CAPY_BUFFERS_FLAT_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                 : namespace boost {
      18                 : namespace capy {
      19                 : 
      20                 : /** A fixed-capacity linear buffer satisfying DynamicBuffer.
      21                 : 
      22                 :     This class provides a contiguous buffer with fixed capacity
      23                 :     determined at construction. Buffer sequences returned from
      24                 :     @ref data and @ref prepare always contain exactly one element,
      25                 :     making it suitable for APIs requiring contiguous memory.
      26                 : 
      27                 :     @par Example
      28                 :     @code
      29                 :     char storage[1024];
      30                 :     flat_dynamic_buffer fb( storage, sizeof( storage ) );
      31                 : 
      32                 :     // Write data
      33                 :     auto mb = fb.prepare( 100 );
      34                 :     std::memcpy( mb.data(), "hello", 5 );
      35                 :     fb.commit( 5 );
      36                 : 
      37                 :     // Read data
      38                 :     auto data = fb.data();
      39                 :     // process data...
      40                 :     fb.consume( 5 );
      41                 :     @endcode
      42                 : 
      43                 :     @par Thread Safety
      44                 :     Distinct objects: Safe.
      45                 :     Shared objects: Unsafe.
      46                 : 
      47                 :     @see circular_dynamic_buffer, string_dynamic_buffer
      48                 : */
      49                 : class flat_dynamic_buffer
      50                 : {
      51                 :     unsigned char* data_ = nullptr;
      52                 :     std::size_t cap_ = 0;
      53                 :     std::size_t in_pos_ = 0;
      54                 :     std::size_t in_size_ = 0;
      55                 :     std::size_t out_size_ = 0;
      56                 : 
      57                 : public:
      58                 :     /// Indicates this is a DynamicBuffer adapter over external storage.
      59                 :     using is_dynamic_buffer_adapter = void;
      60                 : 
      61                 :     /// The ConstBufferSequence type for readable bytes.
      62                 :     using const_buffers_type = const_buffer;
      63                 : 
      64                 :     /// The MutableBufferSequence type for writable bytes.
      65                 :     using mutable_buffers_type = mutable_buffer;
      66                 : 
      67                 :     /// Construct an empty flat buffer with zero capacity.
      68                 :     flat_dynamic_buffer() = default;
      69                 : 
      70                 :     /** Construct a flat buffer over existing storage.
      71                 : 
      72                 :         @param data Pointer to the storage.
      73                 :         @param capacity Size of the storage in bytes.
      74                 :         @param initial_size Number of bytes already present as
      75                 :             readable. Must not exceed @p capacity.
      76                 : 
      77                 :         @throws std::invalid_argument if initial_size > capacity.
      78                 :     */
      79 HIT         223 :     flat_dynamic_buffer(
      80                 :         void* data,
      81                 :         std::size_t capacity,
      82                 :         std::size_t initial_size = 0)
      83             223 :         : data_(static_cast<
      84                 :             unsigned char*>(data))
      85             223 :         , cap_(capacity)
      86             223 :         , in_size_(initial_size)
      87                 :     {
      88             223 :         if(in_size_ > cap_)
      89               1 :             detail::throw_invalid_argument();
      90             222 :     }
      91                 : 
      92                 :     /// Copy constructor.
      93                 :     flat_dynamic_buffer(
      94                 :         flat_dynamic_buffer const&) = default;
      95                 : 
      96                 :     /// Copy assignment.
      97                 :     flat_dynamic_buffer& operator=(
      98                 :         flat_dynamic_buffer const&) = default;
      99                 : 
     100                 :     /// Return the number of readable bytes.
     101                 :     std::size_t
     102             856 :     size() const noexcept
     103                 :     {
     104             856 :         return in_size_;
     105                 :     }
     106                 : 
     107                 :     /// Return the maximum number of bytes the buffer can hold.
     108                 :     std::size_t
     109              10 :     max_size() const noexcept
     110                 :     {
     111              10 :         return cap_;
     112                 :     }
     113                 : 
     114                 :     /// Return the number of writable bytes without reallocation.
     115                 :     std::size_t
     116             238 :     capacity() const noexcept
     117                 :     {
     118             238 :         return cap_ - (in_pos_ + in_size_);
     119                 :     }
     120                 : 
     121                 :     /// Return a buffer sequence representing the readable bytes.
     122                 :     const_buffers_type
     123             161 :     data() const noexcept
     124                 :     {
     125             322 :         return const_buffers_type(
     126             161 :             data_ + in_pos_, in_size_);
     127                 :     }
     128                 : 
     129                 :     /** Return a buffer sequence for writing.
     130                 : 
     131                 :         Invalidates buffer sequences previously obtained
     132                 :         from @ref prepare.
     133                 : 
     134                 :         @param n The desired number of writable bytes.
     135                 : 
     136                 :         @return A mutable buffer sequence of size @p n.
     137                 : 
     138                 :         @throws std::invalid_argument if `n > capacity()`.
     139                 :     */
     140                 :     mutable_buffers_type
     141             197 :     prepare(std::size_t n)
     142                 :     {
     143             197 :         if( n > capacity() )
     144               3 :             detail::throw_invalid_argument();
     145                 : 
     146             194 :         out_size_ = n;
     147             388 :         return mutable_buffers_type(
     148             194 :             data_ + in_pos_ + in_size_, n);
     149                 :     }
     150                 : 
     151                 :     /** Move bytes from the output to the input sequence.
     152                 : 
     153                 :         Invalidates buffer sequences previously obtained
     154                 :         from @ref prepare. Buffer sequences from @ref data
     155                 :         remain valid.
     156                 : 
     157                 :         @param n The number of bytes to commit. If greater
     158                 :             than the prepared size, all prepared bytes
     159                 :             are committed.
     160                 :     */
     161                 :     void
     162             160 :     commit(
     163                 :         std::size_t n) noexcept
     164                 :     {
     165             160 :         if(n < out_size_)
     166              15 :             in_size_ += n;
     167                 :         else
     168             145 :             in_size_ += out_size_;
     169             160 :         out_size_ = 0;
     170             160 :     }
     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                 :     void
     182             180 :     consume(
     183                 :         std::size_t n) noexcept
     184                 :     {
     185             180 :         if(n < in_size_)
     186                 :         {
     187              15 :             in_pos_ += n;
     188              15 :             in_size_ -= n;
     189                 :         }
     190                 :         else
     191                 :         {
     192             165 :             in_pos_ = 0;
     193             165 :             in_size_ = 0;
     194                 :         }
     195             180 :     }
     196                 : };
     197                 : 
     198                 : } // capy
     199                 : } // boost
     200                 : 
     201                 : #endif
        

Generated by: LCOV version 2.3