| 2206 | } |
| 2207 | |
| 2208 | int64_t String::hex_to_int() const { |
| 2209 | int len = length(); |
| 2210 | if (len == 0) { |
| 2211 | return 0; |
| 2212 | } |
| 2213 | |
| 2214 | const char32_t *s = ptr(); |
| 2215 | |
| 2216 | int64_t sign = s[0] == '-' ? -1 : 1; |
| 2217 | |
| 2218 | if (sign < 0) { |
| 2219 | s++; |
| 2220 | } |
| 2221 | |
| 2222 | if (len > 2 && s[0] == '0' && lower_case(s[1]) == 'x') { |
| 2223 | s += 2; |
| 2224 | } |
| 2225 | |
| 2226 | int64_t hex = 0; |
| 2227 | |
| 2228 | while (*s) { |
| 2229 | char32_t c = lower_case(*s); |
| 2230 | int64_t n; |
| 2231 | if (is_digit(c)) { |
| 2232 | n = c - '0'; |
| 2233 | } else if (c >= 'a' && c <= 'f') { |
| 2234 | n = (c - 'a') + 10; |
| 2235 | } else { |
| 2236 | ERR_FAIL_V_MSG(0, vformat(R"(Invalid hexadecimal notation character "%c" (U+%04X) in string "%s".)", *s, static_cast<int32_t>(*s), *this)); |
| 2237 | } |
| 2238 | // Check for overflow/underflow, with special case to ensure INT64_MIN does not result in error |
| 2239 | bool overflow = ((hex > INT64_MAX / 16) && (sign == 1 || (sign == -1 && hex != (INT64_MAX >> 4) + 1))) || (sign == -1 && hex == (INT64_MAX >> 4) + 1 && c > '0'); |
| 2240 | ERR_FAIL_COND_V_MSG(overflow, sign == 1 ? INT64_MAX : INT64_MIN, "Cannot represent " + *this + " as a 64-bit signed integer, since the value is " + (sign == 1 ? "too large." : "too small.")); |
| 2241 | hex *= 16; |
| 2242 | hex += n; |
| 2243 | s++; |
| 2244 | } |
| 2245 | |
| 2246 | return hex * sign; |
| 2247 | } |
| 2248 | |
| 2249 | int64_t String::bin_to_int() const { |
| 2250 | int len = length(); |
no test coverage detected