xref: /reactos/sdk/lib/crt/string/wtoi64.c (revision 8a978a17)
1 #include <precomp.h>
2 #include <internal/wine/msvcrt.h>
3 
4 /*********************************************************************
5  *              _wtoi64_l (MSVCRT.@)
6  */
7 __int64 CDECL _wtoi64_l(const wchar_t *str, _locale_t locale)
8 {
9     ULONGLONG RunningTotal = 0;
10     BOOL bMinus = FALSE;
11 
12     while (iswctype((int)*str, _SPACE)) {
13         str++;
14     } /* while */
15 
16     if (*str == '+') {
17         str++;
18     } else if (*str == '-') {
19         bMinus = TRUE;
20         str++;
21     } /* if */
22 
23     while (*str >= '0' && *str <= '9') {
24         RunningTotal = RunningTotal * 10 + *str - '0';
25         str++;
26     } /* while */
27 
28     return bMinus ? -RunningTotal : RunningTotal;
29 }
30 
31 /*********************************************************************
32  *              _wtoi64 (MSVCRT.@)
33  */
34 __int64 CDECL _wtoi64(const wchar_t *str)
35 {
36     return _wtoi64_l(str, NULL);
37 }
38 
39 
40 /*********************************************************************
41  *  _wcstoi64_l (MSVCRT.@)
42  *
43  * FIXME: locale parameter is ignored
44  */
45 __int64 CDECL _wcstoi64_l(const wchar_t *nptr,
46         wchar_t **endptr, int base, _locale_t locale)
47 {
48     BOOL negative = FALSE;
49     __int64 ret = 0;
50 
51 #ifndef _LIBCNT_
52     TRACE("(%s %p %d %p)\n", debugstr_w(nptr), endptr, base, locale);
53 #endif
54 
55     if (!MSVCRT_CHECK_PMT(nptr != NULL)) return 0;
56     if (!MSVCRT_CHECK_PMT(base == 0 || base >= 2)) return 0;
57     if (!MSVCRT_CHECK_PMT(base <= 36)) return 0;
58 
59     while (iswctype((int)*nptr, _SPACE)) nptr++;
60 
61     if(*nptr == '-') {
62         negative = TRUE;
63         nptr++;
64     } else if(*nptr == '+')
65         nptr++;
66 
67     if((base==0 || base==16) && *nptr=='0' && towlower(*(nptr+1))=='x') {
68         base = 16;
69         nptr += 2;
70     }
71 
72     if(base == 0) {
73         if(*nptr=='0')
74             base = 8;
75         else
76             base = 10;
77     }
78 
79     while(*nptr) {
80         wchar_t cur = towlower(*nptr);
81         int v;
82 
83         if(cur>='0' && cur<='9') {
84             if(cur >= '0'+base)
85                 break;
86             v = cur-'0';
87         } else {
88             if(cur<'a' || cur>='a'+base-10)
89                 break;
90             v = cur-'a'+10;
91         }
92 
93         if(negative)
94             v = -v;
95 
96         nptr++;
97 
98         if(!negative && (ret>_I64_MAX/base || ret*base>_I64_MAX-v)) {
99             ret = _I64_MAX;
100 #ifndef _LIBCNT_
101             *_errno() = ERANGE;
102 #endif
103         } else if(negative && (ret<_I64_MIN/base || ret*base<_I64_MIN-v)) {
104             ret = _I64_MIN;
105 #ifndef _LIBCNT_
106             *_errno() = ERANGE;
107 #endif
108         } else
109             ret = ret*base + v;
110     }
111 
112     if(endptr)
113         *endptr = (wchar_t*)nptr;
114 
115     return ret;
116 }
117 
118 /*********************************************************************
119  *  _wcstoi64 (MSVCRT.@)
120  */
121 __int64 CDECL _wcstoi64(const wchar_t *nptr,
122         wchar_t **endptr, int base)
123 {
124     return _wcstoi64_l(nptr, endptr, base, NULL);
125 }
126 
127 /*********************************************************************
128  *  _wcstoui64_l (MSVCRT.@)
129  *
130  * FIXME: locale parameter is ignored
131  */
132 unsigned __int64 CDECL _wcstoui64_l(const wchar_t *nptr,
133         wchar_t **endptr, int base, _locale_t locale)
134 {
135     BOOL negative = FALSE;
136     unsigned __int64 ret = 0;
137 
138 #ifndef _LIBCNT_
139     TRACE("(%s %p %d %p)\n", debugstr_w(nptr), endptr, base, locale);
140 #endif
141 
142     if (!MSVCRT_CHECK_PMT(nptr != NULL)) return 0;
143     if (!MSVCRT_CHECK_PMT(base == 0 || base >= 2)) return 0;
144     if (!MSVCRT_CHECK_PMT(base <= 36)) return 0;
145 
146     while (iswctype((int)*nptr, _SPACE)) nptr++;
147 
148     if(*nptr == '-') {
149         negative = TRUE;
150         nptr++;
151     } else if(*nptr == '+')
152         nptr++;
153 
154     if((base==0 || base==16) && *nptr=='0' && towlower(*(nptr+1))=='x') {
155         base = 16;
156         nptr += 2;
157     }
158 
159     if(base == 0) {
160         if(*nptr=='0')
161             base = 8;
162         else
163             base = 10;
164     }
165 
166     while(*nptr) {
167         wchar_t cur = towlower(*nptr);
168         int v;
169 
170         if(cur>='0' && cur<='9') {
171             if(cur >= '0'+base)
172                 break;
173             v = *nptr-'0';
174         } else {
175             if(cur<'a' || cur>='a'+base-10)
176                 break;
177             v = cur-'a'+10;
178         }
179 
180         nptr++;
181 
182         if(ret>_UI64_MAX/base || ret*base>_UI64_MAX-v) {
183             ret = _UI64_MAX;
184 #ifndef _LIBCNT_
185             *_errno() = ERANGE;
186 #endif
187             } else
188             ret = ret*base + v;
189     }
190 
191     if(endptr)
192         *endptr = (wchar_t*)nptr;
193 
194     return negative ? -ret : ret;
195 }
196 
197 /*********************************************************************
198  *  _wcstoui64 (MSVCRT.@)
199  */
200 unsigned __int64 CDECL _wcstoui64(const wchar_t *nptr,
201         wchar_t **endptr, int base)
202 {
203     return _wcstoui64_l(nptr, endptr, base, NULL);
204 }
205 
206 
207 /* EOF */
208