Coverage Report

Created: 2026-06-01 18:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/bitcoin/src/util/strencodings.h
Line
Count
Source
1
// Copyright (c) 2009-2010 Satoshi Nakamoto
2
// Copyright (c) 2009-present The Bitcoin Core developers
3
// Distributed under the MIT software license, see the accompanying
4
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6
/**
7
 * Utilities for converting data from/to strings.
8
 */
9
#ifndef BITCOIN_UTIL_STRENCODINGS_H
10
#define BITCOIN_UTIL_STRENCODINGS_H
11
12
#include <span.h>
13
#include <util/string.h>
14
15
#include <array>
16
#include <bit>
17
#include <charconv>
18
#include <cstddef>
19
#include <cstdint>
20
#include <limits>
21
#include <optional>
22
#include <span>
23
#include <string>
24
#include <string_view>
25
#include <system_error>
26
#include <type_traits>
27
#include <vector>
28
29
/** Used by SanitizeString() */
30
enum SafeChars
31
{
32
    SAFE_CHARS_DEFAULT, //!< The full set of allowed chars
33
    SAFE_CHARS_UA_COMMENT, //!< BIP-0014 subset
34
    SAFE_CHARS_FILENAME, //!< Chars allowed in filenames
35
    SAFE_CHARS_URI, //!< Chars allowed in URIs (RFC 3986)
36
};
37
38
/**
39
 * Used by ParseByteUnits()
40
 * Lowercase base 1000
41
 * Uppercase base 1024
42
*/
43
enum class ByteUnit : uint64_t {
44
    NOOP = 1ULL,
45
    k = 1000ULL,
46
    K = 1024ULL,
47
    m = 1'000'000ULL,
48
    M = 1ULL << 20,
49
    g = 1'000'000'000ULL,
50
    G = 1ULL << 30,
51
    t = 1'000'000'000'000ULL,
52
    T = 1ULL << 40,
53
};
54
55
/**
56
* Remove unsafe chars. Safe chars chosen to allow simple messages/URLs/email
57
* addresses, but avoid anything even possibly remotely dangerous like & or >
58
* @param[in] str    The string to sanitize
59
* @param[in] rule   The set of safe chars to choose (default: least restrictive)
60
* @return           A new string without unsafe chars
61
*/
62
std::string SanitizeString(std::string_view str, int rule = SAFE_CHARS_DEFAULT);
63
/** Parse the hex string into bytes (uint8_t or std::byte). Ignores whitespace. Returns nullopt on invalid input. */
64
template <typename Byte = std::byte>
65
std::optional<std::vector<Byte>> TryParseHex(std::string_view str);
66
/** Like TryParseHex, but returns an empty vector on invalid input. */
67
template <typename Byte = uint8_t>
68
std::vector<Byte> ParseHex(std::string_view hex_str)
69
0
{
70
0
    return TryParseHex<Byte>(hex_str).value_or(std::vector<Byte>{});
71
0
}
72
/* Returns true if each character in str is a hex character, and has an even
73
 * number of hex digits.*/
74
bool IsHex(std::string_view str);
75
std::optional<std::vector<unsigned char>> DecodeBase64(std::string_view str);
76
std::string EncodeBase64(std::span<const unsigned char> input);
77
0
inline std::string EncodeBase64(std::span<const std::byte> input) { return EncodeBase64(MakeUCharSpan(input)); }
78
0
inline std::string EncodeBase64(std::string_view str) { return EncodeBase64(MakeUCharSpan(str)); }
79
std::optional<std::vector<unsigned char>> DecodeBase32(std::string_view str);
80
81
/**
82
 * Base32 encode.
83
 * If `pad` is true, then the output will be padded with '=' so that its length
84
 * is a multiple of 8.
85
 */
86
std::string EncodeBase32(std::span<const unsigned char> input, bool pad = true);
87
88
/**
89
 * Base32 encode.
90
 * If `pad` is true, then the output will be padded with '=' so that its length
91
 * is a multiple of 8.
92
 */
93
std::string EncodeBase32(std::string_view str, bool pad = true);
94
95
/**
96
 * Splits socket address string into host string and port value.
97
 * Validates port value.
98
 *
99
 * @param[in] in        The socket address string to split.
100
 * @param[out] portOut  Port-portion of the input, if found and parsable.
101
 * @param[out] hostOut  Host-portion of the input, if found.
102
 * @return              true if port-portion is absent or within its allowed range, otherwise false
103
 */
