/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 <crypto/hex_base.h> // IWYU pragma: export |
13 | | #include <span.h> |
14 | | #include <util/string.h> |
15 | | |
16 | | #include <array> |
17 | | #include <bit> |
18 | | #include <charconv> |
19 | | #include <cstddef> |
20 | | #include <cstdint> |
21 | | #include <limits> |
22 | | #include <optional> |
23 | | #include <string> // IWYU pragma: export |
24 | | #include <string_view> // IWYU pragma: export |
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 | 296k | { |
119 | 296k | static_assert(std::is_integral_v<T>); |
120 | 296k | T result; |
121 | | // Emulate atoi(...) handling of white space and leading +/-. |
122 | 296k | std::string_view s = util::TrimStringView(str); |
123 | 296k | if (!s.empty() && s[0] == '+') { Branch (123:9): [True: 44.3k, False: 0]
Branch (123:23): [True: 0, False: 44.3k]
Branch (123:9): [True: 252k, False: 0]
Branch (123:23): [True: 0, False: 252k]
|
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]
|
125 | 0 | return 0; |
126 | 0 | } |
127 | 0 | s = s.substr(1); |
128 | 0 | } |
129 | 296k | auto [_, error_condition] = std::from_chars(s.data(), s.data() + s.size(), result); |
130 | 296k | if (error_condition == std::errc::result_out_of_range) { Branch (130:9): [True: 0, False: 44.3k]
Branch (130:9): [True: 0, False: 252k]
|
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]
|
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 | 296k | } else if (error_condition != std::errc{}) { Branch (138:16): [True: 0, False: 44.3k]
Branch (138:16): [True: 0, False: 252k]
|
139 | 0 | return 0; |
140 | 0 | } |
141 | 296k | return result; |
142 | 296k | } int LocaleIndependentAtoi<int>(std::basic_string_view<char, std::char_traits<char> >) Line | Count | Source | 118 | 44.3k | { | 119 | 44.3k | static_assert(std::is_integral_v<T>); | 120 | 44.3k | T result; | 121 | | // Emulate atoi(...) handling of white space and leading +/-. | 122 | 44.3k | std::string_view s = util::TrimStringView(str); | 123 | 44.3k | if (!s.empty() && s[0] == '+') { Branch (123:9): [True: 44.3k, False: 0]
Branch (123:23): [True: 0, False: 44.3k]
| 124 | 0 | if (s.length() >= 2 && s[1] == '-') { 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 | 44.3k | auto [_, error_condition] = std::from_chars(s.data(), s.data() + s.size(), result); | 130 | 44.3k | if (error_condition == std::errc::result_out_of_range) { Branch (130:9): [True: 0, False: 44.3k]
| 131 | 0 | if (s.length() >= 1 && s[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 | 44.3k | } else if (error_condition != std::errc{}) { Branch (138:16): [True: 0, False: 44.3k]
| 139 | 0 | return 0; | 140 | 0 | } | 141 | 44.3k | return result; | 142 | 44.3k | } |
long LocaleIndependentAtoi<long>(std::basic_string_view<char, std::char_traits<char> >) Line | Count | Source | 118 | 252k | { | 119 | 252k | static_assert(std::is_integral_v<T>); | 120 | 252k | T result; | 121 | | // Emulate atoi(...) handling of white space and leading +/-. | 122 | 252k | std::string_view s = util::TrimStringView(str); | 123 | 252k | if (!s.empty() && s[0] == '+') { Branch (123:9): [True: 252k, False: 0]
Branch (123:23): [True: 0, False: 252k]
| 124 | 0 | if (s.length() >= 2 && s[1] == '-') { 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 | 252k | auto [_, error_condition] = std::from_chars(s.data(), s.data() + s.size(), result); | 130 | 252k | if (error_condition == std::errc::result_out_of_range) { Branch (130:9): [True: 0, False: 252k]
| 131 | 0 | if (s.length() >= 1 && s[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 | 252k | } else if (error_condition != std::errc{}) { Branch (138:16): [True: 0, False: 252k]
| 139 | 0 | return 0; | 140 | 0 | } | 141 | 252k | return result; | 142 | 252k | } |
|
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 | 1.57M | { |
151 | 1.57M | return c >= '0' && c <= '9'; Branch (151:12): [True: 1.38M, False: 188k]
Branch (151:24): [True: 1.38M, False: 0]
|
152 | 1.57M | } |
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 | 20.2M | constexpr inline bool IsSpace(char c) noexcept { |
166 | 20.2M | return c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v'; Branch (166:12): [True: 0, False: 20.2M]
Branch (166:24): [True: 0, False: 20.2M]
Branch (166:37): [True: 0, False: 20.2M]
Branch (166:50): [True: 0, False: 20.2M]
Branch (166:63): [True: 0, False: 20.2M]
Branch (166:76): [True: 0, False: 20.2M]
|
167 | 20.2M | } |
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]+`. The minus sign is only permitted for signed integer types. |
173 | | * |
174 | | * @returns std::nullopt if the entire string could not be parsed, or if the |
175 | | * parsed value is not in the range representable by the type T. |
176 | | */ |
177 | | template <typename T> |
178 | | std::optional<T> ToIntegral(std::string_view str) |
179 | 432k | { |
180 | 432k | static_assert(std::is_integral_v<T>); |
181 | 432k | T result; |
182 | 432k | const auto [first_nonmatching, error_condition] = std::from_chars(str.data(), str.data() + str.size(), result); |
183 | 432k | if (first_nonmatching != str.data() + str.size() || error_condition != std::errc{}) { Branch (183:9): [True: 0, False: 66.5k]
Branch (183:57): [True: 0, False: 66.5k]
Branch (183:9): [True: 0, False: 11.0k]
Branch (183:57): [True: 0, False: 11.0k]
Branch (183:9): [True: 0, False: 354k]
Branch (183:57): [True: 0, False: 354k]
Branch (183:9): [True: 0, False: 0]
Branch (183:57): [True: 0, False: 0]
Branch (183:9): [True: 0, False: 0]
Branch (183:57): [True: 0, False: 0]
Branch (183:9): [True: 0, False: 0]
Branch (183:57): [True: 0, False: 0]
|
184 | 0 | return std::nullopt; |
185 | 0 | } |
186 | 432k | return result; |
187 | 432k | } std::optional<unsigned short> ToIntegral<unsigned short>(std::basic_string_view<char, std::char_traits<char> >) Line | Count | Source | 179 | 66.5k | { | 180 | 66.5k | static_assert(std::is_integral_v<T>); | 181 | 66.5k | T result; | 182 | 66.5k | const auto [first_nonmatching, error_condition] = std::from_chars(str.data(), str.data() + str.size(), result); | 183 | 66.5k | if (first_nonmatching != str.data() + str.size() || error_condition != std::errc{}) { Branch (183:9): [True: 0, False: 66.5k]
Branch (183:57): [True: 0, False: 66.5k]
| 184 | 0 | return std::nullopt; | 185 | 0 | } | 186 | 66.5k | return result; | 187 | 66.5k | } |
std::optional<unsigned long> ToIntegral<unsigned long>(std::basic_string_view<char, std::char_traits<char> >) Line | Count | Source | 179 | 11.0k | { | 180 | 11.0k | static_assert(std::is_integral_v<T>); | 181 | 11.0k | T result; | 182 | 11.0k | const auto [first_nonmatching, error_condition] = std::from_chars(str.data(), str.data() + str.size(), result); | 183 | 11.0k | if (first_nonmatching != str.data() + str.size() || error_condition != std::errc{}) { Branch (183:9): [True: 0, False: 11.0k]
Branch (183:57): [True: 0, False: 11.0k]
| 184 | 0 | return std::nullopt; | 185 | 0 | } | 186 | 11.0k | return result; | 187 | 11.0k | } |
std::optional<unsigned int> ToIntegral<unsigned int>(std::basic_string_view<char, std::char_traits<char> >) Line | Count | Source | 179 | 354k | { | 180 | 354k | static_assert(std::is_integral_v<T>); | 181 | 354k | T result; | 182 | 354k | const auto [first_nonmatching, error_condition] = std::from_chars(str.data(), str.data() + str.size(), result); | 183 | 354k | if (first_nonmatching != str.data() + str.size() || error_condition != std::errc{}) { Branch (183:9): [True: 0, False: 354k]
Branch (183:57): [True: 0, False: 354k]
| 184 | 0 | return std::nullopt; | 185 | 0 | } | 186 | 354k | return result; | 187 | 354k | } |
Unexecuted instantiation: std::optional<int> ToIntegral<int>(std::basic_string_view<char, std::char_traits<char> >) Unexecuted instantiation: std::optional<long> ToIntegral<long>(std::basic_string_view<char, std::char_traits<char> >) Unexecuted instantiation: std::optional<unsigned char> ToIntegral<unsigned char>(std::basic_string_view<char, std::char_traits<char> >) |
188 | | |
189 | | /** |
190 | | * Format a paragraph of text to a fixed width, adding spaces for |
191 | | * indentation to any added line. |
192 | | */ |
193 | | std::string FormatParagraph(std::string_view in, size_t width = 79, size_t indent = 0); |
194 | | |
195 | | /** |
196 | | * Timing-attack-resistant comparison. |
197 | | * Takes time proportional to length |
198 | | * of first argument. |
199 | | */ |
200 | | template <typename T> |
201 | | bool TimingResistantEqual(const T& a, const T& b) |
202 | 4.71M | { |
203 | 4.71M | if (b.size() == 0) return a.size() == 0; Branch (203:9): [True: 0, False: 2.35M]
Branch (203:9): [True: 0, False: 2.35M]
|
204 | 4.71M | size_t accumulator = a.size() ^ b.size(); |
205 | 179M | for (size_t i = 0; i < a.size(); i++) Branch (205:24): [True: 23.5M, False: 2.35M]
Branch (205:24): [True: 150M, False: 2.35M]
|
206 | 174M | accumulator |= size_t(a[i] ^ b[i%b.size()]); |
207 | 4.71M | return accumulator == 0; |
208 | 4.71M | } 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 | 202 | 2.35M | { | 203 | 2.35M | if (b.size() == 0) return a.size() == 0; Branch (203:9): [True: 0, False: 2.35M]
| 204 | 2.35M | size_t accumulator = a.size() ^ b.size(); | 205 | 25.9M | for (size_t i = 0; i < a.size(); i++) Branch (205:24): [True: 23.5M, False: 2.35M]
| 206 | 23.5M | accumulator |= size_t(a[i] ^ b[i%b.size()]); | 207 | 2.35M | return accumulator == 0; | 208 | 2.35M | } |
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 | 202 | 2.35M | { | 203 | 2.35M | if (b.size() == 0) return a.size() == 0; Branch (203:9): [True: 0, False: 2.35M]
| 204 | 2.35M | size_t accumulator = a.size() ^ b.size(); | 205 | 153M | for (size_t i = 0; i < a.size(); i++) Branch (205:24): [True: 150M, False: 2.35M]
| 206 | 150M | accumulator |= size_t(a[i] ^ b[i%b.size()]); | 207 | 2.35M | return accumulator == 0; | 208 | 2.35M | } |
|
209 | | |
210 | | /** Parse number as fixed point according to JSON number syntax. |
211 | | * @returns true on success, false on error. |
212 | | * @note The result must be in the range (-10^18,10^18), otherwise an overflow error will trigger. |
213 | | */ |
214 | | [[nodiscard]] bool ParseFixedPoint(std::string_view, int decimals, int64_t *amount_out); |
215 | | |
216 | | namespace { |
217 | | /** Helper class for the default infn argument to ConvertBits (just returns the input). */ |
218 | | struct IntIdentity |
219 | | { |
220 | 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: checks.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: net_processing.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: eviction.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: interfaces.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: 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: txreconciliation.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: fees.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: 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: 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: 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: txorphanage.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: validationinterface.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: versionbits.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: banman.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: bip324.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: blockencodings.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: blockfilter.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: tx_verify.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: dbwrapper.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: headerssync.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: httprpc.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: httpserver.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: i2p.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: base.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: blockfilterindex.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: coinstatsindex.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: txindex.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: chain.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: coinstats.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: disconnected_transactions.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: coin.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: psbt.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: sigcache.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: scriptpubkeyman.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: spend.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: walletdb.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: walletutil.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: coincontrol.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: coinselection.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: crypter.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: db.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: external_signer_scriptpubkeyman.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: feebumper.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: addresses.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: backup.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: coins.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: encrypt.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: transactions.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: util.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: sqlite.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_read.cpp:(anonymous namespace)::IntIdentity::operator()(int) const Unexecuted instantiation: core_write.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: 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: run_command.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: 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: 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 |
221 | | }; |
222 | | |
223 | | } // namespace |
224 | | |
225 | | /** Convert from one power-of-2 number base to another. */ |
226 | | template<int frombits, int tobits, bool pad, typename O, typename It, typename I = IntIdentity> |
227 | 2.35M | bool ConvertBits(O outfn, It it, It end, I infn = {}) { |
228 | 2.35M | size_t acc = 0; |
229 | 2.35M | size_t bits = 0; |
230 | 2.35M | constexpr size_t maxv = (1 << tobits) - 1; |
231 | 2.35M | constexpr size_t max_acc = (1 << (frombits + tobits - 1)) - 1; |
232 | 238M | while (it != end) { Branch (232:12): [True: 0, False: 0]
Branch (232:12): [True: 0, False: 0]
Branch (232:12): [True: 0, False: 0]
Branch (232:12): [True: 0, False: 0]
Branch (232:12): [True: 0, False: 0]
Branch (232:12): [True: 0, False: 0]
Branch (232:12): [True: 235M, False: 2.35M]
Branch (232:12): [True: 0, False: 0]
Branch (232:12): [True: 0, False: 0]
|
233 | 235M | int v = infn(*it); |
234 | 235M | if (v < 0) return false; Branch (234:13): [True: 0, False: 0]
Branch (234:13): [True: 0, False: 0]
Branch (234:13): [True: 0, False: 0]
Branch (234:13): [True: 0, False: 0]
Branch (234:13): [True: 0, False: 0]
Branch (234:13): [True: 0, False: 0]
Branch (234:13): [True: 0, False: 235M]
Branch (234:13): [True: 0, False: 0]
Branch (234:13): [True: 0, False: 0]
|
235 | 235M | acc = ((acc << frombits) | v) & max_acc; |
236 | 235M | bits += frombits; |
237 | 412M | while (bits >= tobits) { Branch (237:16): [True: 0, False: 0]
Branch (237:16): [True: 0, False: 0]
Branch (237:16): [True: 0, False: 0]
Branch (237:16): [True: 0, False: 0]
Branch (237:16): [True: 0, False: 0]
Branch (237:16): [True: 0, False: 0]
Branch (237:16): [True: 176M, False: 235M]
Branch (237:16): [True: 0, False: 0]
Branch (237:16): [True: 0, False: 0]
|
238 | 176M | bits -= tobits; |
239 | 176M | outfn((acc >> bits) & maxv); |
240 | 176M | } |
241 | 235M | ++it; |
242 | 235M | } |
243 | 2.35M | if (pad) { Branch (243:9): [Folded - Ignored]
Branch (243:9): [Folded - Ignored]
Branch (243:9): [Folded - Ignored]
Branch (243:9): [Folded - Ignored]
Branch (243:9): [Folded - Ignored]
Branch (243:9): [Folded - Ignored]
Branch (243:9): [Folded - Ignored]
Branch (243:9): [Folded - Ignored]
Branch (243:9): [Folded - Ignored]
|
244 | 0 | if (bits) outfn((acc << (tobits - bits)) & maxv); Branch (244:13): [True: 0, False: 0]
Branch (244:13): [True: 0, False: 0]
Branch (244:13): [True: 0, False: 0]
Branch (244:13): [True: 0, False: 0]
Branch (244:13): [True: 0, False: 0]
Branch (244:13): [True: 0, False: 0]
Branch (244:13): [True: 0, False: 0]
Branch (244:13): [True: 0, False: 0]
Branch (244:13): [True: 0, False: 0]
|
245 | 2.35M | } else if (bits >= frombits || ((acc << (tobits - bits)) & maxv)) { Branch (245:16): [True: 0, False: 0]
Branch (245:36): [True: 0, False: 0]
Branch (245:16): [True: 0, False: 0]
Branch (245:36): [True: 0, False: 0]
Branch (245:16): [True: 0, False: 0]
Branch (245:36): [True: 0, False: 0]
Branch (245:16): [True: 0, False: 0]
Branch (245:36): [True: 0, False: 0]
Branch (245:16): [True: 0, False: 0]
Branch (245:36): [True: 0, False: 0]
Branch (245:16): [True: 0, False: 0]
Branch (245:36): [True: 0, False: 0]
Branch (245:16): [True: 0, False: 2.35M]
Branch (245:36): [True: 0, False: 2.35M]
Branch (245:16): [True: 0, False: 0]
Branch (245:36): [True: 0, False: 0]
Branch (245:16): [True: 0, False: 0]
Branch (245:36): [True: 0, False: 0]
|
246 | 0 | return false; |
247 | 0 | } |
248 | 2.35M | return true; |
249 | 2.35M | } 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 | 227 | 2.35M | bool ConvertBits(O outfn, It it, It end, I infn = {}) { | 228 | 2.35M | size_t acc = 0; | 229 | 2.35M | size_t bits = 0; | 230 | 2.35M | constexpr size_t maxv = (1 << tobits) - 1; | 231 | 2.35M | constexpr size_t max_acc = (1 << (frombits + tobits - 1)) - 1; | 232 | 238M | while (it != end) { Branch (232:12): [True: 235M, False: 2.35M]
| 233 | 235M | int v = infn(*it); | 234 | 235M | if (v < 0) return false; Branch (234:13): [True: 0, False: 235M]
| 235 | 235M | acc = ((acc << frombits) | v) & max_acc; | 236 | 235M | bits += frombits; | 237 | 412M | while (bits >= tobits) { Branch (237:16): [True: 176M, False: 235M]
| 238 | 176M | bits -= tobits; | 239 | 176M | outfn((acc >> bits) & maxv); | 240 | 176M | } | 241 | 235M | ++it; | 242 | 235M | } | 243 | 2.35M | if (pad) { Branch (243:9): [Folded - Ignored]
| 244 | 0 | if (bits) outfn((acc << (tobits - bits)) & maxv); Branch (244:13): [True: 0, False: 0]
| 245 | 2.35M | } else if (bits >= frombits || ((acc << (tobits - bits)) & maxv)) { Branch (245:16): [True: 0, False: 2.35M]
Branch (245:36): [True: 0, False: 2.35M]
| 246 | 0 | return false; | 247 | 0 | } | 248 | 2.35M | return true; | 249 | 2.35M | } |
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) |
250 | | |
251 | | /** |
252 | | * Converts the given character to its lowercase equivalent. |
253 | | * This function is locale independent. It only converts uppercase |
254 | | * characters in the standard 7-bit ASCII range. |
255 | | * This is a feature, not a limitation. |
256 | | * |
257 | | * @param[in] c the character to convert to lowercase. |
258 | | * @return the lowercase equivalent of c; or the argument |
259 | | * if no conversion is possible. |
260 | | */ |
261 | | constexpr char ToLower(char c) |
262 | 0 | { |
263 | 0 | return (c >= 'A' && c <= 'Z' ? (c - 'A') + 'a' : c); Branch (263:13): [True: 0, False: 0]
Branch (263:25): [True: 0, False: 0]
|
264 | 0 | } |
265 | | |
266 | | /** |
267 | | * Returns the lowercase equivalent of the given string. |
268 | | * This function is locale independent. It only converts uppercase |
269 | | * characters in the standard 7-bit ASCII range. |
270 | | * This is a feature, not a limitation. |
271 | | * |
272 | | * @param[in] str the string to convert to lowercase. |
273 | | * @returns lowercased equivalent of str |
274 | | */ |
275 | | std::string ToLower(std::string_view str); |
276 | | |
277 | | /** |
278 | | * Converts the given character to its uppercase equivalent. |
279 | | * This function is locale independent. It only converts lowercase |
280 | | * characters in the standard 7-bit ASCII range. |
281 | | * This is a feature, not a limitation. |
282 | | * |
283 | | * @param[in] c the character to convert to uppercase. |
284 | | * @return the uppercase equivalent of c; or the argument |
285 | | * if no conversion is possible. |
286 | | */ |
287 | | constexpr char ToUpper(char c) |
288 | 0 | { |
289 | 0 | return (c >= 'a' && c <= 'z' ? (c - 'a') + 'A' : c); Branch (289:13): [True: 0, False: 0]
Branch (289:25): [True: 0, False: 0]
|
290 | 0 | } |
291 | | |
292 | | /** |
293 | | * Returns the uppercase equivalent of the given string. |
294 | | * This function is locale independent. It only converts lowercase |
295 | | * characters in the standard 7-bit ASCII range. |
296 | | * This is a feature, not a limitation. |
297 | | * |
298 | | * @param[in] str the string to convert to uppercase. |
299 | | * @returns UPPERCASED EQUIVALENT OF str |
300 | | */ |
301 | | std::string ToUpper(std::string_view str); |
302 | | |
303 | | /** |
304 | | * Capitalizes the first character of the given string. |
305 | | * This function is locale independent. It only converts lowercase |
306 | | * characters in the standard 7-bit ASCII range. |
307 | | * This is a feature, not a limitation. |
308 | | * |
309 | | * @param[in] str the string to capitalize. |
310 | | * @returns string with the first letter capitalized. |
311 | | */ |
312 | | std::string Capitalize(std::string str); |
313 | | |
314 | | /** |
315 | | * Parse a string with suffix unit [k|K|m|M|g|G|t|T]. |
316 | | * Must be a whole integer, fractions not allowed (0.5t), no whitespace or +- |
317 | | * Lowercase units are 1000 base. Uppercase units are 1024 base. |
318 | | * Examples: 2m,27M,19g,41T |
319 | | * |
320 | | * @param[in] str the string to convert into bytes |
321 | | * @param[in] default_multiplier if no unit is found in str use this unit |
322 | | * @returns optional uint64_t bytes from str or nullopt |
323 | | * if ToIntegral is false, str is empty, trailing whitespace or overflow |
324 | | */ |
325 | | std::optional<uint64_t> ParseByteUnits(std::string_view str, ByteUnit default_multiplier); |
326 | | |
327 | | namespace util { |
328 | | /** consteval version of HexDigit() without the lookup table. */ |
329 | | consteval uint8_t ConstevalHexDigit(const char c) |
330 | | { |
331 | | if (c >= '0' && c <= '9') return c - '0'; |
332 | | if (c >= 'a' && c <= 'f') return c - 'a' + 0xa; |
333 | | |
334 | | throw "Only lowercase hex digits are allowed, for consistency"; |
335 | | } |
336 | | |
337 | | namespace detail { |
338 | | template <size_t N> |
339 | | struct Hex { |
340 | | std::array<std::byte, N / 2> bytes{}; |
341 | | consteval Hex(const char (&hex_str)[N]) |
342 | | // 2 hex digits required per byte + implicit null terminator |
343 | | requires(N % 2 == 1) |
344 | | { |
345 | | if (hex_str[N - 1]) throw "null terminator required"; |
346 | | for (std::size_t i = 0; i < bytes.size(); ++i) { |
347 | | bytes[i] = static_cast<std::byte>( |
348 | | (ConstevalHexDigit(hex_str[2 * i]) << 4) | |
349 | | ConstevalHexDigit(hex_str[2 * i + 1])); |
350 | | } |
351 | | } |
352 | | }; |
353 | | } // namespace detail |
354 | | |
355 | | /** |
356 | | * ""_hex is a compile-time user-defined literal returning a |
357 | | * `std::array<std::byte>`, equivalent to ParseHex(). Variants provided: |
358 | | * |
359 | | * - ""_hex_v: Returns `std::vector<std::byte>`, useful for heap allocation or |
360 | | * variable-length serialization. |
361 | | * |
362 | | * - ""_hex_u8: Returns `std::array<uint8_t>`, for cases where `std::byte` is |
363 | | * incompatible. |
364 | | * |
365 | | * - ""_hex_v_u8: Returns `std::vector<uint8_t>`, combining heap allocation with |
366 | | * `uint8_t`. |
367 | | * |
368 | | * @warning It could be necessary to use vector instead of array variants when |
369 | | * serializing, or vice versa, because vectors are assumed to be variable- |
370 | | * length and serialized with a size prefix, while arrays are considered fixed |
371 | | * length and serialized with no prefix. |
372 | | * |
373 | | * @warning It may be preferable to use vector variants to save stack space when |
374 | | * declaring local variables if hex strings are large. Alternatively variables |
375 | | * could be declared constexpr to avoid using stack space. |
376 | | * |
377 | | * @warning Avoid `uint8_t` variants when not necessary, as the codebase |
378 | | * migrates to use `std::byte` instead of `unsigned char` and `uint8_t`. |
379 | | * |
380 | | * @note One reason ""_hex uses `std::array` instead of `std::vector` like |
381 | | * ParseHex() does is because heap-based containers cannot cross the compile- |
382 | | * time/runtime barrier. |
383 | | */ |
384 | | inline namespace hex_literals { |
385 | | |
386 | | template <util::detail::Hex str> |
387 | 66.5k | 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 _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 Line | Count | Source | 387 | 55.4k | constexpr auto operator""_hex() { return str.bytes; } |
_ZN4util12hex_literalsli4_hexITnNS_6detail3HexEXtlNS3_ILm67EEEEEEEDav Line | Count | Source | 387 | 11.0k | constexpr auto operator""_hex() { return str.bytes; } |
|
388 | | |
389 | | template <util::detail::Hex str> |
390 | 0 | constexpr auto operator""_hex_u8() { return std::bit_cast<std::array<uint8_t, str.bytes.size()>>(str.bytes); } |
391 | | |
392 | | template <util::detail::Hex str> |
393 | | constexpr auto operator""_hex_v() { return std::vector<std::byte>{str.bytes.begin(), str.bytes.end()}; } |
394 | | |
395 | | template <util::detail::Hex str> |
396 | 11.0k | inline auto operator""_hex_v_u8() { return std::vector<uint8_t>{UCharCast(str.bytes.data()), UCharCast(str.bytes.data() + str.bytes.size())}; } |
397 | | |
398 | | } // inline namespace hex_literals |
399 | | } // namespace util |
400 | | |
401 | | #endif // BITCOIN_UTIL_STRENCODINGS_H |