msvcp90: Added char_traits<wchar_t> 64-bit exports.
[wine] / dlls / msvcp90 / string.c
1 /*
2  * Copyright 2010 Piotr Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include <stdarg.h>
20
21 #include "msvcp90.h"
22 #include "stdio.h"
23
24 #include "windef.h"
25 #include "winbase.h"
26 #include "wine/debug.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(msvcp90);
28
29 /* char_traits<char> */
30 /* ?assign@?$char_traits@D@std@@SAXAADABD@Z */
31 /* ?assign@?$char_traits@D@std@@SAXAEADAEBD@Z */
32 void CDECL MSVCP_char_traits_char_assign(char *ch, const char *assign)
33 {
34     *ch = *assign;
35 }
36
37 /* ?eq@?$char_traits@D@std@@SA_NABD0@Z */
38 /* ?eq@?$char_traits@D@std@@SA_NAEBD0@Z */
39 MSVCP_BOOL CDECL MSVCP_char_traits_char_eq(const char *ch1, const char *ch2)
40 {
41     return *ch1 == *ch2;
42 }
43
44 /* ?lt@?$char_traits@D@std@@SA_NABD0@Z */
45 /* ?lt@?$char_traits@D@std@@SA_NAEBD0@Z */
46 MSVCP_BOOL CDECL MSVCP_char_traits_lt(const char *ch1, const char *ch2)
47 {
48     return *ch1 < *ch2;
49 }
50
51 /* ?compare@?$char_traits@D@std@@SAHPBD0I@Z */
52 /* ?compare@?$char_traits@D@std@@SAHPEBD0_K@Z */
53 int CDECL MSVCP_char_traits_char_compare(
54         const char *s1, const char *s2, size_t count)
55 {
56     int ret = memcmp(s1, s2, count);
57     return (ret>0 ? 1 : (ret<0 ? -1 : 0));
58 }
59
60 /* ?length@?$char_traits@D@std@@SAIPBD@Z */
61 /* ?length@?$char_traits@D@std@@SA_KPEBD@Z */
62 size_t CDECL MSVCP_char_traits_char_length(const char *str)
63 {
64     return strlen(str);
65 }
66
67 /* ?_Copy_s@?$char_traits@D@std@@SAPADPADIPBDI@Z */
68 /* ?_Copy_s@?$char_traits@D@std@@SAPEADPEAD_KPEBD1@Z */
69 char* CDECL MSVCP_char_traits_char__Copy_s(char *dest,
70         size_t size, const char *src, size_t count)
71 {
72     if(!dest || !src || size<count) {
73         if(dest && size)
74             dest[0] = '\0';
75         _invalid_parameter(NULL, NULL, NULL, 0, 0);
76         return dest;
77     }
78
79     return memcpy(dest, src, count);
80 }
81
82 /* ?copy@?$char_traits@D@std@@SAPADPADPBDI@Z */
83 /* ?copy@?$char_traits@D@std@@SAPEADPEADPEBD_K@Z */
84 char* CDECL MSVCP_char_traits_char_copy(
85         char *dest, const char *src, size_t count)
86 {
87     return MSVCP_char_traits_char__Copy_s(dest, count, src, count);
88 }
89
90 /* ?find@?$char_traits@D@std@@SAPBDPBDIABD@Z */
91 /* ?find@?$char_traits@D@std@@SAPEBDPEBD_KAEBD@Z */
92 const char * CDECL MSVCP_char_traits_char_find(
93         const char *str, size_t range, const char *c)
94 {
95     return memchr(str, *c, range);
96 }
97
98 /* ?_Move_s@?$char_traits@D@std@@SAPADPADIPBDI@Z */
99 /* ?_Move_s@?$char_traits@D@std@@SAPEADPEAD_KPEBD1@Z */
100 char* CDECL MSVCP_char_traits_char__Move_s(char *dest,
101         size_t size, const char *src, size_t count)
102 {
103     if(!dest || !src || size<count) {
104         if(dest && size)
105             dest[0] = '\0';
106         _invalid_parameter(NULL, NULL, NULL, 0, 0);
107         return dest;
108     }
109
110     return memmove(dest, src, count);
111 }
112
113 /* ?move@?$char_traits@D@std@@SAPADPADPBDI@Z */
114 /* ?move@?$char_traits@D@std@@SAPEADPEADPEBD_K@Z */
115 char* CDECL MSVCP_char_traits_char_move(
116         char *dest, const char *src, size_t count)
117 {
118     return MSVCP_char_traits_char__Move_s(dest, count, src, count);
119 }
120
121 /* ?assign@?$char_traits@D@std@@SAPADPADID@Z */
122 /* ?assign@?$char_traits@D@std@@SAPEADPEAD_KD@Z */
123 char* CDECL MSVCP_char_traits_char_assignn(char *str, size_t num, char c)
124 {
125     return memset(str, c, num);
126 }
127
128 /* ?to_char_type@?$char_traits@D@std@@SADABH@Z */
129 /* ?to_char_type@?$char_traits@D@std@@SADAEBH@Z */
130 char CDECL MSVCP_char_traits_char_to_char_type(const int *i)
131 {
132     return (char)*i;
133 }
134
135 /* ?to_int_type@?$char_traits@D@std@@SAHABD@Z */
136 /* ?to_int_type@?$char_traits@D@std@@SAHAEBD@Z */
137 int CDECL MSVCP_char_traits_char_to_int_type(const char *ch)
138 {
139     return (int)*ch;
140 }
141
142 /* ?eq_int_type@?$char_traits@D@std@@SA_NABH0@Z */
143 /* ?eq_int_type@?$char_traits@D@std@@SA_NAEBH0@Z */
144 MSVCP_BOOL CDECL MSVCP_char_traits_char_eq_int_type(const int *i1, const int *i2)
145 {
146     return *i1 == *i2;
147 }
148
149 /* ?eof@?$char_traits@D@std@@SAHXZ */
150 int CDECL MSVCP_char_traits_char_eof(void)
151 {
152     return EOF;
153 }
154
155 /* ?not_eof@?$char_traits@D@std@@SAHABH@Z */
156 /* ?not_eof@?$char_traits@D@std@@SAHAEBH@Z */
157 int CDECL MSVCP_char_traits_char_not_eof(int *in)
158 {
159     return (*in==EOF ? !EOF : *in);
160 }
161
162
163 /* char_traits<wchar_t> */
164 /* ?assign@?$char_traits@_W@std@@SAXAA_WAB_W@Z */
165 /* ?assign@?$char_traits@_W@std@@SAXAEA_WAEB_W@Z */
166 void CDECL MSVCP_char_traits_wchar_assign(wchar_t *ch,
167         const wchar_t *assign)
168 {
169     *ch = *assign;
170 }
171
172 /* ?eq@?$char_traits@_W@std@@SA_NAB_W0@Z */
173 /* ?eq@?$char_traits@_W@std@@SA_NAEB_W0@Z */
174 MSVCP_BOOL CDECL MSVCP_char_traits_wchar_eq(wchar_t *ch1, wchar_t *ch2)
175 {
176     return *ch1 == *ch2;
177 }
178
179 /* ?lt@?$char_traits@_W@std@@SA_NAB_W0@Z */
180 /* ?lt@?$char_traits@_W@std@@SA_NAEB_W0@Z */
181 MSVCP_BOOL CDECL MSVCP_char_traits_wchar_lt(const wchar_t *ch1,
182         const wchar_t *ch2)
183 {
184     return *ch1 < *ch2;
185 }
186
187 /* ?compare@?$char_traits@_W@std@@SAHPB_W0I@Z */
188 /* ?compare@?$char_traits@_W@std@@SAHPEB_W0_K@Z */
189 int CDECL MSVCP_char_traits_wchar_compare(const wchar_t *s1,
190         const wchar_t *s2, size_t count)
191 {
192     int ret = memcmp(s1, s2, sizeof(wchar_t[count]));
193     return (ret>0 ? 1 : (ret<0 ? -1 : 0));
194 }
195
196 /* ?length@?$char_traits@_W@std@@SAIPB_W@Z */
197 /* ?length@?$char_traits@_W@std@@SA_KPEB_W@Z */
198 size_t CDECL MSVCP_char_traits_wchar_length(const wchar_t *str)
199 {
200     return wcslen((WCHAR*)str);
201 }
202
203 /* ?_Copy_s@?$char_traits@_W@std@@SAPA_WPA_WIPB_WI@Z */
204 /* ?_Copy_s@?$char_traits@_W@std@@SAPEA_WPEA_W_KPEB_W1@Z */
205 wchar_t* CDECL MSVCP_char_traits_wchar__Copy_s(wchar_t *dest,
206         size_t size, const wchar_t *src, size_t count)
207 {
208     if(!dest || !src || size<count) {
209         if(dest && size)
210             dest[0] = '\0';
211         _invalid_parameter(NULL, NULL, NULL, 0, 0);
212         return dest;
213     }
214
215     return memcpy(dest, src, sizeof(wchar_t[count]));
216 }
217
218 /* ?copy@?$char_traits@_W@std@@SAPA_WPA_WPB_WI@Z */
219 /* ?copy@?$char_traits@_W@std@@SAPEA_WPEA_WPEB_W_K@Z */
220 wchar_t* CDECL MSVCP_char_traits_wchar_copy(wchar_t *dest,
221         const wchar_t *src, size_t count)
222 {
223     return MSVCP_char_traits_wchar__Copy_s(dest, count, src, count);
224 }
225
226 /* ?find@?$char_traits@_W@std@@SAPB_WPB_WIAB_W@Z */
227 /* ?find@?$char_traits@_W@std@@SAPEB_WPEB_W_KAEB_W@Z */
228 const wchar_t* CDECL MSVCP_char_traits_wchar_find(
229         const wchar_t *str, size_t range, const wchar_t *c)
230 {
231     size_t i=0;
232
233     for(i=0; i<range; i++)
234         if(str[i] == *c)
235             return str+i;
236
237     return NULL;
238 }
239
240 /* ?_Move_s@?$char_traits@_W@std@@SAPA_WPA_WIPB_WI@Z */
241 /* ?_Move_s@?$char_traits@_W@std@@SAPEA_WPEA_W_KPEB_W1@Z */
242 wchar_t* CDECL MSVCP_char_traits_wchar__Move_s(wchar_t *dest,
243         size_t size, const wchar_t *src, size_t count)
244 {
245     if(!dest || !src || size<count) {
246         if(dest && size)
247             dest[0] = '\0';
248         _invalid_parameter(NULL, NULL, NULL, 0, 0);
249         return dest;
250     }
251
252     return memmove(dest, src, sizeof(WCHAR[count]));
253 }
254
255 /* ?move@?$char_traits@_W@std@@SAPA_WPA_WPB_WI@Z */
256 /* ?move@?$char_traits@_W@std@@SAPEA_WPEA_WPEB_W_K@Z */
257 wchar_t* CDECL MSVCP_char_traits_wchar_move(wchar_t *dest,
258         const wchar_t *src, size_t count)
259 {
260     return MSVCP_char_traits_wchar__Move_s(dest, count, src, count);
261 }
262
263 /* ?assign@?$char_traits@_W@std@@SAPA_WPA_WI_W@Z */
264 /* ?assign@?$char_traits@_W@std@@SAPEA_WPEA_W_K_W@Z */
265 wchar_t* CDECL MSVCP_char_traits_wchar_assignn(wchar_t *str,
266         size_t num, wchar_t c)
267 {
268     size_t i;
269
270     for(i=0; i<num; i++)
271         str[i] = c;
272
273     return str;
274 }
275
276 /* ?to_char_type@?$char_traits@_W@std@@SA_WABG@Z */
277 /* ?to_char_type@?$char_traits@_W@std@@SA_WAEBG@Z */
278 wchar_t CDECL MSVCP_char_traits_wchar_to_char_type(const unsigned short *i)
279 {
280     return *i;
281 }
282
283 /* ?to_int_type@?$char_traits@_W@std@@SAGAB_W@Z */
284 /* ?to_int_type@?$char_traits@_W@std@@SAGAEB_W@Z */
285 unsigned short CDECL MSVCP_char_traits_wchar_to_int_type(const wchar_t *ch)
286 {
287     return *ch;
288 }
289
290 /* ?eq_int_type@?$char_traits@_W@std@@SA_NABG0@Z */
291 /* ?eq_int_type@?$char_traits@_W@std@@SA_NAEBG0@Z */
292 MSVCP_BOOL CDECL MSVCP_char_traits_wchar_eq_int_tpe(const unsigned short *i1,
293         const unsigned short *i2)
294 {
295     return *i1 == *i2;
296 }
297
298 /* ?eof@?$char_traits@_W@std@@SAGXZ */
299 unsigned short CDECL MSVCP_char_traits_wchar_eof(void)
300 {
301     return WEOF;
302 }
303
304 /* ?not_eof@?$char_traits@_W@std@@SAGABG@Z */
305 /* ?not_eof@?$char_traits@_W@std@@SAGAEBG@Z */
306 unsigned short CDECL MSVCP_char_traits_wchar_not_eof(const unsigned short *in)
307 {
308     return (*in==WEOF ? !WEOF : *in);
309 }
310
311
312 /* char_traits<unsigned short> */
313 /* ?assign@?$char_traits@G@std@@SAXAAGABG@Z */
314 void CDECL MSVCP_char_traits_short_assign(unsigned short *ch,
315         const unsigned short *assign)
316 {
317     *ch = *assign;
318 }
319
320 /* ?eq@?$char_traits@G@std@@SA_NABG0@Z */
321 MSVCP_BOOL CDECL MSVCP_char_traits_short_eq(const unsigned short *ch1,
322         const unsigned short *ch2)
323 {
324     return *ch1 == *ch2;
325 }
326
327 /* ?lt@?$char_traits@G@std@@SA_NABG0@Z */
328 MSVCP_BOOL CDECL MSVCP_char_traits_short_lt(const unsigned short *ch1,
329         const unsigned short *ch2)
330 {
331     return *ch1 < *ch2;
332 }
333
334 /* ?compare@?$char_traits@G@std@@SAHPBG0I@Z */
335 int CDECL MSVCP_char_traits_short_compare(const unsigned short *s1,
336         const unsigned short *s2, unsigned int count)
337 {
338     unsigned int i;
339
340     for(i=0; i<count; i++)
341         if(s1[i] != s2[i])
342             return (s1[i] < s2[i] ? -1 : 1);
343
344     return 0;
345 }
346
347 /* ?length@?$char_traits@G@std@@SAIPBG@Z */
348 unsigned int CDECL MSVCP_char_traits_short_length(const unsigned short *str)
349 {
350     unsigned int len;
351
352     for(len=0; str[len]; len++);
353
354     return len;
355 }
356
357 /* ?_Copy_s@?$char_traits@G@std@@SAPAGPAGIPBGI@Z */
358 unsigned short * CDECL MSVCP_char_traits_short__Copy_s(unsigned short *dest,
359         unsigned int size, const unsigned short *src, unsigned int count)
360 {
361     if(size<count) {
362         _invalid_parameter(NULL, NULL, NULL, 0, 0);
363         return dest;
364     }
365
366     return memcpy(dest, src, sizeof(unsigned short[count]));
367 }
368
369 /* ?copy@?$char_traits@G@std@@SAPAGPAGPBGI@Z */
370 unsigned short* CDECL MSVCP_char_traits_short_copy(unsigned short *dest,
371         const unsigned short *src, unsigned int count)
372 {
373     return MSVCP_char_traits_short__Copy_s(dest, count, src, count);
374 }
375
376 /* ?find@?$char_traits@G@std@@SAPBGPBGIABG@Z */
377 const unsigned short* CDECL MSVCP_char_traits_short_find(
378         const unsigned short *str, unsigned int range, const unsigned short *c)
379 {
380     unsigned int i;
381
382     for(i=0; i<range; i++)
383         if(str[i] == *c)
384             return str+i;
385
386     return NULL;
387 }
388
389 /* ?_Move_s@?$char_traits@G@std@@SAPAGPAGIPBGI@Z */
390 unsigned short* CDECL MSVCP_char_traits_short__Move_s(unsigned short *dest,
391         unsigned int size, const unsigned short *src, unsigned int count)
392 {
393     if(size<count) {
394         _invalid_parameter(NULL, NULL, NULL, 0, 0);
395         return dest;
396     }
397
398     return memmove(dest, src, sizeof(unsigned short[count]));
399 }
400
401 /* ?move@?$char_traits@G@std@@SAPAGPAGPBGI@Z */
402 unsigned short* CDECL MSVCP_char_traits_short_move(unsigned short *dest,
403         const unsigned short *src, unsigned int count)
404 {
405     return MSVCP_char_traits_short__Move_s(dest, count, src, count);
406 }
407
408 /* ?assign@?$char_traits@G@std@@SAPAGPAGIG@Z */
409 unsigned short* CDECL MSVCP_char_traits_short_assignn(unsigned short *str,
410         unsigned int num, unsigned short c)
411 {
412     unsigned int i;
413
414     for(i=0; i<num; i++)
415         str[i] = c;
416
417     return str;
418 }
419
420 /* ?to_char_type@?$char_traits@G@std@@SAGABG@Z */
421 unsigned short CDECL MSVCP_char_traits_short_to_char_type(const unsigned short *i)
422 {
423     return *i;
424 }
425
426 /* ?to_int_type@?$char_traits@G@std@@SAGABG@Z */
427 unsigned short CDECL MSVCP_char_traits_short_to_int_type(const unsigned short *ch)
428 {
429     return *ch;
430 }
431
432 /* ?eq_int_type@?$char_traits@G@std@@SA_NABG0@Z */
433 MSVCP_BOOL CDECL MSVCP_char_traits_short_eq_int_type(unsigned short *i1,
434         unsigned short *i2)
435 {
436     return *i1 == *i2;
437 }
438
439 /* ?eof@?$char_traits@G@std@@SAGXZ */
440 unsigned short CDECL MSVCP_char_traits_short_eof(void)
441 {
442     return -1;
443 }
444
445 /* ?not_eof@?$char_traits@G@std@@SAGABG@Z */
446 unsigned short CDECL MSVCP_char_traits_short_not_eof(const unsigned short *in)
447 {
448     return (*in==(unsigned short)-1 ? 0 : *in);
449 }