LCOV - code coverage report
Current view: top level - include/boost/http/detail - flat_buffer.hpp (source / functions) Coverage Total Hit Missed
Test: coverage_remapped.info Lines: 91.7 % 24 22 2
Test Date: 2026-07-22 18:52:55 Functions: 100.0 % 6 6

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

Generated by: LCOV version 2.3