104
bool SplitHostPort(std::string_view in, uint16_t& portOut, std::string& hostOut);
105
106
// LocaleIndependentAtoi is provided for backwards compatibility reasons.
107
//
108
// New code should use ToIntegral.
109
//
110
// The goal of LocaleIndependentAtoi is to replicate the defined behaviour of
111
// std::atoi as it behaves under the "C" locale, and remove some undefined
112
// behavior. If the parsed value is bigger than the integer type's maximum
113
// value, or smaller than the integer type's minimum value, std::atoi has
114
// undefined behavior, while this function returns the maximum or minimum
115
// values, respectively.
116
template <typename T>
117
T LocaleIndependentAtoi(std::string_view str)
118
0
{
119
0
    static_assert(std::is_integral_v<T>);
120
0
    T result;
121
    // Emulate atoi(...) handling of white space and leading +/-.
122
0
    std::string_view s = util::TrimStringView(str);
123
0
    if (!s.empty() && s[0] == '+') {
  Branch (123:9): [True: 0, False: 0]
  Branch (123:23): [True: 0, False: 0]
  Branch (123:9): [True: 0, False: 0]
  Branch (123:23): [True: 0, False: 0]
  Branch (123:9): [True: 0, False: 0]
  Branch (123:23): [True: 0, False: 0]
  Branch (123:9): [True: 0, False: 0]
  Branch (123:23): [True: 0, False: 0]
  Branch (123:9): [True: 0, False: 0]
  Branch (123:23): [True: 0, False: 0]
  Branch (123:9): [True: 0, False: 0]
  Branch (123:23): [True: 0, False: 0]
  Branch (123:9): [True: 0, False: 0]
  Branch (123:23): [True: 0, False: 0]
  Branch (123:9): [True: 0, False: 0]
  Branch (123:23): [True: 0, False: 0]
124
0
        if (s.length() >= 2 && s[1] == '-') {
  Branch (124:13): [True: 0, False: 0]
  Branch (124:32): [True: 0, False: 0]
  Branch (124:13): [True: 0, False: 0]
  Branch (124:32): [True: 0, False: 0]
  Branch (124:13): [True: 0, False: 0]
  Branch (124:32): [True: 0, False: 0]
  Branch (124:13): [True: 0, False: 0]
  Branch (124:32): [True: 0, False: 0]
  Branch (124:13): [True: 0, False: 0]
  Branch (124:32): [True: 0, False: 0]
  Branch (124:13): [True: 0, False: 0]
  Branch (124:32): [True: 0, False: 0]
  Branch (124:13): [True: 0, False: 0]
  Branch (124:32): [True: 0, False: 0]
  Branch (124:13): [True: 0, False: 0]
  Branch (124:32): [True: 0, False: 0]
125
0
            return 0;
126
0
        }
127
0
        s = s.substr(1);
128
0
    }
129
0
    auto [_, error_condition] = std::from_chars(s.data(), s.data() + s.size(), result);
130
0
    if (error_condition == std::errc::result_out_of_range) {
  Branch (130:9): [True: 0, False: 0]
  Branch (130:9): [True: 0, False: 0]
  Branch (130:9): [True: 0, False: 0]
  Branch (130:9): [True: 0, False: 0]
  Branch (130:9): [True: 0, False: 0]
  Branch (130:9): [True: 0, False: 0]
  Branch (130:9): [True: 0, False: 0]
  Branch (130:9): [True: 0, False: 0]
131
0
        if (s.length() >= 1 && s[0] == '-') {
  Branch (131:13): [True: 0, False: 0]
  Branch (131:32): [True: 0, False: 0]
  Branch (131:13): [True: 0, False: 0]
  Branch (131:32): [True: 0, False: 0]
  Branch (131:13): [True: 0, False: 0]
  Branch (131:32): [True: 0, False: 0]
  Branch (131:13): [True: 0, False: 0]
  Branch (131:32): [True: 0, False: 0]
  Branch (131:13): [True: 0, False: 0]
  Branch (131:32): [True: 0, False: 0]
  Branch (131:13): [True: 0, False: 0]
  Branch (131:32): [True: 0, False: 0]
  Branch (131:13): [True: 0, False: 0]
  Branch (131:32): [True: 0, False: 0]
  Branch (131:13): [True: 0, False: 0]
  Branch (131:32): [True: 0, False: 0]
132
            // Saturate underflow, per strtoll's behavior.
133
0
            return std::numeric_limits<T>::min();
134
0
        } else {
135
            // Saturate overflow, per strtoll's behavior.
136
0
            return std::numeric_limits<T>::max();
137
0
        }
138
0
    } else if (error_condition != std::errc{}) {
  Branch (138:16): [True: 0, False: 0]
  Branch (138:16): [True: 0, False: 0]
  Branch (138:16): [True: 0, False: 0]
  Branch (138:16): [True: 0, False: 0]
  Branch (138:16): [True: 0, False: 0]
  Branch (138:16): [True: 0, False: 0]
  Branch (138:16): [True: 0, False: 0]
  Branch (138:16): [True: 0, False: 0]
139
0
        return 0;
140
0
    }
141
0
    return result;
142
0
}
Unexecuted instantiation: int LocaleIndependentAtoi<int>(std::basic_string_view<char, std::char_traits<char> >)
Unexecuted instantiation: long LocaleIndependentAtoi<long>(std::basic_string_view<char, std::char_traits<char> >)
Unexecuted instantiation: signed char LocaleIndependentAtoi<signed char>(std::basic_string_view<char, std::char_traits<char> >)
Unexecuted instantiation: unsigned char LocaleIndependentAtoi<unsigned char>(std::basic_string_view<char, std::char_traits<char> >)
Unexecuted instantiation: short LocaleIndependentAtoi<short>(std::basic_string_view<char, std::char_traits<char> >)
Unexecuted instantiation: unsigned short LocaleIndependentAtoi<unsigned short>(std::basic_string_view<char, std::char_traits<char> >)
Unexecuted instantiation: unsigned int LocaleIndependentAtoi<unsigned int>(std::basic_string_view<char, std::char_traits<char> >)
Unexecuted instantiation: unsigned long LocaleIndependentAtoi<unsigned long>(std::basic_string_view<char, std::char_traits<char> >)
143
144
/**
145
 * Tests if the given character is a decimal digit.
146
 * @param[in] c     character to test
147
 * @return          true if the argument is a decimal digit; otherwise false.
148
 */
149
constexpr bool IsDigit(char c)
150
0
{
151
0
    return c >= '0' && c <= '9';
  Branch (151:12): [True: 0, False: 0]
  Branch (151:24): [True: 0, False: 0]
152
0
}
153
154
/**
155
 * Tests if the given character is a whitespace character. The whitespace characters
156
 * are: space, form-feed ('\f'), newline ('\n'), carriage return ('\r'), horizontal
157
 * tab ('\t'), and vertical tab ('\v').
158
 *
159
 * This function is locale independent. Under the C locale this function gives the
160
 * same result as std::isspace.
161
 *
162
 * @param[in] c     character to test
163
 * @return          true if the argument is a whitespace character; otherwise false
164
 */
