Bitcoin Core 31.99.0
P2P Digital Currency
string.cpp
Go to the documentation of this file.
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
13namespace util {
14void ReplaceAll(std::string& in_out, const std::string& search, const std::string& substitute)
15{
16 if (search.empty()) return;
17 in_out = std::regex_replace(in_out, std::regex(search), substitute);
18}
19
20LineReader::LineReader(std::span<const std::byte> buffer, size_t max_line_length)
21 : start(buffer.begin()), end(buffer.end()), max_line_length(max_line_length), it(buffer.begin()) {}
22
23std::optional<std::string> LineReader::ReadLine()
24{
25 if (it == end) {
26 return std::nullopt;
27 }
28
29 auto line_start = it;
30 size_t count = 0;
31 while (it != end) {
32 // Read a character from the incoming buffer and increment the iterator
33 auto c = static_cast<char>(*it);
34 ++it;
35 ++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 if (c == '\n') {
39 const std::string_view untrimmed_line(reinterpret_cast<const char*>(std::to_address(line_start)), count);
40 const std::string_view line = TrimStringView(untrimmed_line); // delete leading and trailing whitespace including \r and \n
41 return std::string(line);
42 }
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 if (count > max_line_length) {
47 // Reset iterator
48 it = line_start;
49 throw std::runtime_error("max_line_length exceeded by LineReader");
50 }
51 }
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 it = line_start;
56 return std::nullopt;
57}
58
59// Ignores max_line_length but won't overflow
60std::string LineReader::ReadLength(size_t len)
61{
62 if (len == 0) return "";
63 if (Remaining() < len) throw std::runtime_error("Not enough data in buffer");
64 std::string out(reinterpret_cast<const char*>(std::to_address(it)), len);
65 it += len;
66 return out;
67}
68
70{
71 return std::distance(it, end);
72}
73
75{
76 return std::distance(start, it);
77}
78} // namespace util
std::string_view TrimStringView(std::string_view str, std::string_view pattern=" \f\n\r\t\v")
Definition: string.h:160
void ReplaceAll(std::string &in_out, const std::string &search, const std::string &substitute)
Definition: string.cpp:14
size_t Consumed() const
Returns number of bytes already read from buffer.
Definition: string.cpp:74
size_t Remaining() const
Returns remaining size of bytes in buffer.
Definition: string.cpp:69
std::span< conststd::byte >::iterator it
Definition: string.h:270
LineReader(std::span< const std::byte > buffer, size_t max_line_length)
Definition: string.cpp:20
const std::span< conststd::byte >::iterator end
Definition: string.h:268
std::string ReadLength(size_t len)
Returns string from current iterator position of specified length if possible and advances iterator o...
Definition: string.cpp:60
const size_t max_line_length
Definition: string.h:269
const std::span< conststd::byte >::iterator start
Definition: string.h:267
std::optional< std::string > ReadLine()
Returns a string from current iterator position up to (but not including) next and advances iterator...
Definition: string.cpp:23
static int count