Bitcoin Core  31.0.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 <regex>
8 #include <string>
9 
10 namespace util {
11 void ReplaceAll(std::string& in_out, const std::string& search, const std::string& substitute)
12 {
13  if (search.empty()) return;
14  in_out = std::regex_replace(in_out, std::regex(search), substitute);
15 }
16 
17 LineReader::LineReader(std::span<const std::byte> buffer, size_t max_line_length)
18  : start(buffer.begin()), end(buffer.end()), max_line_length(max_line_length), it(buffer.begin()) {}
19 
20 std::optional<std::string> LineReader::ReadLine()
21 {
22  if (it == end) {
23  return std::nullopt;
24  }
25 
26  auto line_start = it;
27  size_t count = 0;
28  while (it != end) {
29  // Read a character from the incoming buffer and increment the iterator
30  auto c = static_cast<char>(*it);
31  ++it;
32  ++count;
33  // If the character we just consumed was \n, the line is terminated.
34  // The \n itself does not count against max_line_length.
35  if (c == '\n') {
36  const std::string_view untrimmed_line(reinterpret_cast<const char*>(std::to_address(line_start)), count);
37  const std::string_view line = TrimStringView(untrimmed_line); // delete leading and trailing whitespace including \r and \n
38  return std::string(line);
39  }
40  // If the character we just consumed gives us a line length greater
41  // than max_line_length, and we are not at the end of the line (or buffer) yet,
42  // that means the line we are currently reading is too long, and we throw.
43  if (count > max_line_length) {
44  // Reset iterator
45  it = line_start;
46  throw std::runtime_error("max_line_length exceeded by LineReader");
47  }
48  }
49  // End of buffer reached without finding a \n or exceeding max_line_length.
50  // Reset the iterator so the rest of the buffer can be read granularly
51  // with ReadLength() and return null to indicate a line was not found.
52  it = line_start;
53  return std::nullopt;
54 }
55 
56 // Ignores max_line_length but won't overflow
57 std::string LineReader::ReadLength(size_t len)
58 {
59  if (len == 0) return "";
60  if (Remaining() < len) throw std::runtime_error("Not enough data in buffer");
61  std::string out(reinterpret_cast<const char*>(std::to_address(it)), len);
62  it += len;
63  return out;
64 }
65 
66 size_t LineReader::Remaining() const
67 {
68  return std::distance(it, end);
69 }
70 } // namespace util
void ReplaceAll(std::string &in_out, const std::string &search, const std::string &substitute)
Definition: string.cpp:11
LineReader(std::span< const std::byte > buffer, size_t max_line_length)
Definition: string.cpp:17
const std::span< const std::byte >::iterator end
Definition: string.h:267
std::span< const std::byte >::iterator it
Definition: string.h:269
std::string_view TrimStringView(std::string_view str, std::string_view pattern=" \\\)
Definition: string.h:159
size_t Remaining() const
Returns remaining size of bytes in buffer.
Definition: string.cpp:66
std::optional< std::string > ReadLine()
Returns a string from current iterator position up to (but not including) next and advances iterator...
Definition: string.cpp:20
const size_t max_line_length
Definition: string.h:268
static int count
std::string ReadLength(size_t len)
Returns string from current iterator position of specified length if possible and advances iterator o...
Definition: string.cpp:57