in src/crt_abstractions.c [307:406]
unsigned long long strtoull_s(const char* nptr, char** endptr, int base)
{
unsigned long long result = 0ULL;
bool validStr = true;
char* runner = (char*)nptr;
bool isNegative = false;
int digitVal;
/*Codes_SRS_CRT_ABSTRACTIONS_21_005: [The strtoull_s must convert number using base 2 to 36.]*/
/*Codes_SRS_CRT_ABSTRACTIONS_21_012: [If the subject sequence is empty or does not have the expected form, the strtoull_s must not perform any conversion; the value of nptr is stored in the object pointed to by endptr, provided that endptr is not a NULL pointer.]*/
/*Codes_SRS_CRT_ABSTRACTIONS_21_013: [If no conversion could be performed, the strtoull_s returns the value 0L.]*/
/*Codes_SRS_CRT_ABSTRACTIONS_21_035: [If the nptr is NULL, the strtoull_s must **not** perform any conversion and must returns 0L; endptr must receive NULL, provided that endptr is not a NULL pointer.]*/
if (((base >= 2) || (base == 0)) && (base <= 36) && (runner != NULL))
{
/*Codes_SRS_CRT_ABSTRACTIONS_21_011: [The valid sequence starts after the first non-white-space character, followed by an optional positive or negative sign, a number or a letter(depending of the base).]*/
/*Codes_SRS_CRT_ABSTRACTIONS_21_010: [The white-space must be one of the characters ' ', '\f', '\n', '\r', '\t', '\v'.]*/
while (IS_SPACE(*runner))
{
runner++;
}
if ((*runner) == '+')
{
runner++;
}
else if ((*runner) == '-')
{
/*Codes_SRS_CRT_ABSTRACTIONS_21_038: [If the subject sequence starts with a negative sign, the strtoull_s will convert it to the posive representation of the negative value.]*/
isNegative = true;
runner++;
}
if ((*runner) == '0')
{
if ((*(runner+1) == 'x') || (*(runner+1) == 'X'))
{
/*Codes_SRS_CRT_ABSTRACTIONS_21_008: [If the base is 0 and '0x' or '0X' precedes the number, strtoull_s must convert to a hexadecimal (base 16).]*/
/* hexadecimal... */
if ((base == 0) || (base == 16))
{
base = 16;
runner += 2;
}
}
else if((base == 0) || (base == 8))
{
/*Codes_SRS_CRT_ABSTRACTIONS_21_009: [If the base is 0 and '0' precedes the number, strtoull_s must convert to an octal (base 8).]*/
/* octal... */
base = 8;
runner++;
}
}
if(base == 0)
{
/*Codes_SRS_CRT_ABSTRACTIONS_21_007: [If the base is 0 and no special chars precedes the number, strtoull_s must convert to a decimal (base 10).]*/
/* decimal... */
base = 10;
}
digitVal = DIGIT_VAL(*runner);
if (validStr && IN_BASE_RANGE(digitVal, base))
{
errno = 0;
do
{
if (((ULLONG_MAX - digitVal) / base) < result)
{
/*Codes_SRS_CRT_ABSTRACTIONS_21_014: [If the correct value is outside the range, the strtoull_s returns the value ULLONG_MAX, and errno will receive the value ERANGE.]*/
/* overflow... */
result = ULLONG_MAX;
errno = ERANGE;
}
else
{
result = result * base + digitVal;
}
runner++;
digitVal = DIGIT_VAL(*runner);
} while (IN_BASE_RANGE(digitVal, base));
}
else
{
runner = (char*)nptr;
}
}
/*Codes_SRS_CRT_ABSTRACTIONS_21_004: [The strtoull_s must return in endptr a final string of one or more unrecognized characters, including the terminating null character of the input string.]*/
if (endptr != NULL)
{
(*endptr) = (char*)runner;
}
/*Codes_SRS_CRT_ABSTRACTIONS_21_038: [If the subject sequence starts with a negative sign, the strtoull_s will convert it to the posive representation of the negative value.]*/
if (isNegative)
{
result = ULLONG_MAX - result + 1;
}
return result;
}