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

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

Fix: lstrcpyAtoW bug

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