Ignore:
Timestamp:
Apr 3, 2001, 7:47:13 PM (24 years ago)
Author:
sandervl
Message:

rewrote string functions with new unicode code

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel32/heapstring.cpp

    r4964 r5457  
    1 /* $Id: heapstring.cpp,v 1.36 2001-01-18 18:14:16 sandervl Exp $ */
     1/* $Id: heapstring.cpp,v 1.37 2001-04-03 17:47:11 sandervl Exp $ */
    22
    33/*
     
    2828#include <wcstr.h>
    2929#include "heap.h"
    30 #include <heapstring.h>
     30#include <wine\unicode.h>
    3131#include "misc.h"
    3232#include "codepage.h"
    3333
    34 #define DBG_LOCALLOG    DBG_heapstring
     34#define DBG_LOCALLOG    DBG_heapstring
    3535#include "dbglocal.h"
    3636
     
    227227    do
    228228    {
    229       firstch = tolower((char)*str1);
    230       lastch = tolower((char)*str2);
     229      firstch = tolowerW(*str1);
     230      lastch = tolowerW(*str2);
    231231      str1++;
    232232      str2++;
     
    262262      return 1;
    263263
    264     return wcscmp( (wchar_t*)arg1,
    265                    (wchar_t*)arg2 );
     264    return strcmpW( arg1, arg2 );
    266265}
    267266
     
    305304LPSTR WIN32API lstrcpyA(LPSTR dest, LPCSTR src)
    306305{
    307   if ( (src == NULL) || (dest == NULL) ) // stupid parameter checking
    308      return NULL;
    309 
    310   return O32_lstrcpy(dest, src);
     306    if ( (src == NULL) || (dest == NULL) ) // stupid parameter checking
     307        return NULL;
     308
     309    return strcpy(dest, src);
    311310}
    312311
     
    326325LPWSTR WIN32API lstrcpyW(LPWSTR dest, LPCWSTR src)
    327326{
    328   if ( (src == NULL) || (dest == NULL) ) // stupid parameter checking
    329      return NULL;
    330 
    331   UniStrcpy( (UniChar*)dest,
    332              (UniChar*)src );
    333   return dest;
     327    if ( (src == NULL) || (dest == NULL) ) // stupid parameter checking
     328        return NULL;
     329
     330    UniStrcpy( (UniChar*)dest,
     331               (UniChar*)src );
     332    return dest;
    334333}
    335334
     
    445444 *****************************************************************************/
    446445
    447 int WIN32API lstrcmpiW(LPCWSTR arg1, LPCWSTR arg2)
    448 {
    449   char *astr1, *astr2;
    450   int   rc;
    451 
    452   dprintf2(("KERNEL32: lstrcmpiW(%08xh,%08xh)\n",
    453            arg1,
    454            arg2));
    455 
    456   if(arg1 == NULL)
    457       return -1;
    458 
    459   if(arg2 == NULL)
    460       return 1;
    461 
    462   // NOTE: This function has no equivalent in uunidef.h
    463   astr1 = UnicodeToAsciiString((LPWSTR)arg1);
    464   astr2 = UnicodeToAsciiString((LPWSTR)arg2);
    465   rc = lstrcmpiA(astr1, astr2);
    466   FreeAsciiString(astr2);
    467   FreeAsciiString(astr1);
    468   return(rc);
    469 }
    470 
    471 
    472 /*****************************************************************************
    473  * Name      :
    474  * Purpose   :
    475  * Parameters:
    476  * Variables :
    477  * Result    :
    478  * Remark    :
    479  * Status    :
    480  *
    481  * Author    : Patrick Haller [Thu, 1999/08/05 20:46]
    482  *****************************************************************************/
    483 
    484 // unilen: length of astring buffer (including 0 terminator)
    485 // returns string length
    486 
    487 int WIN32API lstrcpynCtoA(LPSTR  astring,
    488                           LPCWSTR ustring,
    489                           int    unilen,
    490                           UconvObject uconv_object)
    491 {
    492   int      i;
    493   int      rc;
    494   size_t   uni_chars_left;
    495   size_t   out_bytes_left;
    496   size_t   num_subs;
    497   UniChar* in_buf;
    498   char*    out_buf;
    499 
    500   dprintf2(("KERNEL32: HeapString: lstrcpynWtoA(%08x,%08xh,%d)\n",
    501            astring,
    502            ustring,
    503            unilen));
    504 
    505   if (ustring == NULL)
    506   {
    507     if (astring != NULL && unilen > 0)
    508       astring[0] = 0;
    509     return 0;
    510   }
    511 
    512   if (astring == NULL || unilen <= 0)
    513     return 0;
    514 
    515   if (uconv_object)
    516   {
    517     if (unilen == 1)
    518     {
    519       astring[0] = 0;
    520       return 0; //no data
     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;
    521453    }
    522 
    523     //SvL: Determine length of unicode string
    524     uni_chars_left = UniStrlen((UniChar*)ustring)+1;
    525     uni_chars_left = min(uni_chars_left, unilen);
    526     unilen = uni_chars_left;
    527 
    528     out_bytes_left = uni_chars_left; //size in bytes == elements
    529     in_buf  = (UniChar*)ustring;
    530     out_buf = astring;
    531     rc = UniUconvFromUcs(uconv_object,
    532                          &in_buf, &uni_chars_left,
    533                          (void**)&out_buf, &out_bytes_left,
    534                          &num_subs);
    535    
    536     /* @@@PH 2000/08/10
    537      * this causes the last character in the converted
    538      * target string to be chopped off. I.e. causes CMD.EXE
    539      * to loose the CRLF functionality.
    540      */
    541      /*
    542     unilen -= 1+out_bytes_left; //end + left bytes
    543     astring[unilen] = 0; //terminate
    544     */
    545 
    546     return unilen; //length of string (excluding terminator)
    547   }
    548   else
    549   {
    550     /* idiots unicode conversion :) */
    551     for (i = 0; i < unilen-1; i++)
    552     {
    553       astring[i] = (ustring[i] > 255) ? (char)0x20 : (char)ustring[i]; //CB: handle invalid characters as space
    554       if (ustring[i] == 0) return i; //asta la vista, baby
    555     }
    556 
    557 //    astring[unilen-1] = 0; // @@@PH: 1999/06/09 fix - always terminate string
    558 //    return(unilen-1);
    559     return unilen;
    560   }
    561 }
    562 
     454    return strcmpiW( str1, str2 );
     455}
     456
     457//*****************************************************************************
    563458//lstrcpynWtoA and lstrcpynAtoW must zero-terminate the string
    564459//because Wine code depends on this behaviour (i.e. comdlg32)
    565 int WIN32API lstrcpynWtoA(LPSTR  astring,
     460//*****************************************************************************
     461int WIN32API lstrcpynWtoA(LPSTR   astring,
    566462                          LPCWSTR ustring,
    567                           int    unilen)
     463                          int     length)
    568464{
    569465 int ret;
    570466
    571     ret = lstrcpynCtoA(astring, ustring, unilen, GetWindowsUconvObject());
     467    ret = WideCharToMultiByte(CP_ACP, 0, ustring, -1, astring, length, 0, NULL);
    572468    //Must not always set the last character to 0; some apps send the wrong
    573469    //string size to apis that use this function (i.e. GetMenuStringW (Notes))
    574470    //-> overwrites stack
    575     if(ret == unilen) {
    576          astring[unilen-1] = 0;
     471    if(ret == length) {
     472         astring[length-1] = 0;
    577473    }
    578474    else astring[ret] = 0;
    579    
     475
    580476    return ret;
    581 }
    582 
    583 
    584 /*****************************************************************************
    585  * Name      :
    586  * Purpose   :
    587  * Parameters:
    588  * Variables :
    589  * Result    :
    590  * Remark    :
    591  * Status    :
    592  *
    593  * Author    : Patrick Haller [Thu, 1999/08/05 20:46]
    594  *****************************************************************************/
    595 
    596 // asciilen: max length of unicode buffer (including end 0)
    597 // @@@PH 0 termination is NOT necessarily included !
    598 int lstrcpynAtoC(LPWSTR unicode,
    599                  LPCSTR  ascii,
    600                  int    asciilen,
    601                  UconvObject uconv_object)
    602 {
    603   int      rc;
    604   int      i;
    605   size_t   uni_chars_left;
    606   size_t   in_bytes_left;
    607   size_t   num_subs;
    608   UniChar* out_buf;
    609   char*    in_buf;
    610 
    611   dprintf2(("KERNEL32: HeapString: lstrcpynAtoW(%s,%08xh,%d)\n",
    612            ascii,
    613            unicode,
    614            asciilen));
    615 
    616   //CB: no input, set at least terminator
    617   if (ascii == NULL)
    618   {
    619     if (unicode != NULL && asciilen > 0) unicode[0] = 0;
    620     return 0;
    621   }
    622 
    623   if (unicode == NULL || asciilen <= 0)
    624     return 0; //nothing to do
    625 
    626   if (uconv_object)
    627   {
    628     //@@@PH what's this?
    629     if ((asciilen == 1) && (*ascii == '\0') )
    630     {
    631        unicode[0] = 0;
    632        return 0;
    633     }
    634 
    635     in_buf        = (LPSTR)ascii;
    636 
    637     //@@@PH what's this?
    638     //in_bytes_left = asciilen-1; //buffer size in bytes
    639 
    640     //SvL: Determine length of ascii string
    641     in_bytes_left = strlen(in_buf)+1;
    642     in_bytes_left = asciilen = min(in_bytes_left, asciilen); //buffer size in bytes
    643 
    644     out_buf = (UniChar*)unicode;
    645 
    646     uni_chars_left = in_bytes_left; //elements
    647 
    648     rc = UniUconvToUcs( uconv_object,
    649                         (void**)&in_buf, &in_bytes_left,
    650                         &out_buf,        &uni_chars_left,
    651                         &num_subs );
    652    
    653     /* @@@PH 2000/08/10
    654      * this causes the last character in the converted
    655      * target string to be chopped off. I.e. causes CMD.EXE
    656      * to enter command correctly.
    657      */
    658     /*
    659     asciilen -= 1+uni_chars_left; //end + left bytes
    660 
    661     unicode[asciilen] = 0; // always terminate string
    662     */
    663      
    664     return asciilen; //length of string (excluding terminator)
    665   }
    666   else
    667   { //poor man's conversion
    668 
    669 //    for(i = 0;i < asciilen-1;i++)
    670     for(i = 0;i < asciilen;i++)
    671     {
    672       unicode[i] = ascii[i];
    673       if (ascii[i] == 0)
    674         //return i-1; //work done
    675         return i; //work done
    676     }
    677 
    678 //    unicode[asciilen-1] = 0;
    679 //    return asciilen-1;
    680     return asciilen;
    681   }
    682477}
    683478
     
    690485 int ret;
    691486
    692     ret = lstrcpynAtoC(unicode, ascii, asciilen, GetWindowsUconvObject());
     487    ret = MultiByteToWideChar(CP_ACP, 0, ascii, -1, unicode, asciilen);
     488
    693489    //Must not always set the last character to 0; some apps send the wrong
    694490    //string size to apis that use this function (i.e. GetMenuStringW (Notes))
     
    699495    else unicode[ret] = 0;
    700496    return ret;
     497
     498
    701499}
    702500
     
    715513LPSTR WIN32API lstrcpyWtoA(LPSTR ascii, LPCWSTR unicode)
    716514{
    717   //@@@PH huh? wuz dat?
    718   if (unicode == NULL)
    719   {
    720     if (unicode != NULL) ((LPWSTR)unicode)[0] = 0; //CB: set at least end
    721     return NULL;
    722   }
    723 
    724   if (unicode == NULL)
    725     return NULL;  /* garbage in, garbage out ! */
    726 
    727   /* forward to function with len parameter */
    728   lstrcpynWtoA(ascii,
     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,
    729530               unicode,
    730531               UniStrlen((UniChar*)unicode)+1); //end included
    731532
    732   return ascii;
     533    return ascii;
    733534}
    734535
     
    748549LPWSTR WIN32API lstrcpyAtoW(LPWSTR unicode, LPCSTR ascii)
    749550{
    750   /* achimha for security, strlen might trap if garbage in */
    751   /* @@@PH 98/06/07 */
    752   if (ascii == NULL)
    753   {
    754     if (unicode != NULL) unicode[0] = 0; //CB: set at least end
    755     return NULL;
    756   }
    757 
    758   if (unicode == NULL)
    759     return NULL;  /* garbage in, garbage out ! */
    760 
    761   /* forward to call with length parameter */
    762   lstrcpynAtoW(unicode, ascii, strlen(ascii)+1); //end included
    763   return (unicode);
     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);
    764568}
    765569
     
    922726LPSTR WIN32API HEAP_strdupA( HANDLE heap, DWORD flags, LPCSTR str )
    923727{
    924   LPSTR p = (LPSTR)HEAP_xalloc( heap, flags, strlen(str) + 1 );
    925   strcpy( p, str );
    926   return p;
     728    LPSTR p = (LPSTR)HEAP_xalloc( heap, flags, lstrlenA(str) + 1 );
     729    lstrcpyA( p, str );
     730    return p;
    927731}
    928732
     
    942746LPWSTR WIN32API HEAP_strdupW( HANDLE heap, DWORD flags, LPCWSTR str )
    943747{
    944   INT len = lstrlenW(str) + 1;
    945   LPWSTR p = (LPWSTR)HEAP_xalloc( heap, flags, len * sizeof(WCHAR) );
    946   lstrcpyW( p, str );
    947   return p;
     748    INT len = lstrlenW(str) + 1;
     749    LPWSTR p = (LPWSTR)HEAP_xalloc( heap, flags, len * sizeof(WCHAR) );
     750    lstrcpyW( p, str );
     751    return p;
    948752}
    949753
     
    963767LPWSTR WIN32API HEAP_strdupAtoW( HANDLE heap, DWORD flags, LPCSTR str )
    964768{
    965   LPWSTR ret;
    966 
    967   if (!str) return NULL;
    968   ret = (LPWSTR)HEAP_xalloc( heap, flags, (strlen(str)+1) * sizeof(WCHAR) );
    969   lstrcpyAtoW( ret, (LPSTR)str );
    970   return ret;
     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;
    971779}
    972780
     
    986794LPSTR WIN32API HEAP_strdupWtoA( HANDLE heap, DWORD flags, LPCWSTR str )
    987795{
    988   LPSTR ret;
    989 
    990   if (!str) return NULL;
    991   ret = (LPSTR)HEAP_xalloc( heap, flags, lstrlenW(str) + 1 );
    992   lstrcpyWtoA( ret, (LPWSTR)str );
    993   return ret;
     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;
    994805}
    995806
     
    1061872
    1062873
    1063 
    1064 
    1065 
    1066 #if 0
    1067 
    1068 
    1069 /*****************************************************************************
    1070  * Name      :
    1071  * Purpose   :
    1072  * Parameters:
    1073  * Variables :
    1074  * Result    :
    1075  * Remark    :
    1076  * Status    :
    1077  *
    1078  * Author    : Patrick Haller [Thu, 1999/08/05 20:46]
    1079  *****************************************************************************/
    1080 
    1081 // Converts unicode string to ascii string
    1082 // returns pointer to ascii string
    1083 char * WIN32API UnicodeToAsciiString(WCHAR *ustring)
    1084 {
    1085   char *astring;
    1086 
    1087   if(ustring == NULL)  return(NULL);
    1088 
    1089   astring = (char *)malloc( 1 + UniStrlen((UniChar*)ustring) );
    1090   UnicodeToAscii( ustring, astring );
    1091   return(astring);
    1092 }
    1093 
    1094 
    1095 /*****************************************************************************
    1096  * Name      :
    1097  * Purpose   :
    1098  * Parameters:
    1099  * Variables :
    1100  * Result    :
    1101  * Remark    :
    1102  * Status    :
    1103  *
    1104  * Author    : Patrick Haller [Thu, 1999/08/05 20:46]
    1105  *****************************************************************************/
    1106 
    1107 // Converts ascii string to unicode string
    1108 // returns pointer to unicode string
    1109 WCHAR * WIN32API AsciiToUnicodeString(char *astring)
    1110 {
    1111   WCHAR *ustring;
    1112 
    1113   if(astring == NULL)
    1114     return(NULL);
    1115 
    1116   ustring = (WCHAR *)malloc( 1 + strlen(astring) << 1 );
    1117   AsciiToUnicode( astring, ustring );
    1118   return(ustring);
    1119 }
    1120 
    1121 #endif
    1122 
    1123 
    1124 
    1125 /**************************************************************************
    1126  *           This function is used just locally !
    1127  *  Description: Inverts a string.
    1128  */
    1129 static void OLE_InvertString(char* string)
    1130 {   
    1131     char    sTmpArray[128];
    1132     INT     counter, i = 0;
    1133 
    1134     for (counter = strlen(string); counter > 0; counter--)
    1135     {
    1136         memcpy(sTmpArray + i, string + counter-1, 1);
    1137         i++;
    1138     }
    1139     memcpy(sTmpArray + i, "\0", 1);
    1140     strcpy(string, sTmpArray);
    1141 }
    1142 
    1143 /***************************************************************************************
    1144  *           This function is used just locally !
    1145  *  Description: Test if the given string (psNumber) is valid or not.
    1146  *               The valid characters are the following:
    1147  *               - Characters '0' through '9'.
    1148  *               - One decimal point (dot) if the number is a floating-point value.
    1149  *               - A minus sign in the first character position if the number is
    1150  *                 a negative value.
    1151  *              If the function succeeds, psBefore/psAfter will point to the string
    1152  *              on the right/left of the decimal symbol. pbNegative indicates if the
    1153  *              number is negative.
    1154  */
    1155 static INT OLE_GetNumberComponents(char* pInput, char* psBefore, char* psAfter, BOOL* pbNegative)
    1156 {
    1157 char    sNumberSet[] = "0123456789";
    1158 BOOL    bInDecimal = FALSE;
    1159 
    1160         /* Test if we do have a minus sign */
    1161         if ( *pInput == '-' )
    1162         {
    1163                 *pbNegative = TRUE;
    1164                 pInput++; /* Jump to the next character. */
    1165         }
    1166        
    1167         while(*pInput != '\0')
    1168         {
    1169                 /* Do we have a valid numeric character */
    1170                 if ( strchr(sNumberSet, *pInput) != NULL )
    1171                 {
    1172                         if (bInDecimal == TRUE)
    1173                 *psAfter++ = *pInput;
    1174                         else
    1175                 *psBefore++ = *pInput;
    1176                 }
    1177                 else
    1178                 {
    1179                         /* Is this a decimal point (dot) */
    1180                         if ( *pInput == '.' )
    1181                         {
    1182                                 /* Is it the first time we find it */
    1183                                 if ((bInDecimal == FALSE))
    1184                                         bInDecimal = TRUE;
    1185                                 else
    1186                                         return -1; /* ERROR: Invalid parameter */
    1187                         }
    1188                         else
    1189                         {
    1190                                 /* It's neither a numeric character, nor a decimal point.
    1191                                  * Thus, return an error.
    1192                  */
    1193                                 return -1;
    1194                         }
    1195                 }
    1196         pInput++;
    1197         }
    1198        
    1199         /* Add an End of Line character to the output buffers */
    1200         *psBefore = '\0';
    1201         *psAfter = '\0';
    1202 
    1203         return 0;
    1204 }
    1205 
    1206 /**************************************************************************
    1207  *           This function is used just locally !
    1208  *  Description: A number could be formatted using different numbers
    1209  *               of "digits in group" (example: 4;3;2;0).
    1210  *               The first parameter of this function is an array
    1211  *               containing the rule to be used. It's format is the following:
    1212  *               |NDG|DG1|DG2|...|0|
    1213  *               where NDG is the number of used "digits in group" and DG1, DG2,
    1214  *               are the corresponding "digits in group".
    1215  *               Thus, this function returns the grouping value in the array
    1216  *               pointed by the second parameter.
    1217  */
    1218 static INT OLE_GetGrouping(char* sRule, INT index)
    1219 {
    1220     char    sData[2], sRuleSize[2];
    1221     INT     nData, nRuleSize;
    1222 
    1223     memcpy(sRuleSize, sRule, 1);
    1224     memcpy(sRuleSize+1, "\0", 1);
    1225     nRuleSize = atoi(sRuleSize);
    1226 
    1227     if (index > 0 && index < nRuleSize)
    1228     {
    1229         memcpy(sData, sRule+index, 1);
    1230         memcpy(sData+1, "\0", 1);
    1231         nData = atoi(sData);           
    1232     }
    1233        
    1234     else
    1235     {
    1236         memcpy(sData, sRule+nRuleSize-1, 1);
    1237         memcpy(sData+1, "\0", 1);
    1238         nData = atoi(sData);           
    1239     }
    1240    
    1241     return nData;
    1242 }
Note: See TracChangeset for help on using the changeset viewer.