Branch data Line data Source code
# 1 : : // Copyright (c) 2009-2010 Satoshi Nakamoto
# 2 : : // Copyright (c) 2009-2020 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 <attributes.h>
# 13 : : #include <span.h>
# 14 : :
# 15 : : #include <cstdint>
# 16 : : #include <iterator>
# 17 : : #include <string>
# 18 : : #include <vector>
# 19 : :
# 20 : : /** Used by SanitizeString() */
# 21 : : enum SafeChars
# 22 : : {
# 23 : : SAFE_CHARS_DEFAULT, //!< The full set of allowed chars
# 24 : : SAFE_CHARS_UA_COMMENT, //!< BIP-0014 subset
# 25 : : SAFE_CHARS_FILENAME, //!< Chars allowed in filenames
# 26 : : SAFE_CHARS_URI, //!< Chars allowed in URIs (RFC 3986)
# 27 : : };
# 28 : :
# 29 : : /**
# 30 : : * Remove unsafe chars. Safe chars chosen to allow simple messages/URLs/email
# 31 : : * addresses, but avoid anything even possibly remotely dangerous like & or >
# 32 : : * @param[in] str The string to sanitize
# 33 : : * @param[in] rule The set of safe chars to choose (default: least restrictive)
# 34 : : * @return A new string without unsafe chars
# 35 : : */
# 36 : : std::string SanitizeString(const std::string& str, int rule = SAFE_CHARS_DEFAULT);
# 37 : : std::vector<unsigned char> ParseHex(const char* psz);
# 38 : : std::vector<unsigned char> ParseHex(const std::string& str);
# 39 : : signed char HexDigit(char c);
# 40 : : /* Returns true if each character in str is a hex character, and has an even
# 41 : : * number of hex digits.*/
# 42 : : bool IsHex(const std::string& str);
# 43 : : /**
# 44 : : * Return true if the string is a hex number, optionally prefixed with "0x"
# 45 : : */
# 46 : : bool IsHexNumber(const std::string& str);
# 47 : : std::vector<unsigned char> DecodeBase64(const char* p, bool* pf_invalid = nullptr);
# 48 : : std::string DecodeBase64(const std::string& str, bool* pf_invalid = nullptr);
# 49 : : std::string EncodeBase64(Span<const unsigned char> input);
# 50 : : std::string EncodeBase64(const std::string& str);
# 51 : : std::vector<unsigned char> DecodeBase32(const char* p, bool* pf_invalid = nullptr);
# 52 : : std::string DecodeBase32(const std::string& str, bool* pf_invalid = nullptr);
# 53 : :
# 54 : : /**
# 55 : : * Base32 encode.
# 56 : : * If `pad` is true, then the output will be padded with '=' so that its length
# 57 : : * is a multiple of 8.
# 58 : : */
# 59 : : std::string EncodeBase32(Span<const unsigned char> input, bool pad = true);
# 60 : :
# 61 : : /**
# 62 : : * Base32 encode.
# 63 : : * If `pad` is true, then the output will be padded with '=' so that its length
# 64 : : * is a multiple of 8.
# 65 : : */
# 66 : : std::string EncodeBase32(const std::string& str, bool pad = true);
# 67 : :
# 68 : : void SplitHostPort(std::string in, uint16_t& portOut, std::string& hostOut);
# 69 : : int64_t atoi64(const std::string& str);
# 70 : : int atoi(const std::string& str);
# 71 : :
# 72 : : /**
# 73 : : * Tests if the given character is a decimal digit.
# 74 : : * @param[in] c character to test
# 75 : : * @return true if the argument is a decimal digit; otherwise false.
# 76 : : */
# 77 : : constexpr bool IsDigit(char c)
# 78 : 610185 : {
# 79 [ + + ][ + + ]: 610185 : return c >= '0' && c <= '9';
# 80 : 610185 : }
# 81 : :
# 82 : : /**
# 83 : : * Tests if the given character is a whitespace character. The whitespace characters
# 84 : : * are: space, form-feed ('\f'), newline ('\n'), carriage return ('\r'), horizontal
# 85 : : * tab ('\t'), and vertical tab ('\v').
# 86 : : *
# 87 : : * This function is locale independent. Under the C locale this function gives the
# 88 : : * same result as std::isspace.
# 89 : : *
# 90 : : * @param[in] c character to test
# 91 : : * @return true if the argument is a whitespace character; otherwise false
# 92 : : */
# 93 : 132648861 : constexpr inline bool IsSpace(char c) noexcept {
# 94 [ + + ][ + + ]: 132648861 : return c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v';
# [ + + ][ + + ]
# [ + + ][ + + ]
# 95 : 132648861 : }
# 96 : :
# 97 : : /**
# 98 : : * Convert string to signed 32-bit integer with strict parse error feedback.
# 99 : : * @returns true if the entire string could be parsed as valid integer,
# 100 : : * false if not the entire string could be parsed or when overflow or underflow occurred.
# 101 : : */
# 102 : : [[nodiscard]] bool ParseInt32(const std::string& str, int32_t *out);
# 103 : :
# 104 : : /**
# 105 : : * Convert string to signed 64-bit integer with strict parse error feedback.
# 106 : : * @returns true if the entire string could be parsed as valid integer,
# 107 : : * false if not the entire string could be parsed or when overflow or underflow occurred.
# 108 : : */
# 109 : : [[nodiscard]] bool ParseInt64(const std::string& str, int64_t *out);
# 110 : :
# 111 : : /**
# 112 : : * Convert decimal string to unsigned 8-bit integer with strict parse error feedback.
# 113 : : * @returns true if the entire string could be parsed as valid integer,
# 114 : : * false if not the entire string could be parsed or when overflow or underflow occurred.
# 115 : : */
# 116 : : [[nodiscard]] bool ParseUInt8(const std::string& str, uint8_t *out);
# 117 : :
# 118 : : /**
# 119 : : * Convert decimal string to unsigned 16-bit integer with strict parse error feedback.
# 120 : : * @returns true if the entire string could be parsed as valid integer,
# 121 : : * false if the entire string could not be parsed or if overflow or underflow occurred.
# 122 : : */
# 123 : : [[nodiscard]] bool ParseUInt16(const std::string& str, uint16_t* out);
# 124 : :
# 125 : : /**
# 126 : : * Convert decimal string to unsigned 32-bit integer with strict parse error feedback.
# 127 : : * @returns true if the entire string could be parsed as valid integer,
# 128 : : * false if not the entire string could be parsed or when overflow or underflow occurred.
# 129 : : */
# 130 : : [[nodiscard]] bool ParseUInt32(const std::string& str, uint32_t *out);
# 131 : :
# 132 : : /**
# 133 : : * Convert decimal string to unsigned 64-bit integer with strict parse error feedback.
# 134 : : * @returns true if the entire string could be parsed as valid integer,
# 135 : : * false if not the entire string could be parsed or when overflow or underflow occurred.
# 136 : : */
# 137 : : [[nodiscard]] bool ParseUInt64(const std::string& str, uint64_t *out);
# 138 : :
# 139 : : /**
# 140 : : * Convert string to double with strict parse error feedback.
# 141 : : * @returns true if the entire string could be parsed as valid double,
# 142 : : * false if not the entire string could be parsed or when overflow or underflow occurred.
# 143 : : */
# 144 : : [[nodiscard]] bool ParseDouble(const std::string& str, double *out);
# 145 : :
# 146 : : /**
# 147 : : * Convert a span of bytes to a lower-case hexadecimal string.
# 148 : : */
# 149 : : std::string HexStr(const Span<const uint8_t> s);
# 150 : 5 : inline std::string HexStr(const Span<const char> s) { return HexStr(MakeUCharSpan(s)); }
# 151 : :
# 152 : : /**
# 153 : : * Format a paragraph of text to a fixed width, adding spaces for
# 154 : : * indentation to any added line.
# 155 : : */
# 156 : : std::string FormatParagraph(const std::string& in, size_t width = 79, size_t indent = 0);
# 157 : :
# 158 : : /**
# 159 : : * Timing-attack-resistant comparison.
# 160 : : * Takes time proportional to length
# 161 : : * of first argument.
# 162 : : */
# 163 : : template <typename T>
# 164 : : bool TimingResistantEqual(const T& a, const T& b)
# 165 : 111342 : {
# 166 [ + + ]: 111342 : if (b.size() == 0) return a.size() == 0;
# 167 : 111338 : size_t accumulator = a.size() ^ b.size();
# 168 [ + + ]: 8454056 : for (size_t i = 0; i < a.size(); i++)
# 169 : 8342718 : accumulator |= a[i] ^ b[i%b.size()];
# 170 : 111338 : return accumulator == 0;
# 171 : 111338 : }
# 172 : :
# 173 : : /** Parse number as fixed point according to JSON number syntax.
# 174 : : * See https://json.org/number.gif
# 175 : : * @returns true on success, false on error.
# 176 : : * @note The result must be in the range (-10^18,10^18), otherwise an overflow error will trigger.
# 177 : : */
# 178 : : [[nodiscard]] bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out);
# 179 : :
# 180 : : /** Convert from one power-of-2 number base to another. */
# 181 : : template<int frombits, int tobits, bool pad, typename O, typename I>
# 182 : 199060 : bool ConvertBits(const O& outfn, I it, I end) {
# 183 : 199060 : size_t acc = 0;
# 184 : 199060 : size_t bits = 0;
# 185 : 199060 : constexpr size_t maxv = (1 << tobits) - 1;
# 186 : 199060 : constexpr size_t max_acc = (1 << (frombits + tobits - 1)) - 1;
# 187 [ + + ][ + + ]: 14499412 : while (it != end) {
# [ + + ][ + + ]
# [ + + ][ + + ]
# [ + + ][ + + ]
# 188 : 14300352 : acc = ((acc << frombits) | *it) & max_acc;
# 189 : 14300352 : bits += frombits;
# 190 [ + + ][ + + ]: 26238447 : while (bits >= tobits) {
# [ + + ][ + + ]
# [ + + ][ + + ]
# [ + + ][ + + ]
# 191 : 11938095 : bits -= tobits;
# 192 : 11938095 : outfn((acc >> bits) & maxv);
# 193 : 11938095 : }
# 194 : 14300352 : ++it;
# 195 : 14300352 : }
# 196 : 199060 : if (pad) {
# 197 [ + - ][ - + ]: 60144 : if (bits) outfn((acc << (tobits - bits)) & maxv);
# [ + + ][ + + ]
# [ # # ][ # # ]
# [ # # ][ + + ]
# 198 [ # # ][ + + ]: 138916 : } else if (bits >= frombits || ((acc << (tobits - bits)) & maxv)) {
# [ # # ][ # # ]
# [ # # ][ + + ]
# [ - + ][ # # ]
# [ + + ][ # # ]
# [ + + ][ # # ]
# [ # # ][ # # ]
# [ # # ][ + + ]
# 199 : 20 : return false;
# 200 : 20 : }
# 201 : 199040 : return true;
# 202 : 199040 : }
# 203 : :
# 204 : : /**
# 205 : : * Converts the given character to its lowercase equivalent.
# 206 : : * This function is locale independent. It only converts uppercase
# 207 : : * characters in the standard 7-bit ASCII range.
# 208 : : * This is a feature, not a limitation.
# 209 : : *
# 210 : : * @param[in] c the character to convert to lowercase.
# 211 : : * @return the lowercase equivalent of c; or the argument
# 212 : : * if no conversion is possible.
# 213 : : */
# 214 : : constexpr char ToLower(char c)
# 215 : 99676 : {
# 216 [ + + ][ + + ]: 99676 : return (c >= 'A' && c <= 'Z' ? (c - 'A') + 'a' : c);
# 217 : 99676 : }
# 218 : :
# 219 : : /**
# 220 : : * Returns the lowercase equivalent of the given string.
# 221 : : * This function is locale independent. It only converts uppercase
# 222 : : * characters in the standard 7-bit ASCII range.
# 223 : : * This is a feature, not a limitation.
# 224 : : *
# 225 : : * @param[in] str the string to convert to lowercase.
# 226 : : * @returns lowercased equivalent of str
# 227 : : */
# 228 : : std::string ToLower(const std::string& str);
# 229 : :
# 230 : : /**
# 231 : : * Converts the given character to its uppercase equivalent.
# 232 : : * This function is locale independent. It only converts lowercase
# 233 : : * characters in the standard 7-bit ASCII range.
# 234 : : * This is a feature, not a limitation.
# 235 : : *
# 236 : : * @param[in] c the character to convert to uppercase.
# 237 : : * @return the uppercase equivalent of c; or the argument
# 238 : : * if no conversion is possible.
# 239 : : */
# 240 : : constexpr char ToUpper(char c)
# 241 : 3940 : {
# 242 [ + + ][ + + ]: 3940 : return (c >= 'a' && c <= 'z' ? (c - 'a') + 'A' : c);
# 243 : 3940 : }
# 244 : :
# 245 : : /**
# 246 : : * Returns the uppercase equivalent of the given string.
# 247 : : * This function is locale independent. It only converts lowercase
# 248 : : * characters in the standard 7-bit ASCII range.
# 249 : : * This is a feature, not a limitation.
# 250 : : *
# 251 : : * @param[in] str the string to convert to uppercase.
# 252 : : * @returns UPPERCASED EQUIVALENT OF str
# 253 : : */
# 254 : : std::string ToUpper(const std::string& str);
# 255 : :
# 256 : : /**
# 257 : : * Capitalizes the first character of the given string.
# 258 : : * This function is locale independent. It only converts lowercase
# 259 : : * characters in the standard 7-bit ASCII range.
# 260 : : * This is a feature, not a limitation.
# 261 : : *
# 262 : : * @param[in] str the string to capitalize.
# 263 : : * @returns string with the first letter capitalized.
# 264 : : */
# 265 : : std::string Capitalize(std::string str);
# 266 : :
# 267 : : #endif // BITCOIN_UTIL_STRENCODINGS_H
|