| 292 | // range error occurs. In this case value MAX(T)/MIN(T) is returned. |
| 293 | template<typename T> |
| 294 | inline bool StringToIntegerImpl(T *val, const char *const str, |
| 295 | const int base = 0, |
| 296 | const bool check_errno = true) { |
| 297 | // T is int64_t or uint64_T |
| 298 | FLATBUFFERS_ASSERT(str); |
| 299 | if (base <= 0) { |
| 300 | auto s = str; |
| 301 | while (*s && !is_digit(*s)) s++; |
| 302 | if (s[0] == '0' && is_alpha_char(s[1], 'X')) |
| 303 | return StringToIntegerImpl(val, str, 16, check_errno); |
| 304 | // if a prefix not match, try base=10 |
| 305 | return StringToIntegerImpl(val, str, 10, check_errno); |
| 306 | } else { |
| 307 | if (check_errno) errno = 0; // clear thread-local errno |
| 308 | auto endptr = str; |
| 309 | strtoval_impl(val, str, const_cast<char **>(&endptr), base); |
| 310 | if ((*endptr != '\0') || (endptr == str)) { |
| 311 | *val = 0; // erase partial result |
| 312 | return false; // invalid string |
| 313 | } |
| 314 | // errno is out-of-range, return MAX/MIN |
| 315 | if (check_errno && errno) return false; |
| 316 | return true; |
| 317 | } |
| 318 | } |
| 319 | |
| 320 | template<typename T> |
| 321 | inline bool StringToFloatImpl(T *val, const char *const str) { |
no test coverage detected