e2f5918c13d67a15b1a8895eed7fe9a3bcecf974
[reactos.git] / reactos / lib / sdk / crt / string / itoa.c
1 /* taken from wine ntdll and msvcrt string.c */
2
3 #include <precomp.h>
4
5 /*
6 * @implemented
7 */
8 char *
9 _i64toa(__int64 value, char *string, int radix)
10 {
11 ULONGLONG val;
12 int negative;
13 char buffer[65];
14 char *pos;
15 int digit;
16
17 if (value < 0 && radix == 10) {
18 negative = 1;
19 val = -value;
20 } else {
21 negative = 0;
22 val = value;
23 } /* if */
24
25 pos = &buffer[64];
26 *pos = '\0';
27
28 do {
29 digit = val % radix;
30 val = val / radix;
31 if (digit < 10) {
32 *--pos = '0' + digit;
33 } else {
34 *--pos = 'a' + digit - 10;
35 } /* if */
36 } while (val != 0L);
37
38 if (negative) {
39 *--pos = '-';
40 } /* if */
41
42 memcpy(string, pos, &buffer[64] - pos + 1);
43 return string;
44 }
45
46 /*
47 * @implemented
48 */
49 int CDECL _i64toa_s(__int64 value, char *str, size_t size, int radix)
50 {
51 unsigned __int64 val;
52 unsigned int digit;
53 int is_negative;
54 char buffer[65], *pos;
55 size_t len;
56
57 if (!MSVCRT_CHECK_PMT(str != NULL) || !MSVCRT_CHECK_PMT(size > 0) ||
58 !MSVCRT_CHECK_PMT(radix >= 2) || !MSVCRT_CHECK_PMT(radix <= 36))
59 {
60 if (str && size)
61 str[0] = '\0';
62 #ifndef _LIBCNT_
63 *_errno() = EINVAL;
64 #endif
65 return EINVAL;
66 }
67
68 if (value < 0 && radix == 10)
69 {
70 is_negative = 1;
71 val = -value;
72 }
73 else
74 {
75 is_negative = 0;
76 val = value;
77 }
78
79 pos = buffer + 64;
80 *pos = '\0';
81
82 do
83 {
84 digit = val % radix;
85 val /= radix;
86
87 if (digit < 10)
88 *--pos = '0' + digit;
89 else
90 *--pos = 'a' + digit - 10;
91 }
92 while (val != 0);
93
94 if (is_negative)
95 *--pos = '-';
96
97 len = buffer + 65 - pos;
98 if (len > size)
99 {
100 size_t i;
101 char *p = str;
102
103 /* Copy the temporary buffer backwards up to the available number of
104 * characters. Don't copy the negative sign if present. */
105
106 if (is_negative)
107 {
108 p++;
109 size--;
110 }
111
112 for (pos = buffer + 63, i = 0; i < size; i++)
113 *p++ = *pos--;
114
115 str[0] = '\0';
116 MSVCRT_INVALID_PMT("str[size] is too small");
117 #ifndef _LIBCNT_
118 *_errno() = ERANGE;
119 #endif
120 return ERANGE;
121 }
122
123 memcpy(str, pos, len);
124 return 0;
125 }
126
127 /*
128 * @implemented
129 */
130 char *
131 _ui64toa(unsigned __int64 value, char *string, int radix)
132 {
133 char buffer[65];
134 char *pos;
135 int digit;
136
137 pos = &buffer[64];
138 *pos = '\0';
139
140 do {
141 digit = value % radix;
142 value = value / radix;
143 if (digit < 10) {
144 *--pos = '0' + digit;
145 } else {
146 *--pos = 'a' + digit - 10;
147 } /* if */
148 } while (value != 0L);
149
150 memcpy(string, pos, &buffer[64] - pos + 1);
151 return string;
152 }
153
154 /*
155 * @implemented
156 */
157 int CDECL _ui64toa_s(unsigned __int64 value, char *str,
158 size_t size, int radix)
159 {
160 char buffer[65], *pos;
161 int digit;
162
163 if (!MSVCRT_CHECK_PMT(str != NULL) || !MSVCRT_CHECK_PMT(size > 0) ||
164 !MSVCRT_CHECK_PMT(radix>=2) || !MSVCRT_CHECK_PMT(radix<=36)) {
165 #ifndef _LIBCNT_
166 *_errno() = EINVAL;
167 #endif
168 return EINVAL;
169 }
170
171 pos = buffer+64;
172 *pos = '\0';
173
174 do {
175 digit = value%radix;
176 value /= radix;
177
178 if(digit < 10)
179 *--pos = '0'+digit;
180 else
181 *--pos = 'a'+digit-10;
182 }while(value != 0);
183
184 if((unsigned)(buffer-pos+65) > size) {
185 MSVCRT_INVALID_PMT("str[size] is too small");
186 #ifndef _LIBCNT_
187 *_errno() = EINVAL;
188 #endif
189 return EINVAL;
190 }
191
192 memcpy(str, pos, buffer-pos+65);
193 return 0;
194 }
195
196 /*
197 * @implemented
198 */
199 int CDECL _itoa_s(int value, char *str, size_t size, int radix)
200 {
201 return _ltoa_s(value, str, size, radix);
202 }
203
204 /*
205 * @implemented
206 */
207 char *
208 _itoa(int value, char *string, int radix)
209 {
210 return _ltoa(value, string, radix);
211 }
212
213 /*
214 * @implemented
215 */
216 char *
217 _ltoa(long value, char *string, int radix)
218 {
219 unsigned long val;
220 int negative;
221 char buffer[33];
222 char *pos;
223 int digit;
224
225 if (value < 0 && radix == 10) {
226 negative = 1;
227 val = -value;
228 } else {
229 negative = 0;
230 val = value;
231 } /* if */
232
233 pos = &buffer[32];
234 *pos = '\0';
235
236 do {
237 digit = val % radix;
238 val = val / radix;
239 if (digit < 10) {
240 *--pos = '0' + digit;
241 } else {
242 *--pos = 'a' + digit - 10;
243 } /* if */
244 } while (val != 0L);
245
246 if (negative) {
247 *--pos = '-';
248 } /* if */
249
250 memcpy(string, pos, &buffer[32] - pos + 1);
251 return string;
252 }
253
254 /*
255 * @implemented
256 */
257 int CDECL _ltoa_s(long value, char *str, size_t size, int radix)
258 {
259 unsigned long val;
260 unsigned int digit;
261 int is_negative;
262 char buffer[33], *pos;
263 size_t len;
264
265 if (!MSVCRT_CHECK_PMT(str != NULL) || !MSVCRT_CHECK_PMT(size > 0) ||
266 !MSVCRT_CHECK_PMT(radix >= 2) || !MSVCRT_CHECK_PMT(radix <= 36))
267 {
268 if (str && size)
269 str[0] = '\0';
270
271 #ifndef _LIBCNT_
272 *_errno() = EINVAL;
273 #endif
274 return EINVAL;
275 }
276
277 if (value < 0 && radix == 10)
278 {
279 is_negative = 1;
280 val = -value;
281 }
282 else
283 {
284 is_negative = 0;
285 val = value;
286 }
287
288 pos = buffer + 32;
289 *pos = '\0';
290
291 do
292 {
293 digit = val % radix;
294 val /= radix;
295
296 if (digit < 10)
297 *--pos = '0' + digit;
298 else
299 *--pos = 'a' + digit - 10;
300 }
301 while (val != 0);
302
303 if (is_negative)
304 *--pos = '-';
305
306 len = buffer + 33 - pos;
307 if (len > size)
308 {
309 size_t i;
310 char *p = str;
311
312 /* Copy the temporary buffer backwards up to the available number of
313 * characters. Don't copy the negative sign if present. */
314
315 if (is_negative)
316 {
317 p++;
318 size--;
319 }
320
321 for (pos = buffer + 31, i = 0; i < size; i++)
322 *p++ = *pos--;
323
324 str[0] = '\0';
325 MSVCRT_INVALID_PMT("str[size] is too small");
326 #ifndef _LIBCNT_
327 *_errno() = EINVAL;
328 #endif
329 return ERANGE;
330 }
331
332 memcpy(str, pos, len);
333 return 0;
334 }
335
336 /*
337 * @implemented
338 */
339 char *
340 _ultoa(unsigned long value, char *string, int radix)
341 {
342 char buffer[33];
343 char *pos;
344 int digit;
345
346 pos = &buffer[32];
347 *pos = '\0';
348
349 do {
350 digit = value % radix;
351 value = value / radix;
352 if (digit < 10) {
353 *--pos = '0' + digit;
354 } else {
355 *--pos = 'a' + digit - 10;
356 } /* if */
357 } while (value != 0L);
358
359 memcpy(string, pos, &buffer[32] - pos + 1);
360
361 return string;
362 }