If base is 0 the string should be prefixed by 0x, 0d, 0o, or 0b to allow the function to automatically determine the radix
| 172 | |
| 173 | // If base is 0 the string should be prefixed by 0x, 0d, 0o, or 0b to allow the function to automatically determine the radix |
| 174 | asQWORD asStringScanUInt64(const char *string, int base, size_t *numScanned, bool *overflow) |
| 175 | { |
| 176 | asASSERT(base == 10 || base == 16 || base == 0); |
| 177 | |
| 178 | if (overflow) |
| 179 | *overflow = false; |
| 180 | |
| 181 | const char *end = string; |
| 182 | |
| 183 | static const asQWORD QWORD_MAX = (~asQWORD(0)); |
| 184 | |
| 185 | asQWORD res = 0; |
| 186 | if( base == 10 ) |
| 187 | { |
| 188 | while( *end >= '0' && *end <= '9' ) |
| 189 | { |
| 190 | if( overflow && ((res > QWORD_MAX / 10) || ((asUINT(*end - '0') > (QWORD_MAX - (QWORD_MAX / 10) * 10)) && res == QWORD_MAX / 10)) ) |
| 191 | *overflow = true; |
| 192 | res *= 10; |
| 193 | res += *end++ - '0'; |
| 194 | } |
| 195 | } |
| 196 | else |
| 197 | { |
| 198 | if( base == 0 && string[0] == '0') |
| 199 | { |
| 200 | // Determine the radix from the prefix |
| 201 | switch( string[1] ) |
| 202 | { |
| 203 | case 'b': case 'B': base = 2; break; |
| 204 | case 'o': case 'O': base = 8; break; |
| 205 | case 'd': case 'D': base = 10; break; |
| 206 | case 'x': case 'X': base = 16; break; |
| 207 | } |
| 208 | end += 2; |
| 209 | } |
| 210 | |
| 211 | asASSERT( base ); |
| 212 | |
| 213 | if( base ) |
| 214 | { |
| 215 | for (int nbr; (nbr = asCharToNbr(*end, base)) >= 0; end++) |
| 216 | { |
| 217 | if (overflow && ((res > QWORD_MAX / base) || ((asUINT(nbr) > (QWORD_MAX - (QWORD_MAX / base) * base)) && res == QWORD_MAX / base)) ) |
| 218 | *overflow = true; |
| 219 | |
| 220 | res = res * base + nbr; |
| 221 | } |
| 222 | } |
| 223 | } |
| 224 | |
| 225 | if( numScanned ) |
| 226 | *numScanned = end - string; |
| 227 | |
| 228 | return res; |
| 229 | } |
| 230 | |
| 231 | // |
no test coverage detected