165
0
constexpr inline bool IsSpace(char c) noexcept {
166
0
    return c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v';
  Branch (166:12): [True: 0, False: 0]
  Branch (166:24): [True: 0, False: 0]
  Branch (166:37): [True: 0, False: 0]
  Branch (166:50): [True: 0, False: 0]
  Branch (166:63): [True: 0, False: 0]
  Branch (166:76): [True: 0, False: 0]
167
0
}
168
169
/**
170
 * Convert string to integral type T. Leading whitespace, a leading +, or any
171
 * trailing character fail the parsing. The required format expressed as regex
172
 * is `-?[0-9]+` by default (or `-?[0-9a-fA-F]+` if base = 16).
173
 * The minus sign is only permitted for signed integer types.
174
 *
175
 * @returns std::nullopt if the entire string could not be parsed, or if the
176
 *   parsed value is not in the range representable by the type T.
177
 */
178
template <typename T>
179
std::optional<T> ToIntegral(std::string_view str, size_t base = 10)
180
12.4k
{
181
12.4k
    static_assert(std::is_integral_v<T>);
182
12.4k
    T result;
183
12.4k
    const auto [first_nonmatching, error_condition] = std::from_chars(str.data(), str.data() + str.size(), result, base);
184
12.4k
    if (first_nonmatching != str.data() + str.size() || error_condition != std::errc{}) {
  Branch (184:9): [True: 0, False: 0]
  Branch (184:57): [True: 0, False: 0]
  Branch (184:9): [True: 7, False: 9.97k]
  Branch (184:57): [True: 0, False: 9.97k]
  Branch (184:9): [True: 13, False: 2.43k]
  Branch (184:57): [True: 9, False: 2.42k]
  Branch (184:9): [True: 0, False: 0]
  Branch (184:57): [True: 0, False: 0]
  Branch (184:9): [True: 0, False: 0]
  Branch (184:57): [True: 0, False: 0]
  Branch (184:9): [True: 0, False: 0]
  Branch (184:57): [True: 0, False: 0]
185
29
        return std::nullopt;
186
29
    }
187
12.3k
    return result;
188
12.4k
}
Unexecuted instantiation: std::optional<unsigned short> ToIntegral<unsigned short>(std::basic_string_view<char, std::char_traits<char> >, unsigned long)
std::optional<unsigned char> ToIntegral<unsigned char>(std::basic_string_view<char, std::char_traits<char> >, unsigned long)
Line
Count
Source
180
9.98k
{
181
9.98k
    static_assert(std::is_integral_v<T>);
182
9.98k
    T result;
183
9.98k
    const auto [first_nonmatching, error_condition] = std::from_chars(str.data(), str.data() + str.size(), result, base);
184
9.98k
    if (first_nonmatching != str.data() + str.size() || error_condition != std::errc{}) {
  Branch (184:9): [True: 7, False: 9.97k]
  Branch (184:57): [True: 0, False: 9.97k]
185
7
        return std::nullopt;
186
7
    }
187
9.97k
    return result;
188
9.98k
}
std::optional<unsigned long> ToIntegral<unsigned long>(std::basic_string_view<char, std::char_traits<char> >, unsigned long)
Line
Count
Source
180
2.44k
{
181
2.44k
    static_assert(std::is_integral_v<T>);
182
2.44k
    T result;
183
2.44k
    const auto [first_nonmatching, error_condition] = std::from_chars(str.data(), str.data() + str.size(), result, base);
184
2.44k
    if (first_nonmatching != str.data() + str.size() || error_condition != std::errc{}) {
  Branch (184:9): [True: 13, False: 2.43k]
  Branch (184:57): [True: 9, False: 2.42k]
185
22
        return std::nullopt;
186
22
    }
187
2.42k
    return result;
188
2.44k
}
Unexecuted instantiation: std::optional<unsigned int> ToIntegral<unsigned int>(std::basic_string_view<char, std::char_traits<char> >, unsigned long)
Unexecuted instantiation: std::optional<int> ToIntegral<int>(std::basic_string_view<char, std::char_traits<char> >, unsigned long)
Unexecuted instantiation: std::optional<long> ToIntegral<long>(std::basic_string_view<char, std::char_traits<char> >, unsigned long)
189
190
/**
191
 * Format a paragraph of text to a fixed width, adding spaces for
192
 * indentation to any added line.
193
 */
194
std::string FormatParagraph(std::string_view in, size_t width = 79, size_t indent = 0);
195
196
/**
197
 * Timing-attack-resistant comparison.
198
 * Takes time proportional to length
199
 * of first argument.
200
 */
201
template <typename T>
202
bool TimingResistantEqual(const T& a, const T& b)
203
1.82k
{
204
1.82k
    if (b.size() == 0) return a.size() == 0;
  Branch (204:9): [True: 0, False: 913]
  Branch (204:9): [True: 0, False: 913]
205
1.82k
    size_t accumulator = a.size() ^ b.size();
206
69.3k
    for (size_t i = 0; i < a.size(); i++)
  Branch (206:24): [True: 9.13k, False: 913]
  Branch (206:24): [True: 58.4k, False: 913]
207
67.5k
        accumulator |= size_t(a[i] ^ b[i%b.size()]);
208
1.82k
    return accumulator == 0;
209
1.82k
}
bool TimingResistantEqual<std::basic_string_view<char, std::char_traits<char> > >(std::basic_string_view<char, std::char_traits<char> > const&, std::basic_string_view<char, std::char_traits<char> > const&)
Line
Count
Source
203
913
{
204
913
    if (b.size() == 0) return a.size() == 0;
  Branch (204:9): [True: 0, False: 913]
205
913
    size_t accumulator = a.size() ^ b.size();
206
10.0k
    for (size_t i = 0; i < a.size(); i++)
  Branch (206:24): [True: 9.13k, False: 913]
207
9.13k
        accumulator |= size_t(a[i] ^ b[i%b.size()]);
208
913
    return accumulator == 0;
209
913
}
bool TimingResistantEqual<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
Line
Count
Source
203
913
{
204
913
    if (b.size() == 0) return a.size() == 0;
  Branch (204:9): [True: 0, False: 913]
205
913
    size_t accumulator = a.size() ^ b.size();
206
59.3k
    for (size_t i = 0; i < a.size(); i++)
  Branch (206:24): [True: 58.4k, False: 913]
207
58.4k
        accumulator |= size_t(a[i] ^ b[i%b.size()]);
208
913
    return accumulator == 0;
209
913
}
210
211
/** Parse number as fixed point according to JSON number syntax.
212
 * @returns true on success, false on error.
213
 * @note The result must be in the range (-10^18,10^18), otherwise an overflow error will trigger.
214
 */
