LCOV - code coverage report
Current view: top level - http_proto/detail/impl - workspace.ipp (source / functions) Hit Total Coverage
Test: coverage_filtered.info Lines: 61 83 73.5 %
Date: 2023-12-11 14:11:20 Functions: 7 8 87.5 %

          Line data    Source code
       1             : //
       2             : // Copyright (c) 2019 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_proto
       8             : //
       9             : 
      10             : #ifndef BOOST_HTTP_PROTO_DETAIL_IMPL_WORKSPACE_IPP
      11             : #define BOOST_HTTP_PROTO_DETAIL_IMPL_WORKSPACE_IPP
      12             : 
      13             : #include <boost/http_proto/detail/workspace.hpp>
      14             : #include <boost/http_proto/detail/except.hpp>
      15             : #include <boost/assert.hpp>
      16             : 
      17             : namespace boost {
      18             : namespace http_proto {
      19             : namespace detail {
      20             : 
      21             : workspace::
      22             : any::
      23             : ~any() = default;
      24             : 
      25         803 : workspace::
      26         803 : ~workspace()
      27             : {
      28         803 :     if(begin_)
      29             :     {
      30         803 :         clear();
      31         803 :         delete[] begin_;
      32             :     }
      33         803 : }
      34             : 
      35          12 : workspace::
      36             : workspace(
      37          12 :     std::size_t n)
      38          12 :     : begin_(new unsigned char[n])
      39          12 :     , front_(begin_)
      40          12 :     , head_(begin_ + n)
      41          12 :     , back_(head_)
      42          12 :     , end_(head_)
      43             : {
      44          12 : }
      45             : 
      46           0 : workspace::
      47             : workspace(
      48           0 :     workspace&& other) noexcept
      49           0 :     : begin_(other.begin_)
      50           0 :     , front_(other.front_)
      51           0 :     , head_(other.end_)
      52           0 :     , back_(other.back_)
      53           0 :     , end_(other.end_)
      54             : {
      55           0 :     other.begin_ = nullptr;
      56           0 :     other.front_ = nullptr;
      57           0 :     other.head_ = nullptr;
      58           0 :     other.back_ = nullptr;
      59           0 :     other.end_ = nullptr;
      60           0 : }
      61             : 
      62             : void
      63         791 : workspace::
      64             : allocate(
      65             :     std::size_t n)
      66             : {
      67             :     // Cannot be empty
      68         791 :     if(n == 0)
      69           0 :         detail::throw_invalid_argument();
      70             : 
      71             :     // Already allocated
      72         791 :     if(begin_ != nullptr)
      73           0 :         detail::throw_logic_error();
      74             : 
      75         791 :     begin_ = new unsigned char[n];
      76         791 :     front_ = begin_;
      77         791 :     head_ = begin_ + n;
      78         791 :     back_ = head_;
      79         791 :     end_ = head_;
      80         791 : }
      81             : 
      82             : void
      83        3550 : workspace::
      84             : clear() noexcept
      85             : {
      86        3550 :     if(! begin_)
      87           0 :         return;
      88             : 
      89        3550 :     auto const end =
      90             :         reinterpret_cast<
      91             :             any const*>(back_);
      92        3550 :     auto p =
      93             :         reinterpret_cast<
      94             :             any const*>(head_);
      95        3886 :     while(p != end)
      96             :     {
      97         336 :         auto next = p->next;
      98         336 :         p->~any();
      99         336 :         p = next;
     100             :     }
     101        3550 :     front_ = begin_;
     102        3550 :     head_ = end_;
     103        3550 :     back_ = end_;
     104             : }
     105             : 
     106             : unsigned char*
     107        1213 : workspace::
     108             : reserve_front(
     109             :     std::size_t n)
     110             : {
     111             :     // 
     112             :     // Requested size exceeds available space.
     113             :     // Note you can never reserve the last byte.
     114        1213 :     if(n >= size())
     115           0 :         detail::throw_length_error();
     116             : 
     117        1213 :     auto const p = front_;
     118        1213 :     front_ += n ;
     119        1213 :     return p;
     120             : }
     121             : 
     122             : unsigned char*
     123        1207 : workspace::
     124             : reserve_back(
     125             :     std::size_t n)
     126             : {
     127             :     // can't reserve after acquire
     128        1207 :     if(head_ != end_)
     129           0 :         detail::throw_logic_error();
     130             : 
     131             :     // can't reserve twice
     132        1207 :     if(back_ != end_)
     133           0 :         detail::throw_logic_error();
     134             : 
     135             :     // over capacity
     136        1207 :     std::size_t const lim =
     137        1207 :         head_ - front_;
     138        1207 :     if(n >= lim)
     139           0 :         detail::throw_length_error();
     140             : 
     141        1207 :     head_ -= n;
     142        1207 :     back_ = head_;
     143        1207 :     return back_;
     144             : }
     145             : 
     146             : // https://fitzgeraldnick.com/2019/11/01/always-bump-downwards.html
     147             : unsigned char*
     148         336 : workspace::
     149             : bump_down(
     150             :     std::size_t size,
     151             :     std::size_t align)
     152             : {
     153         336 :     BOOST_ASSERT(align > 0);
     154         336 :     BOOST_ASSERT(
     155             :         (align & (align - 1)) == 0);
     156         336 :     BOOST_ASSERT(front_);
     157             : 
     158         336 :     auto ip0 = reinterpret_cast<
     159         336 :         std::uintptr_t>(front_);
     160         336 :     auto ip = reinterpret_cast<
     161         336 :         std::uintptr_t>(head_);
     162             : 
     163             :     // If you get an exception here, it
     164             :     // means that a buffer was too small
     165             :     // for your workload. Increase the
     166             :     // buffer size.
     167         336 :     if(size > ip - ip0)
     168           0 :         detail::throw_bad_alloc();
     169             : 
     170         336 :     ip -= size;
     171         336 :     ip &= ~(align - 1);
     172             : 
     173             :     // If you get an exception here, it
     174             :     // means that a buffer was too small
     175             :     // for your workload. Increase the
     176             :     // buffer size.
     177         336 :     if(ip < ip0)
     178           0 :         detail::throw_bad_alloc();
     179             : 
     180             :     return reinterpret_cast<
     181         336 :         unsigned char*>(ip);
     182             : }
     183             : 
     184             : } // detail
     185             : } // http_proto
     186             : } // boost
     187             : 
     188             : #endif

Generated by: LCOV version 1.15