Coverage Report

Created: 2026-06-01 18:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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::span<const std::byte> buffer, size_t max_line_length)
21
6.70k
    : start(buffer.begin()), end(buffer.end()), max_line_length(max_line_length), it(buffer.begin()) {}
22
23
std::optional<std::string_view> LineReader::ReadLine()
24
30.0k
{
25
30.0k
    if (it == end) {
  Branch (25:9): [True: 172, False: 29.8k]
26
172
        return std::nullopt;
27
172
    }
28
29
29.8k
    auto line_start = it;
30
29.8k
    size_t count = 0;
31
2.81M
    while (it != end) {
  Branch (31:12): [True: 2.80M, False: 4.80k]
32
        // Read a character from the incoming buffer and increment the iterator
33
2.80M
        auto c = static_cast<char>(*it);
34
2.80M
        ++it;
35
2.80M
        ++count;
36
        // If the character we just consumed was \n, the line is terminated.
37
        // The \n itself does not count against max_line_length.
38
2.80M
        if (c == '\n') {
  Branch (38:13): [True: 25.0k, False: 2.78M]
39
25.0k
            const std::string_view untrimmed_line(reinterpret_cast<const char*>(std::to_address(line_start)), count);
40
25.0k
            std::string_view line = RemoveSuffixView(untrimmed_line, "\n");
41
25.0k
            return RemoveSuffixView(line, "\r");
42
25.0k
        }
43
        // If the character we just consumed gives us a line length greater
44
        // than max_line_length, and we are not at the end of the line (or buffer) yet,
45
        // that means the line we are currently reading is too long, and we throw.
46
2.78M
        if (count > max_line_length) {
  Branch (46:13): [True: 5, False: 2.78M]
47
            // Reset iterator
48
5
            it = line_start;
49
5
            throw std::runtime_error("max_line_length exceeded by LineReader");
50
5
        }
51
2.78M
    }
52
    // End of buffer reached without finding a \n or exceeding max_line_length.
53
    // Reset the iterator so the rest of the buffer can be read granularly
54
    // with ReadLength() and return null to indicate a line was not found.
55
4.80k
    it = line_start;
56
4.80k
    return std::nullopt;
57
29.8k
}
58
59
// Ignores max_line_length but won't overflow
60
std::string_view LineReader::ReadLength(size_t len)
61
1.76k
{
62
1.76k
    if (len == 0) return {};
  Branch (62:9): [True: 0, False: 1.76k]
63
1.76k
    if (Remaining() < len) throw std::runtime_error("Not enough data in buffer");
  Branch (63:9): [True: 0, False: 1.76k]
64
1.76k
    std::string_view out(reinterpret_cast<const char*>(std::to_address(it)), len);
65
1.76k
    it += len;
66
1.76k
    return out;
67
1.76k
}
68
69
size_t LineReader::Remaining() const
70
5.59k
{
71
5.59k
    return std::distance(it, end);
72
5.59k
}
73
74
size_t LineReader::Consumed() const
75
20.3k
{
76
20.3k
    return std::distance(start, it);
77
20.3k
}
78
} // namespace util