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