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