123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451 |
- //
- // Copyright (c) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE file in the project root for full license information.
- //
- /***
- *xtoa.c - convert integers/longs to ASCII string
- *
- *
- *Purpose:
- * The module has code to convert integers/longs to ASCII strings. See
- *
- *******************************************************************************/
- #ifdef _UNICODE
- #define xtox_s xtow_s
- #define _itox_s _itow_s
- #define _ltox_s _ltow_s
- #define _ultox_s _ultow_s
- #define x64tox_s x64tow_s
- #define _i64tox_s _i64tow_s
- #define _ui64tox_s _ui64tow_s
- #define xtox xtow
- #define _itox _itow
- #define _ltox _ltow
- #define _ultox _ultow
- #define x64tox x64tow
- #define _i64tox _i64tow
- #define _ui64tox _ui64tow
- #else /* _UNICODE */
- #define xtox_s xtoa_s
- #define _itox_s _itoa_s
- #define _ltox_s _ltoa_s
- #define _ultox_s _ultoa_s
- #define x64tox_s x64toa_s
- #define _i64tox_s _i64toa_s
- #define _ui64tox_s _ui64toa_s
- #define xtox xtoa
- #define _itox _itoa
- #define _ltox _ltoa
- #define _ultox _ultoa
- #define x64tox x64toa
- #define _i64tox _i64toa
- #define _ui64tox _ui64toa
- #endif /* _UNICODE */
- /***
- *char *_itoa_s, *_ltoa_s, *_ultoa_s(val, buf, sizeInTChars, radix) - convert binary int to ASCII
- * string
- *
- *Purpose:
- * Converts an int to a character string.
- *
- *Entry:
- * val - number to be converted (int, long or unsigned long)
- * char *buf - ptr to buffer to place result
- * size_t sizeInTChars - size of the destination buffer
- * int radix - base to convert into
- *
- *Exit:
- * Fills in space pointed to by buf with string result.
- * Returns the errno_t: err != 0 means that something went wrong, and
- * an empty string (buf[0] = 0) is returned.
- *
- *Exceptions:
- * Input parameters and buffer length are validated.
- * Refer to the validation section of the function.
- *
- *******************************************************************************/
- /* helper routine that does the main job. */
- #ifdef _SECURE_ITOA
- errno_t __stdcall xtox_s
- (
- unsigned long val,
- TCHAR *buf,
- size_t sizeInTChars,
- unsigned radix,
- int is_neg
- )
- #else /* _SECURE_ITOA */
- void __stdcall xtox
- (
- unsigned long val,
- TCHAR *buf,
- unsigned radix,
- int is_neg
- )
- #endif /* _SECURE_ITOA */
- {
- TCHAR *p; /* pointer to traverse string */
- TCHAR *firstdig; /* pointer to first digit */
- TCHAR temp; /* temp char */
- unsigned digval; /* value of digit */
- #ifdef _SECURE_ITOA
- size_t length; /* current length of the string */
- /* validation section */
- _VALIDATE_RETURN_ERRCODE(buf != NULL, EINVAL);
- _VALIDATE_RETURN_ERRCODE(sizeInTChars > 0, EINVAL);
- _RESET_STRING(buf, sizeInTChars);
- _VALIDATE_RETURN_ERRCODE(sizeInTChars > (size_t)(is_neg ? 2 : 1), ERANGE);
- _VALIDATE_RETURN_ERRCODE(2 <= radix && radix <= 36, EINVAL);
- length = 0;
- #endif /* _SECURE_ITOA */
- p = buf;
- if (is_neg) {
- /* negative, so output '-' and negate */
- *p++ = _T('-');
- #ifdef _SECURE_ITOA
- length++;
- #endif /* _SECURE_ITOA */
- val = (unsigned long)(-(long)val);
- }
- firstdig = p; /* save pointer to first digit */
- do {
- digval = (unsigned) (val % radix);
- val /= radix; /* get next digit */
- /* convert to ascii and store */
- if (digval > 9)
- *p++ = (TCHAR) (digval - 10 + _T('a')); /* a letter */
- else
- *p++ = (TCHAR) (digval + _T('0')); /* a digit */
- #ifndef _SECURE_ITOA
- } while (val > 0);
- #else /* _SECURE_ITOA */
- length++;
- } while (val > 0 && length < sizeInTChars);
- /* Check for buffer overrun */
- if (length >= sizeInTChars)
- {
- buf[0] = '\0';
- _VALIDATE_RETURN_ERRCODE(length < sizeInTChars, ERANGE);
- }
- #endif /* _SECURE_ITOA */
- /* We now have the digit of the number in the buffer, but in reverse
- order. Thus we reverse them now. */
- *p-- = _T('\0'); /* terminate string; p points to last digit */
- do {
- temp = *p;
- *p = *firstdig;
- *firstdig = temp; /* swap *p and *firstdig */
- --p;
- ++firstdig; /* advance to next two digits */
- } while (firstdig < p); /* repeat until halfway */
- #ifdef _SECURE_ITOA
- return 0;
- #endif /* _SECURE_ITOA */
- }
- /* Actual functions just call conversion helper with neg flag set correctly,
- and return pointer to buffer. */
- #ifdef _SECURE_ITOA
- errno_t __cdecl _itox_s (
- int val,
- TCHAR *buf,
- size_t sizeInTChars,
- int radix
- )
- {
- errno_t e = 0;
- if (radix == 10 && val < 0)
- e = xtox_s((unsigned long)val, buf, sizeInTChars, (unsigned)radix, 1);
- else
- e = xtox_s((unsigned long)(unsigned int)val, buf, sizeInTChars, (unsigned)radix, 0);
- return e;
- }
- errno_t __cdecl _ltox_s (
- long val,
- TCHAR *buf,
- size_t sizeInTChars,
- int radix
- )
- {
- return xtox_s((unsigned long)val, buf, sizeInTChars, (unsigned)radix, (radix == 10 && val < 0));
- }
- errno_t __cdecl _ultox_s (
- unsigned long val,
- TCHAR *buf,
- size_t sizeInTChars,
- int radix
- )
- {
- return xtox_s(val, buf, sizeInTChars, (unsigned)radix, 0);
- }
- #else /* _SECURE_ITOA */
- /***
- *char *_itoa, *_ltoa, *_ultoa(val, buf, radix) - convert binary int to ASCII
- * string
- *
- *Purpose:
- * Converts an int to a character string.
- *
- *Entry:
- * val - number to be converted (int, long or unsigned long)
- * int radix - base to convert into
- * char *buf - ptr to buffer to place result
- *
- *Exit:
- * fills in space pointed to by buf with string result
- * returns a pointer to this buffer
- *
- *Exceptions:
- * Input parameters are validated. The buffer is assumed to be big enough to
- * contain the string. Refer to the validation section of the function.
- *
- *******************************************************************************/
- /* Actual functions just call conversion helper with neg flag set correctly,
- and return pointer to buffer. */
- TCHAR * __cdecl _itox (
- int val,
- TCHAR *buf,
- int radix
- )
- {
- if (radix == 10 && val < 0)
- xtox((unsigned long)val, buf, radix, 1);
- else
- xtox((unsigned long)(unsigned int)val, buf, radix, 0);
- return buf;
- }
- TCHAR * __cdecl _ltox (
- long val,
- TCHAR *buf,
- int radix
- )
- {
- xtox((unsigned long)val, buf, radix, (radix == 10 && val < 0));
- return buf;
- }
- TCHAR * __cdecl _ultox (
- unsigned long val,
- TCHAR *buf,
- int radix
- )
- {
- xtox(val, buf, radix, 0);
- return buf;
- }
- #endif /* _SECURE_ITOA */
- #ifndef _NO_INT64
- /***
- *char *_i64toa_s(val, buf, sizeInTChars, radix) - convert binary int to ASCII
- * string
- *
- *Purpose:
- * Converts an int64 to a character string.
- *
- *Entry:
- * val - number to be converted
- * char *buf - ptr to buffer to place result
- * size_t sizeInTChars - size of the destination buffer
- * int radix - base to convert into
- *
- *Exit:
- * Fills in space pointed to by buf with string result.
- * Returns the errno_t: err != 0 means that something went wrong, and
- * an empty string (buf[0] = 0) is returned.
- *
- *Exceptions:
- * Input parameters and buffer length are validated.
- * Refer to the validation section of the function.
- *
- *******************************************************************************/
- #ifdef _SECURE_ITOA
- errno_t __fastcall x64tox_s
- (/* stdcall is faster and smaller... Might as well use it for the helper. */
- unsigned __int64 val,
- TCHAR *buf,
- size_t sizeInTChars,
- unsigned radix,
- int is_neg
- )
- #else /* _SECURE_ITOA */
- void __fastcall x64tox
- (/* stdcall is faster and smaller... Might as well use it for the helper. */
- unsigned __int64 val,
- TCHAR *buf,
- unsigned radix,
- int is_neg
- )
- #endif /* _SECURE_ITOA */
- {
- TCHAR *p; /* pointer to traverse string */
- TCHAR *firstdig; /* pointer to first digit */
- TCHAR temp; /* temp char */
- unsigned digval; /* value of digit */
- #ifdef _SECURE_ITOA
- size_t length; /* current length of the string */
- /* validation section */
- _VALIDATE_RETURN_ERRCODE(buf != NULL, EINVAL);
- _VALIDATE_RETURN_ERRCODE(sizeInTChars > 0, EINVAL);
- _RESET_STRING(buf, sizeInTChars);
- _VALIDATE_RETURN_ERRCODE(sizeInTChars > (size_t)(is_neg ? 2 : 1), ERANGE);
- _VALIDATE_RETURN_ERRCODE(2 <= radix && radix <= 36, EINVAL);
- length = 0;
- #endif /* _SECURE_ITOA */
- p = buf;
- if ( is_neg )
- {
- *p++ = _T('-'); /* negative, so output '-' and negate */
- #ifdef _SECURE_ITOA
- length++;
- #endif /* _SECURE_ITOA */
- val = (unsigned __int64)(-(__int64)val);
- }
- firstdig = p; /* save pointer to first digit */
- do {
- digval = (unsigned) (val % radix);
- val /= radix; /* get next digit */
- /* convert to ascii and store */
- if (digval > 9)
- *p++ = (TCHAR) (digval - 10 + _T('a')); /* a letter */
- else
- *p++ = (TCHAR) (digval + _T('0')); /* a digit */
- #ifndef _SECURE_ITOA
- } while (val > 0);
- #else /* _SECURE_ITOA */
- length++;
- } while (val > 0 && length < sizeInTChars);
- /* Check for buffer overrun */
- if (length >= sizeInTChars)
- {
- buf[0] = '\0';
- _VALIDATE_RETURN_ERRCODE(length < sizeInTChars, ERANGE);
- }
- #endif /* _SECURE_ITOA */
- /* We now have the digit of the number in the buffer, but in reverse
- order. Thus we reverse them now. */
- *p-- = _T('\0'); /* terminate string; p points to last digit */
- do {
- temp = *p;
- *p = *firstdig;
- *firstdig = temp; /* swap *p and *firstdig */
- --p;
- ++firstdig; /* advance to next two digits */
- } while (firstdig < p); /* repeat until halfway */
- #ifdef _SECURE_ITOA
- return 0;
- #endif /* _SECURE_ITOA */
- }
- #ifdef _SECURE_ITOA
- /* Actual functions just call conversion helper with neg flag set correctly,
- and return pointer to buffer. */
- errno_t __cdecl _i64tox_s (
- long long val,
- TCHAR *buf,
- size_t sizeInTChars,
- int radix
- )
- {
- return x64tox_s((unsigned __int64)val, buf, sizeInTChars, (unsigned)radix, (radix == 10 && val < 0));
- }
- errno_t __cdecl _ui64tox_s (
- unsigned long long val,
- TCHAR *buf,
- size_t sizeInTChars,
- int radix
- )
- {
- return x64tox_s(val, buf, sizeInTChars, (unsigned)radix, 0);
- }
- #else /* _SECURE_ITOA */
- /***
- *char *_i64toa(val, buf, radix) - convert binary int to ASCII
- * string
- *
- *Purpose:
- * Converts an int64 to a character string.
- *
- *Entry:
- * val - number to be converted
- * int radix - base to convert into
- * char *buf - ptr to buffer to place result
- *
- *Exit:
- * fills in space pointed to by buf with string result
- * returns a pointer to this buffer
- *
- *Exceptions:
- * Input parameters are validated. The buffer is assumed to be big enough to
- * contain the string. Refer to the validation section of the function.
- *
- *******************************************************************************/
- /* Actual functions just call conversion helper with neg flag set correctly,
- and return pointer to buffer. */
- TCHAR * __cdecl _i64tox (
- __int64 val,
- TCHAR *buf,
- int radix
- )
- {
- x64tox((unsigned __int64)val, buf, radix, (radix == 10 && val < 0));
- return buf;
- }
- TCHAR * __cdecl _ui64tox (
- unsigned __int64 val,
- TCHAR *buf,
- int radix
- )
- {
- x64tox(val, buf, radix, 0);
- return buf;
- }
- #endif /* _SECURE_ITOA */
- #endif /* _NO_INT64 */
|