215
[[nodiscard]] bool ParseFixedPoint(std::string_view, int decimals, int64_t *amount_out);
216
217
namespace {
218
/** Helper class for the default infn argument to ConvertBits (just returns the input). */
219
struct IntIdentity
220
{
221
0
    [[maybe_unused]] int operator()(int x) const { return x; }
Unexecuted instantiation: bitcoind.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: init.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: httpserver.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: httprpc.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: base.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: dbwrapper.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: banman.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: addrdb.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: addrman.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: txindex.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: txospenderindex.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: coinstatsindex.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: blockfilterindex.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: blockfilter.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: chain.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: checks.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: coinstats.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: context.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: mapport.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: net.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: i2p.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: bip324.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: net_processing.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: blockencodings.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: headerssync.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: netgroup.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: blockmanager_args.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: blockstorage.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: caches.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: chainstate.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: chainstatemanager_args.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: coins_view_args.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: database_args.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: eviction.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: interfaces.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: coin.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: kernel_notifications.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: mempool_args.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: mempool_persist.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: mempool_persist_args.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: miner.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: tx_verify.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: mining_args.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: mini_miner.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: peerman_args.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: transaction.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: txdownloadman_impl.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: txorphanage.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: txreconciliation.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: block_policy_estimator.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: packages.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: rbf.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: settings.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: private_broadcast.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: rest.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: blockchain.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: external_signer.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: fees.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: mempool.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: mining.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: node.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: output_script.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: rawtransaction.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: psbt.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: server.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: server_util.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: signmessage.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: txoutproof.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: signet.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: torcontrol.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: txdb.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: txmempool.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: txgraph.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: txrequest.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: validation.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: disconnected_transactions.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: sigcache.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: utxo_snapshot.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: ephemeral_policy.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: truc_policy.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: validationinterface.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: versionbits.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: feebumper.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: coincontrol.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: db.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: load.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: receive.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: wallet.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: spend.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: util.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: transactions.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: backup.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: encrypt.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: addresses.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: coins.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: scriptpubkeyman.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: crypter.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: coinselection.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: external_signer_scriptpubkeyman.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: walletdb.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: sqlite.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: migrate.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: walletutil.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: addresstype.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: base58.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: chainparams.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: args.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: bloom.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: messages.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: netif.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: pcp.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: compressor.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: core_io.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: deploymentinfo.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: key.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: key_io.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: merkleblock.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: musig.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: net_permissions.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: net_types.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: netaddress.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: netbase.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: outputtype.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: policy.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: pow.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: protocol.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: rawtransaction_util.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: request.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: descriptor.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: miniscript.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: sign.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: signingprovider.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: solver.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: asmap.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: bip32.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: bytevectorhash.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: fs_helpers.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: hasher.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: moneystr.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: strencodings.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: time.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: random.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: streams.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: arith_uint256.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: merkle.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: tx_check.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: hash.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: block.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: pubkey.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: interpreter.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: script.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: uint256.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: muhash.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
Unexecuted instantiation: siphash.cpp:(anonymous namespace)::IntIdentity::operator()(int) const
222
};
223
224
} // namespace
225
226
/** Convert from one power-of-2 number base to another. */
227
template<int frombits, int tobits, bool pad, typename O, typename It, typename I = IntIdentity>
228
913
bool ConvertBits(O outfn, It it, It end, I infn = {}) {
229
913
    size_t acc = 0;
230
913
    size_t bits = 0;
231
913
    constexpr size_t maxv = (1 << tobits) - 1;
232
913
    constexpr size_t max_acc = (1 << (frombits + tobits - 1)) - 1;
233
92.2k
    while (it != end) {
  Branch (233:12): [True: 0, False: 0]
  Branch (233:12): [True: 0, False: 0]
  Branch (233:12): [True: 0, False: 0]
  Branch (233:12): [True: 0, False: 0]
  Branch (233:12): [True: 0, False: 0]
  Branch (233:12): [True: 0, False: 0]
  Branch (233:12): [True: 91.3k, False: 913]
  Branch (233:12): [True: 0, False: 0]
  Branch (233:12): [True: 0, False: 0]
234
91.3k
        int v = infn(*it);
235
91.3k
        if (v < 0) return false;
  Branch (235:13): [True: 0, False: 0]
  Branch (235:13): [True: 0, False: 0]
  Branch (235:13): [True: 0, False: 0]
  Branch (235:13): [True: 0, False: 0]
  Branch (235:13): [True: 0, False: 0]
  Branch (235:13): [True: 0, False: 0]
  Branch (235:13): [True: 0, False: 91.3k]
  Branch (235:13): [True: 0, False: 0]
  Branch (235:13): [True: 0, False: 0]
236
91.3k
        acc = ((acc << frombits) | v) & max_acc;
237
91.3k
        bits += frombits;
238
159k
        while (bits >= tobits) {
  Branch (238:16): [True: 0, False: 0]
  Branch (238:16): [True: 0, False: 0]
  Branch (238:16): [True: 0, False: 0]
  Branch (238:16): [True: 0, False: 0]
  Branch (238:16): [True: 0, False: 0]
  Branch (238:16): [True: 0, False: 0]
  Branch (238:16): [True: 68.4k, False: 91.3k]
  Branch (238:16): [True: 0, False: 0]
  Branch (238:16): [True: 0, False: 0]
239
68.4k
            bits -= tobits;
240
68.4k
            outfn((acc >> bits) & maxv);
241
68.4k
        }
242
91.3k
        ++it;
243
91.3k
    }
244
913
    if (pad) {
  Branch (244:9): [Folded - Ignored]
  Branch (244:9): [Folded - Ignored]
  Branch (244:9): [Folded - Ignored]
  Branch (244:9): [Folded - Ignored]
  Branch (244:9): [Folded - Ignored]
  Branch (244:9): [Folded - Ignored]
  Branch (244:9): [Folded - Ignored]
  Branch (244:9): [Folded - Ignored]
  Branch (244:9): [Folded - Ignored]
245
0
        if (bits) outfn((acc << (tobits - bits)) & maxv);
  Branch (245:13): [True: 0, False: 0]
  Branch (245:13): [True: 0, False: 0]
  Branch (245:13): [True: 0, False: 0]
  Branch (245:13): [True: 0, False: 0]
  Branch (245:13): [True: 0, False: 0]
  Branch (245:13): [True: 0, False: 0]
  Branch (245:13): [True: 0, False: 0]
  Branch (245:13): [True: 0, False: 0]
  Branch (245:13): [True: 0, False: 0]
246
913
    } else if (bits >= frombits || ((acc << (tobits - bits)) & maxv)) {
  Branch (246:16): [True: 0, False: 0]
  Branch (246:36): [True: 0, False: 0]
  Branch (246:16): [True: 0, False: 0]
  Branch (246:36): [True: 0, False: 0]
  Branch (246:16): [True: 0, False: 0]
  Branch (246:36): [True: 0, False: 0]
  Branch (246:16): [True: 0, False: 0]
  Branch (246:36): [True: 0, False: 0]
  Branch (246:16): [True: 0, False: 0]
  Branch (246:36): [True: 0, False: 0]
  Branch (246:16): [True: 0, False: 0]
  Branch (246:36): [True: 0, False: 0]
  Branch (246:16): [True: 0, False: 913]
  Branch (246:36): [True: 0, False: 913]
  Branch (246:16): [True: 0, False: 0]
  Branch (246:36): [True: 0, False: 0]
  Branch (246:16): [True: 0, False: 0]
  Branch (246:36): [True: 0, False: 0]
247
0
        return false;
248
0
    }
249
913
    return true;
250
913
}
Unexecuted instantiation: key_io.cpp:bool ConvertBits<8, 5, true, (anonymous namespace)::DestinationEncoder::operator()[abi:cxx11](WitnessV0ScriptHash const&) const::{lambda(unsigned char)#1}, unsigned char const*, (anonymous namespace)::IntIdentity>((anonymous namespace)::DestinationEncoder::operator()[abi:cxx11](WitnessV0ScriptHash const&) const::{lambda(unsigned char)#1}, unsigned char const*, unsigned char const*, (anonymous namespace)::IntIdentity)
Unexecuted instantiation: key_io.cpp:bool ConvertBits<8, 5, true, (anonymous namespace)::DestinationEncoder::operator()[abi:cxx11](WitnessV0KeyHash const&) const::{lambda(unsigned char)#1}, unsigned char const*, (anonymous namespace)::IntIdentity>((anonymous namespace)::DestinationEncoder::operator()[abi:cxx11](WitnessV0KeyHash const&) const::{lambda(unsigned char)#1}, unsigned char const*, unsigned char const*, (anonymous namespace)::IntIdentity)
Unexecuted instantiation: key_io.cpp:bool ConvertBits<8, 5, true, (anonymous namespace)::DestinationEncoder::operator()[abi:cxx11](WitnessV1Taproot const&) const::{lambda(unsigned char)#1}, unsigned char const*, (anonymous namespace)::IntIdentity>((anonymous namespace)::DestinationEncoder::operator()[abi:cxx11](WitnessV1Taproot const&) const::{lambda(unsigned char)#1}, unsigned char const*, unsigned char const*, (anonymous namespace)::IntIdentity)
Unexecuted instantiation: key_io.cpp:bool ConvertBits<8, 5, true, (anonymous namespace)::DestinationEncoder::operator()[abi:cxx11](WitnessUnknown const&) const::{lambda(unsigned char)#1}, __gnu_cxx::__normal_iterator<unsigned char const*, std::vector<unsigned char, std::allocator<unsigned char> > >, (anonymous namespace)::IntIdentity>((anonymous namespace)::DestinationEncoder::operator()[abi:cxx11](WitnessUnknown const&) const::{lambda(unsigned char)#1}, __gnu_cxx::__normal_iterator<unsigned char const*, std::vector<unsigned char, std::allocator<unsigned char> > >, __gnu_cxx::__normal_iterator<unsigned char const*, std::vector<unsigned char, std::allocator<unsigned char> > >, (anonymous namespace)::IntIdentity)
Unexecuted instantiation: key_io.cpp:bool ConvertBits<5, 8, false, (anonymous namespace)::DecodeDestination(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, CChainParams const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::vector<int, std::allocator<int> >*)::$_0, __gnu_cxx::__normal_iterator<unsigned char const*, std::vector<unsigned char, std::allocator<unsigned char> > >, (anonymous namespace)::IntIdentity>((anonymous namespace)::DecodeDestination(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, CChainParams const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::vector<int, std::allocator<int> >*)::$_0, __gnu_cxx::__normal_iterator<unsigned char const*, std::vector<unsigned char, std::allocator<unsigned char> > >, __gnu_cxx::__normal_iterator<unsigned char const*, std::vector<unsigned char, std::allocator<unsigned char> > >, (anonymous namespace)::IntIdentity)
Unexecuted instantiation: strencodings.cpp:bool ConvertBits<8, 6, true, EncodeBase64[abi:cxx11](std::span<unsigned char const, 18446744073709551615ul>)::$_0, __gnu_cxx::__normal_iterator<unsigned char const*, std::span<unsigned char const, 18446744073709551615ul> >, (anonymous namespace)::IntIdentity>(EncodeBase64[abi:cxx11](std::span<unsigned char const, 18446744073709551615ul>)::$_0, __gnu_cxx::__normal_iterator<unsigned char const*, std::span<unsigned char const, 18446744073709551615ul> >, __gnu_cxx::__normal_iterator<unsigned char const*, std::span<unsigned char const, 18446744073709551615ul> >, (anonymous namespace)::IntIdentity)
strencodings.cpp:bool ConvertBits<6, 8, false, DecodeBase64(std::basic_string_view<char, std::char_traits<char> >)::$_0, char const*, DecodeBase64(std::basic_string_view<char, std::char_traits<char> >)::$_1>(DecodeBase64(std::basic_string_view<char, std::char_traits<char> >)::$_0, char const*, char const*, DecodeBase64(std::basic_string_view<char, std::char_traits<char> >)::$_1)
Line
Count
Source
228
913
bool ConvertBits(O outfn, It it, It end, I infn = {}) {
229
913
    size_t acc = 0;
230
913
    size_t bits = 0;
231
913
    constexpr size_t maxv = (1 << tobits) - 1;
232
913
    constexpr size_t max_acc = (1 << (frombits + tobits - 1)) - 1;
233
92.2k
    while (it != end) {
  Branch (233:12): [True: 91.3k, False: 913]
234
91.3k
        int v = infn(*it);
235
91.3k
        if (v < 0) return false;
  Branch (235:13): [True: 0, False: 91.3k]
236
91.3k
        acc = ((acc << frombits) | v) & max_acc;
237
91.3k
        bits += frombits;
238
159k
        while (bits >= tobits) {
  Branch (238:16): [True: 68.4k, False: 91.3k]
239
68.4k
            bits -= tobits;
240
68.4k
            outfn((acc >> bits) & maxv);
241
68.4k
        }
242
91.3k
        ++it;
243
91.3k
    }
244
913
    if (pad) {
  Branch (244:9): [Folded - Ignored]
245
0
        if (bits) outfn((acc << (tobits - bits)) & maxv);
  Branch (245:13): [True: 0, False: 0]
246
913
    } else if (bits >= frombits || ((acc << (tobits - bits)) & maxv)) {
  Branch (246:16): [True: 0, False: 913]
  Branch (246:36): [True: 0, False: 913]
247
0
        return false;
248
0
    }
249
913
    return true;
250
913
}
Unexecuted instantiation: strencodings.cpp:bool ConvertBits<8, 5, true, EncodeBase32[abi:cxx11](std::span<unsigned char const, 18446744073709551615ul>, bool)::$_0, __gnu_cxx::__normal_iterator<unsigned char const*, std::span<unsigned char const, 18446744073709551615ul> >, (anonymous namespace)::IntIdentity>(EncodeBase32[abi:cxx11](std::span<unsigned char const, 18446744073709551615ul>, bool)::$_0, __gnu_cxx::__normal_iterator<unsigned char const*, std::span<unsigned char const, 18446744073709551615ul> >, __gnu_cxx::__normal_iterator<unsigned char const*, std::span<unsigned char const, 18446744073709551615ul> >, (anonymous namespace)::IntIdentity)
Unexecuted instantiation: strencodings.cpp:bool ConvertBits<5, 8, false, DecodeBase32(std::basic_string_view<char, std::char_traits<char> >)::$_0, char const*, DecodeBase32(std::basic_string_view<char, std::char_traits<char> >)::$_1>(DecodeBase32(std::basic_string_view<char, std::char_traits<char> >)::$_0, char const*, char const*, DecodeBase32(std::basic_string_view<char, std::char_traits<char> >)::$_1)
251
252
/**
253
 * Converts the given character to its lowercase equivalent.
254
 * This function is locale independent. It only converts uppercase
255
 * characters in the standard 7-bit ASCII range.
256
 * This is a feature, not a limitation.
257
 *
258
 * @param[in] c     the character to convert to lowercase.
259
 * @return          the lowercase equivalent of c; or the argument
260
 *                  if no conversion is possible.
261
 */
262
constexpr char ToLower(char c)
263
19.4k
{
264
19.4k
    return (c >= 'A' && c <= 'Z' ? (c - 'A') + 'a' : c);
  Branch (264:13): [True: 17.1k, False: 2.35k]
  Branch (264:25): [True: 4.03k, False: 13.0k]
265
19.4k
}
266
267
/**
268
 * Returns the lowercase equivalent of the given string.
269
 * This function is locale independent. It only converts uppercase
270
 * characters in the standard 7-bit ASCII range.
271
 * This is a feature, not a limitation.
272
 *
273
 * @param[in] str   the string to convert to lowercase.
274
 * @returns         lowercased equivalent of str
275
 */
276
std::string ToLower(std::string_view str);
277
278
/**
279
 * Converts the given character to its uppercase equivalent.
280
 * This function is locale independent. It only converts lowercase
281
 * characters in the standard 7-bit ASCII range.
282
 * This is a feature, not a limitation.
283
 *
284
 * @param[in] c     the character to convert to uppercase.
285
 * @return          the uppercase equivalent of c; or the argument
286
 *                  if no conversion is possible.
287
 */
288
constexpr char ToUpper(char c)
289
0
{
290
0
    return (c >= 'a' && c <= 'z' ? (c - 'a') + 'A' : c);
  Branch (290:13): [True: 0, False: 0]
  Branch (290:25): [True: 0, False: 0]
291
0
}
292
293
/**
294
 * Returns the uppercase equivalent of the given string.
295
 * This function is locale independent. It only converts lowercase
296
 * characters in the standard 7-bit ASCII range.
297
 * This is a feature, not a limitation.
298
 *
299
 * @param[in] str   the string to convert to uppercase.
300
 * @returns         UPPERCASED EQUIVALENT OF str
301
 */
302
std::string ToUpper(std::string_view str);
303
304
/**
305
 * Capitalizes the first character of the given string.
306
 * This function is locale independent. It only converts lowercase
307
 * characters in the standard 7-bit ASCII range.
308
 * This is a feature, not a limitation.
309
 *
310
 * @param[in] str   the string to capitalize.
311
 * @returns         string with the first letter capitalized.
312
 */
313
std::string Capitalize(std::string str);
314
315
/**
316
 * Parse a string with suffix unit [k|K|m|M|g|G|t|T].
317
 * Must be a whole integer, fractions not allowed (0.5t), no whitespace or +-
318
 * Lowercase units are 1000 base. Uppercase units are 1024 base.
319
 * Examples: 2m,27M,19g,41T
320
 *
321
 * @param[in] str                  the string to convert into bytes
322
 * @param[in] default_multiplier   if no unit is found in str use this unit
323
 * @returns                        optional uint64_t bytes from str or nullopt
324
 *                                 if ToIntegral is false, str is empty, trailing whitespace or overflow
325
 */
326
std::optional<uint64_t> ParseByteUnits(std::string_view str, ByteUnit default_multiplier);
327
328
/**
329
 *  Locale-independent, ASCII-only comparator
330
 *  @param[in] s1 a string to compare
331
 *  @param[in] s2 another string to compare
332
 *  @returns true if s1 == s2 when both strings are converted to lowercase
333
 */
334
bool CaseInsensitiveEqual(std::string_view s1, std::string_view s2);
335
336
namespace util {
337
/** consteval version of HexDigit() without the lookup table. */
338
consteval uint8_t ConstevalHexDigit(const char c)
339
{
340
    if (c >= '0' && c <= '9') return c - '0';
341
    if (c >= 'a' && c <= 'f') return c - 'a' + 0xa;
342
343
    throw "Only lowercase hex digits are allowed, for consistency";
344
}
345
346
namespace detail {
347
template <size_t N>
348
struct Hex {
349
    std::array<std::byte, N / 2> bytes{};
350
    consteval Hex(const char (&hex_str)[N])
351
        // 2 hex digits required per byte + implicit null terminator
352
        requires(N % 2 == 1)
353
    {
354
        if (hex_str[N - 1]) throw "null terminator required";
355
        for (std::size_t i = 0; i < bytes.size(); ++i) {
356
            bytes[i] = static_cast<std::byte>(
357
                (ConstevalHexDigit(hex_str[2 * i]) << 4) |
358
                 ConstevalHexDigit(hex_str[2 * i + 1]));
359
        }
360
    }
361
};
362
} // namespace detail
363
364
/**
365
 * ""_hex is a compile-time user-defined literal returning a
366
 * `std::array<std::byte>`, equivalent to ParseHex(). Variants provided:
367
 *
368
 * - ""_hex_v: Returns `std::vector<std::byte>`, useful for heap allocation or
369
 *   variable-length serialization.
370
 *
371
 * - ""_hex_u8: Returns `std::array<uint8_t>`, for cases where `std::byte` is
372
 *   incompatible.
373
 *
374
 * - ""_hex_v_u8: Returns `std::vector<uint8_t>`, combining heap allocation with
375
 *   `uint8_t`.
376
 *
377
 * @warning It could be necessary to use vector instead of array variants when
378
 *   serializing, or vice versa, because vectors are assumed to be variable-
379
 *   length and serialized with a size prefix, while arrays are considered fixed
380
 *   length and serialized with no prefix.
381
 *
382
 * @warning It may be preferable to use vector variants to save stack space when
383
 *   declaring local variables if hex strings are large. Alternatively variables
384
 *   could be declared constexpr to avoid using stack space.
385
 *
386
 * @warning Avoid `uint8_t` variants when not necessary, as the codebase
387
 *   migrates to use `std::byte` instead of `unsigned char` and `uint8_t`.
388
 *
389
 * @note One reason ""_hex uses `std::array` instead of `std::vector` like
390
 *   ParseHex() does is because heap-based containers cannot cross the compile-
391
 *   time/runtime barrier.
392
 */
393
inline namespace hex_literals {
394
395
template <util::detail::Hex str>
396
0
constexpr auto operator""_hex() { return str.bytes; }
Unexecuted instantiation: _ZN4util12hex_literalsli4_hexITnNS_6detail3HexEXtlNS3_ILm337EEEtlSt5arrayISt4byteLm168EEtlA168_S6_LS6_96ELS6_1ELS6_0ELS6_0ELS6_0ELS6_0ELS6_0ELS6_0ELS6_0ELS6_0ELS6_0ELS6_0ELS6_0ELS6_255ELS6_255ELS6_255ELS6_127ELS6_0ELS6_0ELS6_0ELS6_0ELS6_255ELS6_255ELS6_255ELS6_127ELS6_254ELS6_255ELS6_255ELS6_127ELS6_1ELS6_255ELS6_255ELS6_255ELS6_127ELS6_0ELS6_0ELS6_0ELS6_0ELS6_255ELS6_255ELS6_255ELS6_127ELS6_0ELS6_255ELS6_255ELS6_255ELS6_127ELS6_0ELS6_47ELS6_85ELS6_82ELS6_71ELS6_69ELS6_78ELS6_84ELS6_58ELS6_32ELS6_65ELS6_108ELS6_101ELS6_114ELS6_116ELS6_32ELS6_107ELS6_101ELS6_121ELS6_32ELS6_99ELS6_111ELS6_109ELS6_112ELS6_114ELS6_111ELS6_109ELS6_105ELS6_115ELS6_101ELS6_100ELS6_44ELS6_32ELS6_117ELS6_112ELS6_103ELS6_114ELS6_97ELS6_100ELS6_101ELS6_32ELS6_114ELS6_101ELS6_113ELS6_117ELS6_105ELS6_114ELS6_101ELS6_100ELS6_0ELS6_70ELS6_48ELS6_68ELS6_2ELS6_32ELS6_101ELS6_63ELS6_235ELS6_214ELS6_65ELS6_15ELS6_71ELS6_15ELS6_107ELS6_174ELS6_17ELS6_202ELS6_209ELS6_156ELS6_72ELS6_65ELS6_59ELS6_236ELS6_177ELS6_172ELS6_44ELS6_23ELS6_249ELS6_8ELS6_253ELS6_15ELS6_213ELS6_59ELS6_220ELS6_58ELS6_189ELS6_82ELS6_2ELS6_32ELS6_109ELS6_14ELS6_156ELS6_150ELS6_254ELS6_136ELS6_212ELS6_160ELS6_240ELS6_30ELS6_217ELS6_222ELS6_218ELS6_226ELS6_182ELS6_249ELS6_224ELS6_13ELS6_169ELS6_76ELS6_173ELS6_15ELS6_236ELS6_170ELS6_230ELS6_110ELS6_207ELS6_104ELS6_155ELS6_247ELS6_27ELS6_80EEEEEEEDav
Unexecuted instantiation: _ZN4util12hex_literalsli4_hexITnNS_6detail3HexEXtlNS3_ILm131EEEtlSt5arrayISt4byteLm65EEtlA65_S6_LS6_4ELS6_103ELS6_138ELS6_253ELS6_176ELS6_254ELS6_85ELS6_72ELS6_39ELS6_25ELS6_103ELS6_241ELS6_166ELS6_113ELS6_48ELS6_183ELS6_16ELS6_92ELS6_214ELS6_168ELS6_40ELS6_224ELS6_57ELS6_9ELS6_166ELS6_121ELS6_98ELS6_224ELS6_234ELS6_31ELS6_97ELS6_222ELS6_182ELS6_73ELS6_246ELS6_188ELS6_63ELS6_76ELS6_239ELS6_56ELS6_196ELS6_243ELS6_85ELS6_4ELS6_229ELS6_30ELS6_193ELS6_18ELS6_222ELS6_92ELS6_56ELS6_77ELS6_247ELS6_186ELS6_11ELS6_141ELS6_87ELS6_138ELS6_76ELS6_112ELS6_43ELS6_107ELS6_241ELS6_29ELS6_95EEEEEEEDav
Unexecuted instantiation: _ZN4util12hex_literalsli4_hexITnNS_6detail3HexEXtlNS3_ILm67EEEEEEEDav
397
398
template <util::detail::Hex str>
399
0
constexpr auto operator""_hex_u8() { return std::bit_cast<std::array<uint8_t, str.bytes.size()>>(str.bytes); }
Unexecuted instantiation: _ZN4util12hex_literalsli7_hex_u8ITnNS_6detail3HexEXtlNS3_ILm65EEEtlSt5arrayISt4byteLm32EEtlA32_S6_LS6_134ELS6_128ELS6_135ELS6_202ELS6_2ELS6_166ELS6_249ELS6_116ELS6_196ELS6_89ELS6_137ELS6_36ELS6_195ELS6_107ELS6_87ELS6_118ELS6_45ELS6_50ELS6_203ELS6_69ELS6_113ELS6_113ELS6_103ELS6_227ELS6_0ELS6_98ELS6_44ELS6_113ELS6_103ELS6_227ELS6_137ELS6_101EEEEEEEDav
Unexecuted instantiation: _ZN4util12hex_literalsli7_hex_u8ITnNS_6detail3HexEXtlNS3_ILm65EEEtlSt5arrayISt4byteLm32EEtlA32_S6_LS6_80ELS6_146ELS6_155ELS6_116ELS6_193ELS6_160ELS6_73ELS6_84ELS6_183ELS6_139ELS6_75ELS6_96ELS6_53ELS6_233ELS6_122ELS6_94ELS6_7ELS6_138ELS6_90ELS6_15ELS6_40ELS6_236ELS6_150ELS6_213ELS6_71ELS6_191ELS6_238ELS6_154ELS6_206ELS6_128ELS6_58ELS6_192EEEEEEEDav
400
401
template <util::detail::Hex str>
402
constexpr auto operator""_hex_v() { return std::vector<std::byte>{str.bytes.begin(), str.bytes.end()}; }
403
404
template <util::detail::Hex str>
405
0
inline auto operator""_hex_v_u8() { return std::vector<uint8_t>{UCharCast(str.bytes.data()), UCharCast(str.bytes.data() + str.bytes.size())}; }
406
407
} // inline namespace hex_literals
408
} // namespace util
409
410
#endif // BITCOIN_UTIL_STRENCODINGS_H