/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 |