1 #include <precomp.h> 2 3 4 /* 5 * Convert a unicode string to an unsigned long integer. 6 * 7 * Ignores `locale' stuff. Assumes that the upper and lower case 8 * alphabets and digits are each contiguous. 9 * 10 * @implemented 11 */ 12 unsigned long 13 CDECL 14 wcstoul(const wchar_t *nptr, wchar_t **endptr, int base) 15 { 16 const wchar_t *s = nptr; 17 unsigned long acc; 18 int c; 19 unsigned long cutoff; 20 int neg = 0, any, cutlim; 21 22 /* 23 * See strtol for comments as to the logic used. 24 */ 25 do { 26 c = *s++; 27 } while (iswctype(c, _SPACE)); 28 if (c == L'-') 29 { 30 neg = 1; 31 c = *s++; 32 } 33 else if (c == L'+') 34 c = *s++; 35 if ((base == 0 || base == 16) && 36 c == L'0' && (*s == L'x' || *s == L'X')) 37 { 38 c = s[1]; 39 s += 2; 40 base = 16; 41 } 42 if (base == 0) 43 base = c == L'0' ? 8 : 10; 44 cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; 45 cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; 46 for (acc = 0, any = 0;; c = *s++) 47 { 48 if (iswctype(c, _DIGIT)) 49 c -= L'0'; 50 else if (iswctype(c, _ALPHA)) 51 c -= iswctype(c, _UPPER) ? L'A' - 10 : L'a' - 10; 52 else 53 break; 54 if (c >= base) 55 break; 56 if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) 57 any = -1; 58 else { 59 any = 1; 60 acc *= base; 61 acc += c; 62 } 63 } 64 if (any < 0) 65 { 66 acc = ULONG_MAX; 67 } 68 else if (neg) 69 acc = 0-acc; 70 if (endptr != 0) 71 *endptr = any ? (wchar_t *)((size_t)(s - 1)) : (wchar_t *)((size_t)nptr); 72 return acc; 73 } 74