source: trunk/src/kernel32/heapstring.cpp@ 5457

Last change on this file since 5457 was 5457, checked in by sandervl, 24 years ago

rewrote string functions with new unicode code

File size: 20.5 KB
Line 
1/* $Id: heapstring.cpp,v 1.37 2001-04-03 17:47:11 sandervl Exp $ */
2
3/*
4 * Project Odin Software License can be found in LICENSE.TXT
5 *
6 * Win32 compatibility string functions for OS/2
7 *
8 * NOTE: lstrcpyn* always appends a terminating 0 (unlike strncpy)!
9 *
10 * Copyright 1999 Patrick Haller
11 */
12
13/*****************************************************************************
14 * Includes *
15 *****************************************************************************/
16
17#include <odin.h>
18#include <odinwrap.h>
19#include <os2sel.h>
20
21#include <os2win.h>
22#include <stdlib.h>
23#include <string.h>
24#include <stdio.h>
25#include <winnls.h>
26#include <unicode.h>
27#include <ctype.h>
28#include <wcstr.h>
29#include "heap.h"
30#include <wine\unicode.h>
31#include "misc.h"
32#include "codepage.h"
33
34#define DBG_LOCALLOG DBG_heapstring
35#include "dbglocal.h"
36
37/*****************************************************************************
38 * Defines *
39 *****************************************************************************/
40
41ODINDEBUGCHANNEL(KERNEL32-HEAPSTRING)
42
43/*****************************************************************************
44 * Name :
45 * Purpose :
46 * Parameters:
47 * Variables :
48 * Result :
49 * Remark :
50 * Status :
51 *
52 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
53 *****************************************************************************/
54
55int WIN32API lstrlenA(LPCSTR arg1)
56{
57 dprintf2(("KERNEL32: lstrlenA(%s)\n",
58 arg1));
59
60 return O32_lstrlen(arg1);
61}
62
63
64/*****************************************************************************
65 * Name :
66 * Purpose :
67 * Parameters:
68 * Variables :
69 * Result :
70 * Remark :
71 * Status :
72 *
73 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
74 *****************************************************************************/
75
76int WIN32API lstrlenW(LPCWSTR arg1)
77{
78 int rc;
79
80 rc = UniStrlen( (UniChar*)arg1);
81 dprintf2(("KERNEL32: lstrlenW(%08xh) returns %d\n",
82 arg1,
83 rc));
84 return rc;
85}
86
87
88/*****************************************************************************
89 * Name :
90 * Purpose :
91 * Parameters:
92 * Variables :
93 * Result :
94 * Remark :
95 * Status :
96 *
97 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
98 *****************************************************************************/
99
100LPSTR WIN32API lstrcatA(LPSTR arg1, LPCSTR arg2)
101{
102 dprintf2(("KERNEL32: lstrcat(%s,%s)\n",
103 arg1,
104 arg2));
105
106 if(arg2 == NULL)
107 return arg1;
108 strcat(arg1, arg2);
109 return arg1;
110}
111
112
113/*****************************************************************************
114 * Name :
115 * Purpose :
116 * Parameters:
117 * Variables :
118 * Result :
119 * Remark :
120 * Status :
121 *
122 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
123 *****************************************************************************/
124
125LPWSTR WIN32API lstrcatW(LPWSTR arg1, LPCWSTR arg2)
126{
127 dprintf2(("KERNEL32: OS2lstrcatW(%08xh,%08xh)\n",
128 arg1,
129 arg2));
130
131 if(arg2 == NULL)
132 return arg1;
133
134 UniStrcat( (UniChar*) arg1, (UniChar*) arg2 );
135 return arg1;
136}
137
138
139/*****************************************************************************
140 * Name :
141 * Purpose :
142 * Parameters:
143 * Variables :
144 * Result :
145 * Remark :
146 * Status :
147 *
148 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
149 *****************************************************************************/
150
151int WIN32API lstrcmpA(LPCSTR arg1, LPCSTR arg2)
152{
153 dprintf2(("KERNEL32: OS2lstrcmpA(%s,%s)\n",
154 arg1,
155 arg2));
156
157 if(arg1 == NULL)
158 return -1;
159 if(arg2 == NULL)
160 return 1;
161
162 return O32_lstrcmp(arg1, arg2);
163}
164
165
166/*****************************************************************************
167 * Name :
168 * Purpose :
169 * Parameters:
170 * Variables :
171 * Result :
172 * Remark :
173 * Status :
174 *
175 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
176 *****************************************************************************/
177
178int WIN32API lstrncmpA(LPCSTR arg1, LPCSTR arg2, int l)
179{
180 dprintf2(("KERNEL32: OS2lstrncmpA(%s,%s,%d)\n",
181 arg1,
182 arg2,
183 l));
184
185 return strncmp(arg1, arg2, l);
186}
187
188/*****************************************************************************
189 * Name : lstrncmpiA
190 * Purpose :
191 * Parameters:
192 * Variables :
193 * Result :
194 * Remark :
195 * Status :
196 *
197 * Author : Przemyslaw Dobrowolski
198 *****************************************************************************/
199INT WINAPI lstrncmpiA( LPCSTR str1, LPCSTR str2, INT n )
200{
201 INT firstch,lastch;
202 INT result = 0;
203
204 if (n)
205 {
206 do
207 {
208 firstch = tolower(*str1);
209 lastch = tolower(*str2);
210 str1++;
211 str2++;
212 } while (--n && str1 && str2 && firstch == lastch);
213
214 result = firstch - lastch;
215 }
216
217 return(result);
218}
219//TODO: Don't know if this is completely correct
220int WIN32API lstrncmpiW(LPCWSTR str1, LPCWSTR str2, int n)
221{
222 INT firstch,lastch;
223 INT result = 0;
224
225 if (n)
226 {
227 do
228 {
229 firstch = tolowerW(*str1);
230 lastch = tolowerW(*str2);
231 str1++;
232 str2++;
233 } while (--n && str1 && str2 && firstch == lastch);
234
235 result = firstch - lastch;
236 }
237
238 return(result);
239}
240
241/*****************************************************************************
242 * Name :
243 * Purpose :
244 * Parameters:
245 * Variables :
246 * Result :
247 * Remark :
248 * Status :
249 *
250 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
251 *****************************************************************************/
252
253int WIN32API lstrcmpW(LPCWSTR arg1, LPCWSTR arg2)
254{
255 dprintf2(("KERNEL32: lstrcmpW (%08xh, %08xh)\n",
256 arg1,
257 arg2));
258
259 if(arg1 == NULL)
260 return -1;
261 if(arg2 == NULL)
262 return 1;
263
264 return strcmpW( arg1, arg2 );
265}
266
267
268/*****************************************************************************
269 * Name :
270 * Purpose :
271 * Parameters:
272 * Variables :
273 * Result :
274 * Remark :
275 * Status :
276 *
277 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
278 *****************************************************************************/
279
280int WIN32API lstrncmpW(LPCWSTR arg1, LPCWSTR arg2, int l)
281{
282 dprintf2(("KERNEL32: OS2lstrncmpW(%08xh,%08xh,%d)\n",
283 arg1,
284 arg2,
285 l));
286
287 return wcsncmp((wchar_t*)arg1,
288 (wchar_t*)arg2,
289 l);
290}
291
292/*****************************************************************************
293 * Name :
294 * Purpose :
295 * Parameters:
296 * Variables :
297 * Result :
298 * Remark :
299 * Status :
300 *
301 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
302 *****************************************************************************/
303
304LPSTR WIN32API lstrcpyA(LPSTR dest, LPCSTR src)
305{
306 if ( (src == NULL) || (dest == NULL) ) // stupid parameter checking
307 return NULL;
308
309 return strcpy(dest, src);
310}
311
312
313/*****************************************************************************
314 * Name :
315 * Purpose :
316 * Parameters:
317 * Variables :
318 * Result :
319 * Remark :
320 * Status :
321 *
322 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
323 *****************************************************************************/
324
325LPWSTR WIN32API lstrcpyW(LPWSTR dest, LPCWSTR src)
326{
327 if ( (src == NULL) || (dest == NULL) ) // stupid parameter checking
328 return NULL;
329
330 UniStrcpy( (UniChar*)dest,
331 (UniChar*)src );
332 return dest;
333}
334
335
336/*****************************************************************************
337 * Name :
338 * Purpose :
339 * Parameters:
340 * Variables :
341 * Result :
342 * Remark :
343 * Status :
344 *
345 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
346 *****************************************************************************/
347
348LPSTR WIN32API lstrcpynA(LPSTR arg1, LPCSTR arg2, int arg3)
349{
350 register LPSTR p1 = arg1;
351 register LPSTR p2 = (LPSTR)arg2;
352
353 dprintf2(("KERNEL32: OS2lstrcpyA(%08xh, %08xh, %08xh)\n",
354 arg1,
355 arg2,
356 arg3));
357
358 if(arg3 == 0) {
359 return NULL;
360 }
361
362 //PH: looks like either \0 or arg3 terminate the copy
363 //return strncpy(arg1, arg2, arg3);
364 arg3--; // pre-decrement to avoid exceeding buffer length
365 // results in better code than (arg1 > 1)
366
367 for (;*p2 && arg3; arg3--)
368 *p1++ = *p2++;
369
370 *p1 = 0; //CB: copy arg-1, set end 0
371
372 return arg1;
373}
374
375
376/*****************************************************************************
377 * Name :
378 * Purpose :
379 * Parameters:
380 * Variables :
381 * Result :
382 * Remark :
383 * Status :
384 *
385 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
386 *****************************************************************************/
387
388LPWSTR WIN32API lstrcpynW(LPWSTR dest, LPCWSTR src, int arg3)
389{
390 dprintf2(("KERNEL32: lstrcpynW(%08xh,%08xh,%08xh)",
391 dest,
392 src,
393 arg3));
394
395 if (arg3 == 0)
396 return NULL;
397
398 UniStrncpy( (UniChar*)dest,
399 (UniChar*)src,
400 arg3-1); //CB: copy arg3-1 characters
401 dest[arg3-1] = 0; //CB: set end
402 return dest;
403}
404
405
406/*****************************************************************************
407 * Name :
408 * Purpose :
409 * Parameters:
410 * Variables :
411 * Result :
412 * Remark :
413 * Status :
414 *
415 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
416 *****************************************************************************/
417
418int WIN32API lstrcmpiA(LPCSTR arg1, LPCSTR arg2)
419{
420 dprintf2(("KERNEL32: lstrcmpiA(%s,%s)\n",
421 arg1,
422 arg2));
423
424 if(arg1 == NULL)
425 return -1;
426
427 if(arg2 == NULL)
428 return 1;
429
430 return O32_lstrcmpi(arg1, arg2);
431}
432
433
434/*****************************************************************************
435 * Name :
436 * Purpose :
437 * Parameters:
438 * Variables :
439 * Result :
440 * Remark :
441 * Status :
442 *
443 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
444 *****************************************************************************/
445
446int WIN32API lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
447{
448 dprintf2(("KERNEL32: lstrcmpiW(%08xh,%08xh)", str1, str2));
449
450 if (!str1 || !str2) {
451 SetLastError(ERROR_INVALID_PARAMETER);
452 return 0;
453 }
454 return strcmpiW( str1, str2 );
455}
456
457//*****************************************************************************
458//lstrcpynWtoA and lstrcpynAtoW must zero-terminate the string
459//because Wine code depends on this behaviour (i.e. comdlg32)
460//*****************************************************************************
461int WIN32API lstrcpynWtoA(LPSTR astring,
462 LPCWSTR ustring,
463 int length)
464{
465 int ret;
466
467 ret = WideCharToMultiByte(CP_ACP, 0, ustring, -1, astring, length, 0, NULL);
468 //Must not always set the last character to 0; some apps send the wrong
469 //string size to apis that use this function (i.e. GetMenuStringW (Notes))
470 //-> overwrites stack
471 if(ret == length) {
472 astring[length-1] = 0;
473 }
474 else astring[ret] = 0;
475
476 return ret;
477}
478
479//lstrcpynWtoA and lstrcpynAtoW must zero-terminate the string
480//because Wine code depends on this behaviour (i.e. comdlg32)
481int WIN32API lstrcpynAtoW(LPWSTR unicode,
482 LPCSTR ascii,
483 int asciilen)
484{
485 int ret;
486
487 ret = MultiByteToWideChar(CP_ACP, 0, ascii, -1, unicode, asciilen);
488
489 //Must not always set the last character to 0; some apps send the wrong
490 //string size to apis that use this function (i.e. GetMenuStringW (Notes))
491 //-> overwrites stack
492 if(ret == asciilen) {
493 unicode[asciilen-1] = 0;
494 }
495 else unicode[ret] = 0;
496 return ret;
497
498
499}
500
501/*****************************************************************************
502 * Name :
503 * Purpose : Converts unicode string to ascii string
504 * Parameters:
505 * Variables :
506 * Result : returns length of ascii string
507 * Remark :
508 * Status :
509 *
510 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
511 *****************************************************************************/
512
513LPSTR WIN32API lstrcpyWtoA(LPSTR ascii, LPCWSTR unicode)
514{
515 //@@@PH huh? wuz dat?
516 if (unicode == NULL)
517 {
518 DebugInt3();
519 if (ascii != NULL) ((LPWSTR)ascii)[0] = 0; //CB: set at least end
520 return NULL;
521 }
522
523 if (ascii == NULL) {
524 DebugInt3();
525 return NULL; /* garbage in, garbage out ! */
526 }
527
528 /* forward to function with len parameter */
529 lstrcpynWtoA(ascii,
530 unicode,
531 UniStrlen((UniChar*)unicode)+1); //end included
532
533 return ascii;
534}
535
536
537/*****************************************************************************
538 * Name :
539 * Purpose : Copies the full string from ascii to unicode
540 * Parameters:
541 * Variables :
542 * Result :
543 * Remark :
544 * Status :
545 *
546 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
547 *****************************************************************************/
548
549LPWSTR WIN32API lstrcpyAtoW(LPWSTR unicode, LPCSTR ascii)
550{
551 /* achimha for security, strlen might trap if garbage in */
552 /* @@@PH 98/06/07 */
553 if (ascii == NULL)
554 {
555 DebugInt3();
556 if (unicode != NULL) unicode[0] = 0; //CB: set at least end
557 return NULL;
558 }
559
560 if (unicode == NULL) {
561 DebugInt3();
562 return NULL; /* garbage in, garbage out ! */
563 }
564
565 /* forward to call with length parameter */
566 lstrcpynAtoW(unicode, ascii, strlen(ascii)+1); //end included
567 return (unicode);
568}
569
570
571
572
573/*****************************************************************************
574 * Name :
575 * Purpose :
576 * Parameters:
577 * Variables :
578 * Result :
579 * Remark :
580 * Status :
581 *
582 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
583 *****************************************************************************/
584
585LPVOID WIN32API HEAP_xalloc( HANDLE heap, DWORD flags, DWORD size )
586{
587 LPVOID p = HeapAlloc( heap, flags, size );
588 if (!p)
589 {
590 dprintf2(("KERNEL32: HEAP_xalloc(%08xh,%08xh,%08xh) out of memory.\n",
591 heap,
592 flags,
593 size));
594 }
595 return p;
596}
597
598
599/*****************************************************************************
600 * Name :
601 * Purpose :
602 * Parameters:
603 * Variables :
604 * Result :
605 * Remark :
606 * Status :
607 *
608 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
609 *****************************************************************************/
610
611LPVOID WIN32API HEAP_xrealloc( HANDLE heap, DWORD flags, LPVOID lpMem, DWORD size )
612{
613 LPVOID p = HeapReAlloc( heap, flags, lpMem, size );
614 if (!p)
615 {
616 dprintf2(("KERNEL32: HEAP_xrealloc(%08xh,%08xh,%08xh,%08xh) out of memory.\n",
617 heap,
618 flags,
619 lpMem,
620 size));
621 }
622 return p;
623}
624
625
626/*****************************************************************************
627 * Name :
628 * Purpose :
629 * Parameters:
630 * Variables :
631 * Result :
632 * Remark :
633 * Status :
634 *
635 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
636 *****************************************************************************/
637
638LPVOID WIN32API HEAP_malloc(DWORD size )
639{
640 LPVOID p = HeapAlloc( GetProcessHeap(), 0, size );
641 if (!p)
642 {
643 dprintf2(("KERNEL32: HEAP_malloc(%08xh) out of memory.\n",
644 size));
645 }
646 return p;
647}
648
649
650/*****************************************************************************
651 * Name :
652 * Purpose :
653 * Parameters:
654 * Variables :
655 * Result :
656 * Remark :
657 * Status :
658 *
659 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
660 *****************************************************************************/
661
662DWORD WIN32API HEAP_size(LPVOID lpMem)
663{
664 return HeapSize( GetProcessHeap(), 0, lpMem );
665}
666
667
668/*****************************************************************************
669 * Name :
670 * Purpose :
671 * Parameters:
672 * Variables :
673 * Result :
674 * Remark :
675 * Status :
676 *
677 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
678 *****************************************************************************/
679
680LPVOID WIN32API HEAP_realloc(LPVOID lpMem, DWORD size )
681{
682 LPVOID p = HeapReAlloc( GetProcessHeap(), 0, lpMem, size );
683 if (!p)
684 {
685 dprintf2(("KERNEL32: HEAP_realloc(%08xh,%08xh) out of memory.\n",
686 lpMem,
687 size));
688 }
689 return p;
690}
691
692
693/*****************************************************************************
694 * Name :
695 * Purpose :
696 * Parameters:
697 * Variables :
698 * Result :
699 * Remark :
700 * Status :
701 *
702 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
703 *****************************************************************************/
704
705VOID WIN32API HEAP_free(LPVOID lpMem)
706{
707 dprintf2(("KERNEL32: HEAP_free(%08xh)\n",
708 lpMem));
709
710 HeapFree( GetProcessHeap(), 0, lpMem);
711}
712
713
714/*****************************************************************************
715 * Name :
716 * Purpose :
717 * Parameters:
718 * Variables :
719 * Result :
720 * Remark :
721 * Status :
722 *
723 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
724 *****************************************************************************/
725
726LPSTR WIN32API HEAP_strdupA( HANDLE heap, DWORD flags, LPCSTR str )
727{
728 LPSTR p = (LPSTR)HEAP_xalloc( heap, flags, lstrlenA(str) + 1 );
729 lstrcpyA( p, str );
730 return p;
731}
732
733
734/*****************************************************************************
735 * Name :
736 * Purpose :
737 * Parameters:
738 * Variables :
739 * Result :
740 * Remark :
741 * Status :
742 *
743 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
744 *****************************************************************************/
745
746LPWSTR WIN32API HEAP_strdupW( HANDLE heap, DWORD flags, LPCWSTR str )
747{
748 INT len = lstrlenW(str) + 1;
749 LPWSTR p = (LPWSTR)HEAP_xalloc( heap, flags, len * sizeof(WCHAR) );
750 lstrcpyW( p, str );
751 return p;
752}
753
754
755/*****************************************************************************
756 * Name :
757 * Purpose :
758 * Parameters:
759 * Variables :
760 * Result :
761 * Remark :
762 * Status :
763 *
764 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
765 *****************************************************************************/
766
767LPWSTR WIN32API HEAP_strdupAtoW( HANDLE heap, DWORD flags, LPCSTR str )
768{
769 LPWSTR ret;
770 int len;
771
772 if (!str) return NULL;
773
774 len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0);
775 ret = (LPWSTR)HEAP_xalloc( heap, flags, len*sizeof(WCHAR));
776 MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
777
778 return ret;
779}
780
781
782/*****************************************************************************
783 * Name :
784 * Purpose :
785 * Parameters:
786 * Variables :
787 * Result :
788 * Remark :
789 * Status :
790 *
791 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
792 *****************************************************************************/
793
794LPSTR WIN32API HEAP_strdupWtoA( HANDLE heap, DWORD flags, LPCWSTR str )
795{
796 LPSTR ret;
797 int len;
798
799 if (!str) return NULL;
800
801 len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, 0, NULL);
802 ret = (LPSTR)HEAP_xalloc( heap, flags, len);
803 WideCharToMultiByte(CP_ACP, 0, str, -1, ret, len, 0, NULL );
804 return ret;
805}
806
807
808/*****************************************************************************
809 * Name : WideCharToLocal
810 * Purpose : similar lstrcpyWtoA, should handle codepages properly
811 * Parameters:
812 * Variables :
813 * Result : strlen of the destination string
814 * Remark :
815 * Status :
816 *
817 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
818 *****************************************************************************/
819
820INT WIN32API WideCharToLocal(LPSTR pLocal, LPWSTR pWide, INT dwChars)
821{
822 dprintf2(("KERNEL32: WideCharToLocal(%08xh,%08xh,%08xh)\n",
823 pLocal,
824 pWide,
825 dwChars));
826
827 *pLocal = 0;
828 WideCharToMultiByte(CP_ACP,
829 0,
830 pWide,
831 -1,
832 pLocal,
833 dwChars,
834 NULL,
835 NULL);
836
837 return strlen(pLocal);
838}
839
840
841/*****************************************************************************
842 * Name : LocalToWideChar
843 * Purpose : similar lstrcpyAtoW, should handle codepages properly
844 * Parameters:
845 * Variables :
846 * Result : strlen of the destination string
847 * Remark :
848 * Status :
849 *
850 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
851 *****************************************************************************/
852
853INT WIN32API LocalToWideChar(LPWSTR pWide, LPSTR pLocal, INT dwChars)
854{
855 *pWide = 0;
856
857 dprintf2(("KERNEL32: LocalToWideChar(%08xh,%08xh,%08xh)\n",
858 pLocal,
859 pWide,
860 dwChars));
861
862 MultiByteToWideChar(CP_ACP,
863 0,
864 pLocal,
865 -1,
866 pWide,
867 dwChars);
868
869 return lstrlenW(pWide);
870}
871
872
873
Note: See TracBrowser for help on using the repository browser.