[CRT]
[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", ERANGE);
117 return ERANGE;
118 }
119
120 memcpy(str, pos, len);
121 return 0;
122 }
123
124 /*
125 * @implemented
126 */
127 char *
128 _ui64toa(unsigned __int64 value, char *string, int radix)
129 {
130 char buffer[65];
131 char *pos;
132 int digit;
133
134 pos = &buffer[64];
135 *pos = '\0';
136
137 do {
138 digit = value % radix;
139 value = value / radix;
140 if (digit < 10) {
141 *--pos = '0' + digit;
142 } else {
143 *--pos = 'a' + digit - 10;
144 } /* if */
145 } while (value != 0L);
146
147 memcpy(string, pos, &buffer[64] - pos + 1);
148 return string;
149 }
150
151 /*
152 * @implemented
153 */
154 int CDECL _ui64toa_s(unsigned __int64 value, char *str,
155 size_t size, int radix)
156 {
157 char buffer[65], *pos;
158 int digit;
159
160 if (!MSVCRT_CHECK_PMT(str != NULL) || !MSVCRT_CHECK_PMT(size > 0) ||
161 !MSVCRT_CHECK_PMT(radix>=2) || !MSVCRT_CHECK_PMT(radix<=36)) {
162 #ifndef _LIBCNT_
163 *_errno() = EINVAL;
164 #endif
165 return EINVAL;
166 }
167
168 pos = buffer+64;
169 *pos = '\0';
170
171 do {
172 digit = value%radix;
173 value /= radix;
174
175 if(digit < 10)
176 *--pos = '0'+digit;
177 else
178 *--pos = 'a'+digit-10;
179 }while(value != 0);
180
181 if((unsigned)(buffer-pos+65) > size) {
182 MSVCRT_INVALID_PMT("str[size] is too small", EINVAL);
183 return EINVAL;
184 }
185
186 memcpy(str, pos, buffer-pos+65);
187 return 0;
188 }
189
190 /*
191 * @implemented
192 */
193 int CDECL _itoa_s(int value, char *str, size_t size, int radix)
194 {
195 return _ltoa_s(value, str, size, radix);
196 }
197
198 /*
199 * @implemented
200 */
201 char *
202 _itoa(int value, char *string, int radix)
203 {
204 return _ltoa(value, string, radix);
205 }
206
207 /*
208 * @implemented
209 */
210 char *
211 _ltoa(long value, char *string, int radix)
212 {
213 unsigned long val;
214 int negative;
215 char buffer[33];
216 char *pos;
217 int digit;
218
219 if (value < 0 && radix == 10) {
220 negative = 1;
221 val = -value;
222 } else {
223 negative = 0;
224 val = value;
225 } /* if */
226
227 pos = &buffer[32];
228 *pos = '\0';
229
230 do {
231 digit = val % radix;
232 val = val / radix;
233 if (digit < 10) {
234 *--pos = '0' + digit;
235 } else {
236 *--pos = 'a' + digit - 10;
237 } /* if */
238 } while (val != 0L);
239
240 if (negative) {
241 *--pos = '-';
242 } /* if */
243
244 memcpy(string, pos, &buffer[32] - pos + 1);
245 return string;
246 }
247
248 /*
249 * @implemented
250 */
251 int CDECL _ltoa_s(long value, char *str, size_t size, int radix)
252 {
253 unsigned long val;
254 unsigned int digit;
255 int is_negative;
256 char buffer[33], *pos;
257 size_t len;
258
259 if (!MSVCRT_CHECK_PMT(str != NULL) || !MSVCRT_CHECK_PMT(size > 0) ||
260 !MSVCRT_CHECK_PMT(radix >= 2) || !MSVCRT_CHECK_PMT(radix <= 36))
261 {
262 if (str && size)
263 str[0] = '\0';
264
265 #ifndef _LIBCNT_
266 *_errno() = EINVAL;
267 #endif
268 return EINVAL;
269 }
270
271 if (value < 0 && radix == 10)
272 {
273 is_negative = 1;
274 val = -value;
275 }
276 else
277 {
278 is_negative = 0;
279 val = value;
280 }
281
282 pos = buffer + 32;
283 *pos = '\0';
284
285 do
286 {
287 digit = val % radix;
288 val /= radix;
289
290 if (digit < 10)
291 *--pos = '0' + digit;
292 else
293 *--pos = 'a' + digit - 10;
294 }
295 while (val != 0);
296
297 if (is_negative)
298 *--pos = '-';
299
300 len = buffer + 33 - pos;
301 if (len > size)
302 {
303 size_t i;
304 char *p = str;
305
306 /* Copy the temporary buffer backwards up to the available number of
307 * characters. Don't copy the negative sign if present. */
308
309 if (is_negative)
310 {
311 p++;
312 size--;
313 }
314
315 for (pos = buffer + 31, i = 0; i < size; i++)
316 *p++ = *pos--;
317
318 str[0] = '\0';
319 MSVCRT_INVALID_PMT("str[size] is too small", ERANGE);
320 return ERANGE;
321 }
322
323 memcpy(str, pos, len);
324 return 0;
325 }
326
327 /*
328 * @implemented
329 */
330 char *
331 _ultoa(unsigned long value, char *string, int radix)
332 {
333 char buffer[33];
334 char *pos;
335 int digit;
336
337 pos = &buffer[32];
338 *pos = '\0';
339
340 do {
341 digit = value % radix;
342 value = value / radix;
343 if (digit < 10) {
344 *--pos = '0' + digit;
345 } else {
346 *--pos = 'a' + digit - 10;
347 } /* if */
348 } while (value != 0L);
349
350 memcpy(string, pos, &buffer[32] - pos + 1);
351
352 return string;
353 }