LCOV - code coverage report
Current view: top level - src/adt - stream_buffer.cpp (source / functions) Coverage Total Hit
Test: HPActor Coverage Lines: 62.1 % 116 72
Test Date: 2026-05-20 02:24:49 Functions: 73.9 % 23 17
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : // Copyright 2026 HPActor Contributors
       2                 :             : //
       3                 :             : // Licensed under the Apache License, Version 2.0 (the "License");
       4                 :             : // you may not use this file except in compliance with the License.
       5                 :             : // You may obtain a copy of the License at
       6                 :             : //
       7                 :             : //     http://www.apache.org/licenses/LICENSE-2.0
       8                 :             : //
       9                 :             : // Unless required by applicable law or agreed to in writing, software
      10                 :             : // distributed under the License is distributed on an "AS IS" BASIS,
      11                 :             : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12                 :             : // See the License for the specific language governing permissions and
      13                 :             : // limitations under the License.
      14                 :             : 
      15                 :             : #include <hpactor/adt/stream_buffer.hpp>
      16                 :             : 
      17                 :             : #include <algorithm>
      18                 :             : #include <cstring>
      19                 :             : 
      20                 :             : namespace hpactor {
      21                 :             : namespace adt {
      22                 :             : 
      23                 :             : // ---- Constructors ----
      24                 :             : 
      25                 :          31 : StreamBuffer::StreamBuffer(size_t count)
      26                 :          62 :     : buf_(count, uint8_t{0}), read_pos_(0) {}
      27                 :             : 
      28                 :     1121669 : StreamBuffer::StreamBuffer(std::initializer_list<uint8_t> ilist)
      29                 :     2243338 :     : buf_(ilist), read_pos_(0) {}
      30                 :             : 
      31                 :           0 : StreamBuffer::StreamBuffer(size_t count, uint8_t value)
      32                 :           0 :     : buf_(count, value), read_pos_(0) {}
      33                 :             : 
      34                 :           0 : StreamBuffer StreamBuffer::with_capacity(size_t cap) {
      35                 :           0 :     StreamBuffer sb;
      36                 :           0 :     sb.buf_.reserve(cap);
      37                 :           0 :     return sb;
      38                 :             : }
      39                 :             : 
      40                 :             : // ---- Copy ----
      41                 :             : 
      42                 :         254 : StreamBuffer::StreamBuffer(const StreamBuffer& other)
      43                 :         254 :     : buf_(other.buf_), read_pos_(other.read_pos_) {}
      44                 :             : 
      45                 :          42 : StreamBuffer& StreamBuffer::operator=(const StreamBuffer& other) {
      46                 :          42 :     if (this != &other) {
      47                 :          42 :         buf_ = other.buf_;
      48                 :          42 :         read_pos_ = other.read_pos_;
      49                 :             :     }
      50                 :          42 :     return *this;
      51                 :             : }
      52                 :             : 
      53                 :             : // ---- Capacity ----
      54                 :             : 
      55                 :          85 : void StreamBuffer::reserve(size_t n) {
      56                 :          85 :     if (n > buf_.capacity()) {
      57                 :          85 :         buf_.reserve(n);
      58                 :             :     }
      59                 :          85 : }
      60                 :             : 
      61                 :           3 : void StreamBuffer::resize(size_t n) {
      62                 :           3 :     compact();
      63                 :           3 :     buf_.resize(n);
      64                 :           3 : }
      65                 :             : 
      66                 :           0 : void StreamBuffer::resize(size_t n, uint8_t value) {
      67                 :           0 :     compact();
      68                 :           0 :     buf_.resize(n, value);
      69                 :           0 : }
      70                 :             : 
      71                 :             : // ---- Reserve + Write (direct I/O) ----
      72                 :             : 
      73                 :          14 : uint8_t* StreamBuffer::reserve_tail(size_t n) {
      74                 :          14 :     ensure_capacity(n);
      75                 :          14 :     size_t old_size = buf_.size();
      76                 :          14 :     buf_.resize(old_size + n);
      77                 :          14 :     reserve_tail_amount_ = n;
      78                 :          14 :     return buf_.data() + old_size;
      79                 :             : }
      80                 :             : 
      81                 :           9 : void StreamBuffer::commit_tail(size_t n) {
      82                 :           9 :     if (reserve_tail_amount_ > 0) {
      83                 :           9 :         if (n < reserve_tail_amount_) {
      84                 :           9 :             buf_.resize(buf_.size() - (reserve_tail_amount_ - n));
      85                 :             :         }
      86                 :           9 :         reserve_tail_amount_ = 0;
      87                 :             :     } else {
      88                 :           0 :         buf_.resize(buf_.size() + n);
      89                 :             :     }
      90                 :           9 : }
      91                 :             : 
      92                 :             : // ---- Append (copy-in) ----
      93                 :             : 
      94                 :         153 : void StreamBuffer::append(const uint8_t* data, size_t len) {
      95                 :         153 :     ensure_capacity(len);
      96                 :         153 :     buf_.insert(buf_.end(), data, data + len);
      97                 :         153 : }
      98                 :             : 
      99                 :             : // ---- Modifiers ----
     100                 :             : 
     101                 :         228 : void StreamBuffer::push_back(uint8_t value) {
     102                 :         228 :     ensure_capacity(1);
     103                 :         228 :     buf_.push_back(value);
     104                 :         228 : }
     105                 :             : 
     106                 :           0 : void StreamBuffer::assign(size_t count, uint8_t value) {
     107                 :           0 :     clear();
     108                 :           0 :     buf_.assign(count, value);
     109                 :           0 : }
     110                 :             : 
     111                 :           0 : void StreamBuffer::assign(std::initializer_list<uint8_t> ilist) {
     112                 :           0 :     clear();
     113                 :           0 :     buf_.assign(ilist);
     114                 :           0 : }
     115                 :             : 
     116                 :           1 : StreamBuffer::iterator StreamBuffer::insert(const_iterator pos,
     117                 :             :                                             std::initializer_list<uint8_t> ilist) {
     118                 :           1 :     size_t offset = static_cast<size_t>(pos - (buf_.data() + read_pos_));
     119                 :           1 :     compact();
     120                 :           1 :     auto it = buf_.insert(buf_.begin() + static_cast<std::ptrdiff_t>(offset), ilist);
     121                 :           1 :     return buf_.data() + static_cast<size_t>(it - buf_.begin());
     122                 :             : }
     123                 :             : 
     124                 :           0 : StreamBuffer::iterator StreamBuffer::erase(const_iterator first, const_iterator last) {
     125                 :           0 :     if (first >= last) return begin();
     126                 :             : 
     127                 :           0 :     size_t old_read_pos = read_pos_;
     128                 :           0 :     const uint8_t* logical_begin = buf_.data() + old_read_pos;
     129                 :           0 :     size_t offset_first = static_cast<size_t>(first - logical_begin);
     130                 :           0 :     size_t offset_last = static_cast<size_t>(last - logical_begin);
     131                 :             : 
     132                 :           0 :     if (offset_first == 0) {
     133                 :           0 :         consume(offset_last - offset_first);
     134                 :           0 :         return begin();
     135                 :             :     }
     136                 :             : 
     137                 :           0 :     compact();
     138                 :           0 :     auto it = buf_.erase(buf_.begin() + static_cast<std::ptrdiff_t>(offset_first),
     139                 :           0 :                          buf_.begin() + static_cast<std::ptrdiff_t>(offset_last));
     140                 :           0 :     return buf_.data() + static_cast<size_t>(it - buf_.begin());
     141                 :             : }
     142                 :             : 
     143                 :          23 : void StreamBuffer::clear() noexcept {
     144                 :          23 :     buf_.clear();
     145                 :          23 :     read_pos_ = 0;
     146                 :          23 : }
     147                 :             : 
     148                 :             : // ---- Consume ----
     149                 :             : 
     150                 :           8 : void StreamBuffer::consume(size_t n) {
     151                 :           8 :     read_pos_ += n;
     152                 :           8 : }
     153                 :             : 
     154                 :          45 : void StreamBuffer::compact() {
     155                 :          45 :     if (read_pos_ == 0)
     156                 :          45 :         return;
     157                 :           0 :     size_t readable = buf_.size() - read_pos_;
     158                 :           0 :     if (readable == 0) {
     159                 :           0 :         buf_.clear();
     160                 :           0 :         read_pos_ = 0;
     161                 :           0 :         return;
     162                 :             :     }
     163                 :           0 :     std::memmove(buf_.data(), buf_.data() + read_pos_, readable);
     164                 :           0 :     buf_.resize(readable);
     165                 :           0 :     read_pos_ = 0;
     166                 :             : }
     167                 :             : 
     168                 :             : // ---- Comparison ----
     169                 :             : 
     170                 :           1 : bool StreamBuffer::operator==(const StreamBuffer& other) const {
     171                 :           1 :     if (size() != other.size()) return false;
     172                 :           1 :     if (size() == 0) return true;
     173                 :           1 :     return std::memcmp(data(), other.data(), size()) == 0;
     174                 :             : }
     175                 :             : 
     176                 :             : // ---- Private ----
     177                 :             : 
     178                 :         133 : void StreamBuffer::maybe_compact() {
     179                 :         133 :     if (read_pos_ == 0)
     180                 :         133 :         return;
     181                 :           0 :     size_t readable = buf_.size() - read_pos_;
     182                 :           0 :     if (read_pos_ > readable || read_pos_ > kCompactThreshold) {
     183                 :           0 :         compact();
     184                 :             :     }
     185                 :             : }
     186                 :             : 
     187                 :         395 : void StreamBuffer::ensure_capacity(size_t additional_bytes) {
     188                 :         395 :     if (read_pos_ > 0) {
     189                 :           1 :         size_t usable = buf_.capacity() - buf_.size();
     190                 :           1 :         if (usable < additional_bytes) {
     191                 :           0 :             compact();
     192                 :             :         }
     193                 :             :     }
     194                 :         395 :     size_t usable = buf_.capacity() - buf_.size();
     195                 :         395 :     if (usable < additional_bytes) {
     196                 :          75 :         size_t new_cap = std::max(buf_.capacity() * 2,
     197                 :          75 :                                   buf_.size() + additional_bytes);
     198                 :          75 :         new_cap = std::max(new_cap, kDefaultInitialCapacity);
     199                 :          75 :         buf_.reserve(new_cap);
     200                 :             :     }
     201                 :         395 : }
     202                 :             : 
     203                 :             : } // namespace adt
     204                 :             : } // namespace hpactor
        

Generated by: LCOV version 2.0-1