LCOV - code coverage report
Current view: top level - spb/io - buffer-io.hpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 28 28
Test Date: 2026-10-01 11:28:31 Functions: 100.0 % 7 7

            Line data    Source code
       1              : /***************************************************************************\
       2              : * Name        : buffered reader                                             *
       3              : * Description : buffer between io::reader and detail::istream              *
       4              : * Author      : antonin.kriz@gmail.com                                      *
       5              : * ------------------------------------------------------------------------- *
       6              : * This is free software; you can redistribute it and/or modify it under the *
       7              : * terms of the MIT license. A copy of the license can be found in the file  *
       8              : * "LICENSE" at the root of this distribution.                               *
       9              : \***************************************************************************/
      10              : 
      11              : #pragma once
      12              : #include "io.hpp"
      13              : #include <array>
      14              : #include <cassert>
      15              : #include <cstdlib>
      16              : #include <cstring>
      17              : #include <string_view>
      18              : #include <sys/types.h>
      19              : 
      20              : namespace spb::io
      21              : {
      22              : class buffered_reader
      23              : {
      24              :   public:
      25              :     static constexpr size_t BUFFER_SIZE = 256;
      26              : 
      27              :   private:
      28              :     using buffer_index_type = uint16_t;
      29              :     std::array<char, BUFFER_SIZE> buffer;
      30              :     io::reader on_read;
      31              :     buffer_index_type begin_index = 0;
      32              :     buffer_index_type end_index = 0;
      33              :     bool eof_reached = false;
      34              : 
      35        19443 :     auto bytes_in_buffer() const noexcept -> size_t
      36              :     {
      37        19443 :         return end_index - begin_index;
      38              :     }
      39              : 
      40          772 :     auto space_left_in_buffer() const noexcept -> size_t
      41              :     {
      42         1544 :         return buffer.size() - end_index;
      43              :     }
      44              : 
      45         1230 :     void shift_data_to_start() noexcept
      46              :     {
      47         1230 :         if (begin_index == 0)
      48          420 :             return;
      49              : 
      50         1620 :         memmove(buffer.data(), buffer.data() + begin_index, bytes_in_buffer());
      51          810 :         end_index -= begin_index;
      52          810 :         begin_index = 0;
      53              :     }
      54              : 
      55         1230 :     void read_buffer()
      56              :     {
      57         1230 :         shift_data_to_start();
      58              : 
      59         4004 :         while (bytes_in_buffer() < buffer.size() && !eof_reached)
      60              :         {
      61              :             auto bytes_in =
      62          772 :                 static_cast<buffer_index_type>(on_read(&buffer[end_index], space_left_in_buffer()));
      63          772 :             eof_reached |= bytes_in == 0;
      64          772 :             end_index += bytes_in;
      65              :         }
      66         1230 :     }
      67              : 
      68              :   public:
      69          386 :     explicit buffered_reader(io::reader reader) : on_read(reader)
      70              :     {
      71          386 :     }
      72              : 
      73         6158 :     [[nodiscard]] auto view(size_t minimal_size) -> std::string_view
      74              :     {
      75         6158 :         minimal_size = std::max<size_t>(minimal_size, 1U);
      76         6158 :         if (bytes_in_buffer() < minimal_size)
      77         1230 :             read_buffer();
      78              : 
      79         6158 :         return std::string_view(&buffer[begin_index], bytes_in_buffer());
      80              :     }
      81              : 
      82         4315 :     void skip(size_t size) noexcept
      83              :     {
      84         4315 :         assert(size <= bytes_in_buffer());
      85         4315 :         begin_index += static_cast<buffer_index_type>(size);
      86         4315 :     }
      87              : };
      88              : 
      89              : } // namespace spb::io
        

Generated by: LCOV version 2.0-1