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-07-19 10:31: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        19074 :     auto bytes_in_buffer() const noexcept -> size_t
      36              :     {
      37        19074 :         return end_index - begin_index;
      38              :     }
      39              : 
      40          756 :     auto space_left_in_buffer() const noexcept -> size_t
      41              :     {
      42         1512 :         return buffer.size() - end_index;
      43              :     }
      44              : 
      45         1211 :     void shift_data_to_start() noexcept
      46              :     {
      47         1211 :         if (begin_index == 0)
      48          412 :             return;
      49              : 
      50         1598 :         memmove(buffer.data(), buffer.data() + begin_index, bytes_in_buffer());
      51          799 :         end_index -= begin_index;
      52          799 :         begin_index = 0;
      53              :     }
      54              : 
      55         1211 :     void read_buffer()
      56              :     {
      57         1211 :         shift_data_to_start();
      58              : 
      59         3934 :         while (bytes_in_buffer() < buffer.size() && !eof_reached)
      60              :         {
      61              :             auto bytes_in =
      62          756 :                 static_cast<buffer_index_type>(on_read(&buffer[end_index], space_left_in_buffer()));
      63          756 :             eof_reached |= bytes_in == 0;
      64          756 :             end_index += bytes_in;
      65              :         }
      66         1211 :     }
      67              : 
      68              :   public:
      69          378 :     explicit buffered_reader(io::reader reader) : on_read(reader)
      70              :     {
      71          378 :     }
      72              : 
      73         6041 :     [[nodiscard]] auto view(size_t minimal_size) -> std::string_view
      74              :     {
      75         6041 :         minimal_size = std::max<size_t>(minimal_size, 1U);
      76         6041 :         if (bytes_in_buffer() < minimal_size)
      77         1211 :             read_buffer();
      78              : 
      79         6041 :         return std::string_view(&buffer[begin_index], bytes_in_buffer());
      80              :     }
      81              : 
      82         4226 :     void skip(size_t size) noexcept
      83              :     {
      84         4226 :         assert(size <= bytes_in_buffer());
      85         4226 :         begin_index += static_cast<buffer_index_type>(size);
      86         4226 :     }
      87              : };
      88              : 
      89              : } // namespace spb::io
        

Generated by: LCOV version 2.0-1