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

Last change on this file since 567 was 567, checked in by phaller, 26 years ago

Add: lstrncmpA, lstrncmpW added

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