LCOV - code coverage report
Current view: top level - src/util - string.cpp (source / functions) Coverage Total Hit
Test: total_coverage.info Lines: 100.0 % 31 31
Test Date: 2026-08-05 07:16:25 Functions: 100.0 % 6 6
Branches: 88.5 % 26 23

             Branch data     Line data    Source code
       1                 :             : // Copyright (c) 2019-present The Bitcoin Core developers
       2                 :             : // Distributed under the MIT software license, see the accompanying
       3                 :             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       4                 :             : 
       5                 :             : #include <util/string.h>
       6                 :             : 
       7                 :             : #include <iterator>
       8                 :             : #include <memory>
       9                 :             : #include <regex>
      10                 :             : #include <stdexcept>
      11                 :             : #include <string>
      12                 :             : 
      13                 :             : namespace util {
      14                 :         255 : void ReplaceAll(std::string& in_out, const std::string& search, const std::string& substitute)
      15                 :             : {
      16         [ +  + ]:         255 :     if (search.empty()) return;
      17         [ +  - ]:         253 :     in_out = std::regex_replace(in_out, std::regex(search), substitute);
      18                 :             : }
      19                 :             : 
      20                 :      371741 : LineReader::LineReader(std::string_view str, size_t max_line_length)
      21                 :      371741 :     : m_str{str}, m_max_line_length{max_line_length}, m_it{str.begin()} {}
      22                 :             : 
      23                 :     2967644 : std::optional<std::string_view> LineReader::ReadLine()
      24                 :             : {
      25         [ +  + ]:     2967644 :     if (m_it == m_str.end()) {
      26                 :         527 :         return std::nullopt;
      27                 :             :     }
      28                 :             : 
      29                 :             :     const auto line_start = m_it;
      30         [ +  + ]:   104282078 :     while (m_it != m_str.end()) {
      31                 :             :         // Read a character from the incoming buffer and increment the iterator
      32                 :   104282027 :         const bool new_line{*m_it == '\n'};
      33                 :   104282027 :         ++m_it;
      34                 :             :         // If the character we just consumed was \n, the line is terminated.
      35                 :             :         // The \n itself does not count against max_line_length.
      36         [ +  + ]:   104282027 :         if (new_line) {
      37         [ +  + ]:     2967060 :             std::string_view line{line_start, m_it - 1};
      38   [ +  +  +  + ]:     2967060 :             if (!line.empty() && line.back() == '\r')
      39                 :     2966164 :                 line.remove_suffix(1);
      40                 :     2967060 :             return line;
      41                 :             :         }
      42                 :             :         // If the character we just consumed gives us a line length greater
      43                 :             :         // than max_line_length, and we are not at the end of the line (or buffer) yet,
      44                 :             :         // that means the line we are currently reading is too long, and we throw.
      45         [ +  + ]:   101314967 :         if (static_cast<size_t>(std::distance(line_start, m_it)) > m_max_line_length) {
      46                 :             :             // Reset iterator
      47                 :           6 :             m_it = line_start;
      48         [ +  - ]:           6 :             throw std::runtime_error("max_line_length exceeded by LineReader");
      49                 :             :         }
      50                 :             :     }
      51                 :             :     // End of buffer reached without finding a \n or exceeding max_line_length.
      52                 :             :     // Reset the iterator so the rest of the buffer can be read granularly
      53                 :             :     // with ReadLength() and return null to indicate a line was not found.
      54                 :          51 :     m_it = line_start;
      55                 :          51 :     return std::nullopt;
      56                 :             : }
      57                 :             : 
      58                 :             : // Ignores max_line_length but won't overflow
      59                 :      221021 : std::string_view LineReader::ReadLength(size_t len)
      60                 :             : {
      61         [ +  + ]:      221021 :     if (len == 0) return {};
      62   [ +  +  +  - ]:      221007 :     if (Remaining() < len) throw std::runtime_error("Not enough data in buffer");
      63                 :      221006 :     std::string_view out(std::to_address(m_it), len);
      64                 :      221006 :     m_it += len;
      65                 :      221006 :     return out;
      66                 :             : }
      67                 :             : 
      68                 :      593094 : size_t LineReader::Remaining() const
      69                 :             : {
      70                 :      593094 :     return std::distance(m_it, m_str.end());
      71                 :             : }
      72                 :             : 
      73                 :     2807220 : size_t LineReader::Consumed() const
      74                 :             : {
      75                 :     2807220 :     return std::distance(m_str.begin(), m_it);
      76                 :             : }
      77                 :             : } // namespace util
        

Generated by: LCOV version 2.0-1