Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

230 lines
6.3 KiB

  1. /***
  2. *xtoa.c - convert integers/longs to ASCII string
  3. *
  4. * Copyright (c) Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * The module has code to convert integers/longs to ASCII strings. See
  8. *
  9. *Revision History:
  10. * 06-06-89 PHG Module created, based on asm version
  11. * 03-06-90 GJF Fixed calling type, added #include <cruntime.h> and
  12. * fixed copyright.
  13. * 03-23-90 GJF Made xtoa() _CALLTYPE4.
  14. * 09-27-90 GJF New-style function declarators.
  15. * 01-21-91 GJF ANSI naming.
  16. * 04-06-93 SKS Replace _CRTAPI* with _cdecl
  17. * 01-19-96 BWT Add __int64 versions.
  18. * 09-22-97 GJF Added negation handling to x64toa.
  19. * 05-11-02 BWT Convert normalize the code so it can be
  20. * compiled for wide as well.
  21. *
  22. *******************************************************************************/
  23. #include <cruntime.h>
  24. #include <stdlib.h>
  25. #include <limits.h>
  26. #include <tchar.h>
  27. #ifdef _UNICODE
  28. #define xtox xtow
  29. #define _itox _itow
  30. #define _ltox _ltow
  31. #define _ultox _ultow
  32. #define x64tox x64tow
  33. #define _i64tox _i64tow
  34. #define _ui64tox _ui64tow
  35. #else
  36. #define xtox xtoa
  37. #define _itox _itoa
  38. #define _ltox _ltoa
  39. #define _ultox _ultoa
  40. #define x64tox x64toa
  41. #define _i64tox _i64toa
  42. #define _ui64tox _ui64toa
  43. #endif
  44. /***
  45. *char *_itoa, *_ltoa, *_ultoa(val, buf, radix) - convert binary int to ASCII
  46. * string
  47. *
  48. *Purpose:
  49. * Converts an int to a character string.
  50. *
  51. *Entry:
  52. * val - number to be converted (int, long or unsigned long)
  53. * int radix - base to convert into
  54. * char *buf - ptr to buffer to place result
  55. *
  56. *Exit:
  57. * fills in space pointed to by buf with string result
  58. * returns a pointer to this buffer
  59. *
  60. *Exceptions:
  61. *
  62. *******************************************************************************/
  63. /* helper routine that does the main job. */
  64. static
  65. void
  66. __stdcall
  67. xtox (
  68. unsigned long val,
  69. TCHAR *buf,
  70. unsigned radix,
  71. int is_neg
  72. )
  73. {
  74. TCHAR *p; /* pointer to traverse string */
  75. TCHAR *firstdig; /* pointer to first digit */
  76. TCHAR temp; /* temp char */
  77. unsigned digval; /* value of digit */
  78. p = buf;
  79. if (is_neg) {
  80. /* negative, so output '-' and negate */
  81. *p++ = _T('-');
  82. val = (unsigned long)(-(long)val);
  83. }
  84. firstdig = p; /* save pointer to first digit */
  85. do {
  86. digval = (unsigned) (val % radix);
  87. val /= radix; /* get next digit */
  88. /* convert to ascii and store */
  89. if (digval > 9)
  90. *p++ = (TCHAR) (digval - 10 + _T('a')); /* a letter */
  91. else
  92. *p++ = (TCHAR) (digval + _T('0')); /* a digit */
  93. } while (val > 0);
  94. /* We now have the digit of the number in the buffer, but in reverse
  95. order. Thus we reverse them now. */
  96. *p-- = _T('\0'); /* terminate string; p points to last digit */
  97. do {
  98. temp = *p;
  99. *p = *firstdig;
  100. *firstdig = temp; /* swap *p and *firstdig */
  101. --p;
  102. ++firstdig; /* advance to next two digits */
  103. } while (firstdig < p); /* repeat until halfway */
  104. }
  105. /* Actual functions just call conversion helper with neg flag set correctly,
  106. and return pointer to buffer. */
  107. TCHAR * __cdecl _itox (
  108. int val,
  109. TCHAR *buf,
  110. int radix
  111. )
  112. {
  113. if (radix == 10 && val < 0)
  114. xtox((unsigned long)val, buf, radix, 1);
  115. else
  116. xtox((unsigned long)(unsigned int)val, buf, radix, 0);
  117. return buf;
  118. }
  119. TCHAR * __cdecl _ltox (
  120. long val,
  121. TCHAR *buf,
  122. int radix
  123. )
  124. {
  125. xtox((unsigned long)val, buf, radix, (radix == 10 && val < 0));
  126. return buf;
  127. }
  128. TCHAR * __cdecl _ultox (
  129. unsigned long val,
  130. TCHAR *buf,
  131. int radix
  132. )
  133. {
  134. xtox(val, buf, radix, 0);
  135. return buf;
  136. }
  137. #ifndef _NO_INT64
  138. static
  139. void
  140. __fastcall
  141. x64tox ( /* stdcall is faster and smaller... Might as well use it for the helper. */
  142. unsigned __int64 val,
  143. TCHAR *buf,
  144. unsigned radix,
  145. int is_neg
  146. )
  147. {
  148. TCHAR *p; /* pointer to traverse string */
  149. TCHAR *firstdig; /* pointer to first digit */
  150. TCHAR temp; /* temp char */
  151. unsigned digval; /* value of digit */
  152. p = buf;
  153. if ( is_neg )
  154. {
  155. *p++ = _T('-'); /* negative, so output '-' and negate */
  156. val = (unsigned __int64)(-(__int64)val);
  157. }
  158. firstdig = p; /* save pointer to first digit */
  159. do {
  160. digval = (unsigned) (val % radix);
  161. val /= radix; /* get next digit */
  162. /* convert to ascii and store */
  163. if (digval > 9)
  164. *p++ = (TCHAR) (digval - 10 + _T('a')); /* a letter */
  165. else
  166. *p++ = (TCHAR) (digval + _T('0')); /* a digit */
  167. } while (val > 0);
  168. /* We now have the digit of the number in the buffer, but in reverse
  169. order. Thus we reverse them now. */
  170. *p-- = _T('\0'); /* terminate string; p points to last digit */
  171. do {
  172. temp = *p;
  173. *p = *firstdig;
  174. *firstdig = temp; /* swap *p and *firstdig */
  175. --p;
  176. ++firstdig; /* advance to next two digits */
  177. } while (firstdig < p); /* repeat until halfway */
  178. }
  179. /* Actual functions just call conversion helper with neg flag set correctly,
  180. and return pointer to buffer. */
  181. TCHAR * __cdecl _i64tox (
  182. __int64 val,
  183. TCHAR *buf,
  184. int radix
  185. )
  186. {
  187. x64tox((unsigned __int64)val, buf, radix, (radix == 10 && val < 0));
  188. return buf;
  189. }
  190. TCHAR * __cdecl _ui64tox (
  191. unsigned __int64 val,
  192. TCHAR *buf,
  193. int radix
  194. )
  195. {
  196. x64tox(val, buf, radix, 0);
  197. return buf;
  198. }
  199. #endif /* _NO_INT64 */