Coverage Report

Created: 2026-08-14 17:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/root/bitcoin/src/util/string.cpp
Line
Count
Source
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
void ReplaceAll(std::string& in_out, const std::string& search, const std::string& substitute)
15
0
{
16
0
    if (search.empty()) return;
  Branch (16:9): [True: 0, False: 0]
17
0
    in_out = std::regex_replace(in_out, std::regex(search), substitute);
18
0
}
19
20
LineReader::LineReader(std::string_view str, size_t max_line_length)
21
0
    : m_str{str}, m_max_line_length{max_line_length}, m_it{str.begin()} {}
22
23
std::optional<std::string_view> LineReader::ReadLine()
24
0
{
25
0
    if (m_it == m_str.end()) {
  Branch (25:9): [True: 0, False: 0]
26
0
        return std::nullopt;
27
0
    }
28
29
0
    const auto line_start = m_it;
30
0
    while (m_it != m_str.end()) {
  Branch (30:12): [True: 0, False: 0]
31
        // Read a character from the incoming buffer and increment the iterator
32
0
        const bool new_line{*m_it == '\n'};
33
0
        ++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
0
        if (new_line) {
  Branch (36:13): [True: 0, False: 0]
37
0
            std::string_view line{line_start, m_it - 1};
38
0
            if (!line.empty() && line.back() == '\r')
  Branch (38:17): [True: 0, False: 0]
  Branch (38:34): [True: 0, False: 0]
39
0
                line.remove_suffix(1);
40
0
            return line;
41
0
        }
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
0
        if (static_cast<size_t>(std::distance(line_start, m_it)) > m_max_line_length) {
  Branch (45:13): [True: 0, False: 0]
46
            // Reset iterator
47
0
            m_it = line_start;
48
0
            throw std::runtime_error("max_line_length exceeded by LineReader");
49
0
        }
50
0
    }
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
0
    m_it = line_start;
55
0
    return std::nullopt;
56
0
}
57
58
// Ignores max_line_length but won't overflow
59
std::string_view LineReader::ReadLength(size_t len)
60
0
{
61
0
    if (len == 0) return {};
  Branch (61:9): [True: 0, False: 0]
62
0
    if (Remaining() < len) throw std::runtime_error("Not enough data in buffer");
  Branch (62:9): [True: 0, False: 0]
63
0
    std::string_view out(std::to_address(m_it), len);
64
0
    m_it += len;
65
0
    return out;
66
0
}
67
68
size_t LineReader::Remaining() const
69
0
{
70
0
    return std::distance(m_it, m_str.end());
71
0
}
72
73
size_t LineReader::Consumed() const
74
0
{
75
0
    return std::distance(m_str.begin(), m_it);
76
0
}
77
} // namespace util