Code/Resource
Windows Develop
Linux-Unix program
Internet-Socket-Network
Web Server
Browser Client
Ftp Server
Ftp Client
Browser Plugins
Proxy Server
Email Server
Email Client
WEB Mail
Firewall-Security
Telnet Server
Telnet Client
ICQ-IM-Chat
Search Engine
Sniffer Package capture
Remote Control
xml-soap-webservice
P2P
WEB(ASP,PHP,...)
TCP/IP Stack
SNMP
Grid Computing
SilverLight
DNS
Cluster Service
Network Security
Communication-Mobile
Game Program
Editor
Multimedia program
Graph program
Compiler program
Compress-Decompress algrithms
Crypt_Decrypt algrithms
Mathimatics-Numerical algorithms
MultiLanguage
Disk/Storage
Java Develop
assembly language
Applications
Other systems
Database system
Embeded-SCM Develop
FlashMX/Flex
source in ebook
Delphi VCL
OS Develop
MiddleWare
MPI
MacOS develop
LabView
ELanguage
Software/Tools
E-Books
Artical/Document
strings.c
Package: shell.rar [view]
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 28k
Category:
Windows Kernel
Development Platform:
Visual C++
- //============================================================================
- //
- // DBCS aware string routines...
- //
- //
- //============================================================================
- //#if defined(UNIX) && !defined(UNICODE)
- //#define UNICODE
- //#endif
- #include "ctlspriv.h"
- #ifdef WINNT
- #include <winnlsp.h> // Get private NORM_ flag for StrEqIntl()
- #endif
- // for those of us who don't ssync to nt's build headers
- #ifndef NORM_STOP_ON_NULL
- #define NORM_STOP_ON_NULL 0x10000000
- #endif
- // WARNING: all of these APIs do not setup DS, so you can not access
- // any data in the default data seg of this DLL.
- //
- // do not create any global variables... talk to chrisg if you don't
- // understand thid
- #ifdef UNIX
- #ifdef BIG_ENDIAN
- #define READNATIVEWORD(x) MAKEWORD(*(char*)(x), *(char*)((char*)(x) + 1))
- #else
- #define READNATIVEWORD(x) MAKEWORD(*(char*)((char*)(x) + 1), *(char*)(x))
- #endif
- #else
- #define READNATIVEWORD(x) (*(UNALIGNED WORD *)x)
- #endif
- /*
- * StrEndN - Find the end of a string, but no more than n bytes
- * Assumes lpStart points to start of null terminated string
- * nBufSize is the maximum length
- * returns ptr to just after the last byte to be included
- */
- LPSTR lstrfns_StrEndNA(LPCSTR lpStart, int nBufSize)
- {
- LPCSTR lpEnd;
- for (lpEnd = lpStart + nBufSize; *lpStart && OFFSETOF(lpStart) < OFFSETOF(lpEnd);
- lpStart = AnsiNext(lpStart))
- continue; /* just getting to the end of the string */
- if (OFFSETOF(lpStart) > OFFSETOF(lpEnd))
- {
- /* We can only get here if the last byte before lpEnd was a lead byte
- */
- lpStart -= 2;
- }
- return((LPSTR)lpStart);
- }
- LPWSTR lstrfns_StrEndNW(LPCWSTR lpStart, int nBufSize)
- {
- #ifdef UNICODE
- LPCWSTR lpEnd;
- for (lpEnd = lpStart + nBufSize; *lpStart && (lpStart < lpEnd);
- lpStart++)
- continue; /* just getting to the end of the string */
- return((LPWSTR)lpStart);
- #else
- SetLastErrorEx(ERROR_CALL_NOT_IMPLEMENTED, SLE_WARNING);
- return NULL;
- #endif
- }
- // REVIEW WIN32 HACK - Convert to 32bit asm.
- #ifndef WIN32
- /*
- * ReverseScan - Find last occurrence of a byte in a string
- * Assumes lpSource points to first byte to check (end of the string)
- * uLen is the number of bytes to check
- * bMatch is the byte to match
- * returns ptr to the last occurrence of ch in str, NULL if not found.
- */
- LPSTR PASCAL ReverseScan(LPCSTR lpSource, UINT uLen, BYTE bMatch)
- {
- _asm
- {
- /* Load count */
- mov cx,uLen
- jcxz ReverseScanFail ; count is zero, return failure.
- /* Load up es:di, ax */
- les di,lpSource
- mov al,bMatch
- /* Set the direction flag based on bBackward
- * Perform the search; return 0 if we reached the end of the string
- * otherwise, return es:di+1
- */
- std
- repne scasb
- jne ReverseScanFail ; check result of last compare.
- inc di
- mov dx,es
- mov ax,di
- jmp ReverseScanExit
- ReverseScanFail:
- xor ax,ax
- xor dx,dx
- /* clear the direction flag and return
- */
- ReverseScanExit:
- cld
- }
- if (0) return 0; // suppress warning, optimized out
- }
- #endif
- /*
- * ChrCmp - Case sensitive character comparison for DBCS
- * Assumes w1, wMatch are characters to be compared
- * Return FALSE if they match, TRUE if no match
- */
- __inline BOOL ChrCmpA_inline(WORD w1, WORD wMatch)
- {
- /* Most of the time this won't match, so test it first for speed.
- */
- if (LOBYTE(w1) == LOBYTE(wMatch))
- {
- if (IsDBCSLeadByte(LOBYTE(w1)))
- {
- return(w1 != wMatch);
- }
- return FALSE;
- }
- return TRUE;
- }
- BOOL ChrCmpA(WORD w1, WORD wMatch)
- {
- return ChrCmpA_inline(w1, wMatch);
- }
- #ifdef UNICODE
- __inline BOOL ChrCmpW_inline(WCHAR w1, WCHAR wMatch)
- {
- return(!(w1 == wMatch));
- }
- #endif
- BOOL ChrCmpW(WCHAR w1, WCHAR wMatch)
- {
- #ifdef UNICODE
- return ChrCmpW_inline(w1, wMatch);
- #else
- SetLastErrorEx(ERROR_CALL_NOT_IMPLEMENTED, SLE_WARNING);
- return FALSE;
- #endif
- }
- /*
- * ChrCmpI - Case insensitive character comparison for DBCS
- * Assumes w1, wMatch are characters to be compared;
- * HIBYTE of wMatch is 0 if not a DBC
- * Return FALSE if match, TRUE if not
- */
- BOOL ChrCmpIA(WORD w1, WORD wMatch)
- {
- char sz1[3], sz2[3];
- if (IsDBCSLeadByte(sz1[0] = LOBYTE(w1)))
- {
- sz1[1] = HIBYTE(w1);
- sz1[2] = '';
- }
- else
- sz1[1] = '';
- #if defined(BIG_ENDIAN)
- sz2[0] = LOBYTE(wMatch);
- sz2[1] = HIBYTE(wMatch);
- #else
- *(WORD FAR *)sz2 = wMatch;
- #endif
- sz2[2] = '';
- return lstrcmpiA(sz1, sz2);
- }
- BOOL ChrCmpIW(WCHAR w1, WCHAR wMatch)
- {
- #ifdef UNICODE
- WCHAR sz1[2], sz2[2];
- sz1[0] = w1;
- sz1[1] = TEXT('');
- sz2[0] = wMatch;
- sz2[1] = TEXT('');
- return lstrcmpiW(sz1, sz2);
- #else
- SetLastErrorEx(ERROR_CALL_NOT_IMPLEMENTED, SLE_WARNING);
- return FALSE;
- #endif
- }
- LPWSTR StrCpyW(LPWSTR psz1, LPCWSTR psz2)
- {
- LPWSTR psz = psz1;
- do {
- *psz1 = *psz2;
- psz1++;
- } while(*psz2++);
- return psz;
- }
- LPWSTR StrCpyNW(LPWSTR psz1, LPCWSTR psz2, int cchMax)
- {
- LPWSTR psz = psz1;
- ASSERT(psz1);
- ASSERT(psz2);
- if (0 < cchMax)
- {
- // Leave room for the null terminator
- while (0 < --cchMax)
- {
- if ( !(*psz1++ = *psz2++) )
- break;
- }
- if (0 == cchMax)
- *psz1 = '';
- }
- return psz;
- }
- /*
- * StrChr - Find first occurrence of character in string
- * Assumes lpStart points to start of null terminated string
- * wMatch is the character to match
- * returns ptr to the first occurrence of ch in str, NULL if not found.
- */
- LPSTR FAR PASCAL StrChrA(LPCSTR lpStart, WORD wMatch)
- {
- for ( ; *lpStart; lpStart = AnsiNext(lpStart))
- {
- if (!ChrCmpA_inline(READNATIVEWORD(lpStart), wMatch))
- {
- return((LPSTR)lpStart);
- }
- }
- return (NULL);
- }
- #ifdef ALIGNMENT_SCENARIO
- LPWSTR StrChrSlowW(const UNALIGNED WCHAR *lpStart, WCHAR wMatch)
- {
- for ( ; *lpStart; lpStart++)
- {
- if (!ChrCmpW_inline(*lpStart, wMatch))
- {
- return((LPWSTR)lpStart);
- }
- }
- }
- #endif
- LPWSTR FAR PASCAL StrChrW(LPCWSTR lpStart, WCHAR wMatch)
- {
- #ifdef UNICODE
- //
- // BUGBUG raymondc
- // Apparently, somebody is passing unaligned strings to StrChrW.
- // Find out who and make them stop.
- //
- ASSERT(!((ULONG_PTR)lpStart & 1)); // Assert alignedness
- #ifdef ALIGNMENT_SCENARIO
- //
- // Since unaligned strings arrive so rarely, put the slow
- // version in a separate function so the common case stays
- // fast. Believe it or not, we call StrChrW so often that
- // it is now a performance-sensitive function!
- //
- if ((ULONG_PTR)lpStart & 1)
- return StrChrSlowW(lpStart, wMatch);
- #endif
- for ( ; *lpStart; lpStart++)
- {
- if (!ChrCmpW_inline(*lpStart, wMatch))
- {
- return((LPWSTR)lpStart);
- }
- }
- return (NULL);
- #else
- SetLastErrorEx(ERROR_CALL_NOT_IMPLEMENTED, SLE_WARNING);
- return NULL;
- #endif
- }
- /*
- * StrRChr - Find last occurrence of character in string
- * Assumes lpStart points to start of string
- * lpEnd points to end of string (NOT included in search)
- * wMatch is the character to match
- * returns ptr to the last occurrence of ch in str, NULL if not found.
- */
- LPSTR FAR PASCAL StrRChrA(LPCSTR lpStart, LPCSTR lpEnd, WORD wMatch)
- {
- LPCSTR lpFound = NULL;
- if (!lpEnd)
- lpEnd = lpStart + lstrlenA(lpStart);
- for ( ; OFFSETOF(lpStart) < OFFSETOF(lpEnd); lpStart = AnsiNext(lpStart))
- {
- if (!ChrCmpA_inline(READNATIVEWORD(lpStart), wMatch))
- lpFound = lpStart;
- }
- return ((LPSTR)lpFound);
- }
- LPWSTR FAR PASCAL StrRChrW(LPCWSTR lpStart, LPCWSTR lpEnd, WCHAR wMatch)
- {
- #ifdef UNICODE
- LPCWSTR lpFound = NULL;
- if (!lpEnd)
- lpEnd = lpStart + lstrlenW(lpStart);
- for ( ; lpStart < lpEnd; lpStart++)
- {
- if (!ChrCmpW_inline(*lpStart, wMatch))
- lpFound = lpStart;
- }
- return ((LPWSTR)lpFound);
- #else
- SetLastErrorEx(ERROR_CALL_NOT_IMPLEMENTED, SLE_WARNING);
- return NULL;
- #endif
- }
- /*
- * StrRChrI - Find last occurrence of character in string, case insensitive
- * Assumes lpStart points to start of string
- * lpEnd points to end of string (NOT included in search)
- * wMatch is the character to match
- * returns ptr to the last occurrence of ch in str, NULL if not found.
- */
- LPSTR FAR PASCAL StrRChrIA(LPCSTR lpStart, LPCSTR lpEnd, WORD wMatch)
- {
- LPCSTR lpFound = NULL;
- if (!lpEnd)
- lpEnd = lpStart + lstrlenA(lpStart);
- wMatch = (UINT)(IsDBCSLeadByte(LOBYTE(wMatch)) ? wMatch : LOBYTE(wMatch));
- for ( ; OFFSETOF(lpStart) < OFFSETOF(lpEnd); lpStart = AnsiNext(lpStart))
- {
- if (!ChrCmpIA(READNATIVEWORD(lpStart), wMatch))
- lpFound = lpStart;
- }
- return ((LPSTR)lpFound);
- }
- LPWSTR FAR PASCAL StrRChrIW(LPCWSTR lpStart, LPCWSTR lpEnd, WCHAR wMatch)
- {
- #ifdef UNICODE
- LPCWSTR lpFound = NULL;
- if (!lpEnd)
- lpEnd = lpStart + lstrlenW(lpStart);
- for ( ; lpStart < lpEnd; lpStart++)
- {
- if (!ChrCmpIW(*lpStart, wMatch))
- lpFound = lpStart;
- }
- return ((LPWSTR)lpFound);
- #else
- SetLastErrorEx(ERROR_CALL_NOT_IMPLEMENTED, SLE_WARNING);
- return NULL;
- #endif
- }
- // StrCSpn: return index to first char of lpStr that is present in lpSet.
- // Includes the NUL in the comparison; if no lpSet chars are found, returns
- // the index to the NUL in lpStr.
- // Just like CRT strcspn.
- //
- int FAR PASCAL StrCSpnA(LPCSTR lpStr, LPCSTR lpSet)
- {
- // nature of the beast: O(lpStr*lpSet) work
- LPCSTR lp = lpStr;
- if (!lpStr || !lpSet)
- return 0;
- while (*lp)
- {
- if (StrChrA(lpSet, READNATIVEWORD(lp)))
- return (int)(lp-lpStr);
- lp = AnsiNext(lp);
- }
- return (int)(lp-lpStr); // ==lstrlen(lpStr)
- }
- int FAR PASCAL StrCSpnW(LPCWSTR lpStr, LPCWSTR lpSet)
- {
- #ifdef UNICODE
- // nature of the beast: O(lpStr*lpSet) work
- LPCWSTR lp = lpStr;
- if (!lpStr || !lpSet)
- return 0;
- while (*lp)
- {
- if (StrChrW(lpSet, *lp))
- return (int)(lp-lpStr);
- lp++;
- }
- return (int)(lp-lpStr); // ==lstrlen(lpStr)
- #else
- SetLastErrorEx(ERROR_CALL_NOT_IMPLEMENTED, SLE_WARNING);
- return -1;
- #endif
- }
- // StrCSpnI: case-insensitive version of StrCSpn.
- //
- int FAR PASCAL StrCSpnIA(LPCSTR lpStr, LPCSTR lpSet)
- {
- // nature of the beast: O(lpStr*lpSet) work
- LPCSTR lp = lpStr;
- if (!lpStr || !lpSet)
- return 0;
- while (*lp)
- {
- if (StrChrIA(lpSet, READNATIVEWORD(lp)))
- return (int)(lp-lpStr);
- lp = AnsiNext(lp);
- }
- return (int)(lp-lpStr); // ==lstrlen(lpStr)
- }
- int FAR PASCAL StrCSpnIW(LPCWSTR lpStr, LPCWSTR lpSet)
- {
- #ifdef UNICODE
- // nature of the beast: O(lpStr*lpSet) work
- LPCWSTR lp = lpStr;
- if (!lpStr || !lpSet)
- return 0;
- while (*lp)
- {
- if (StrChrIW(lpSet, *lp))
- return (int)(lp-lpStr);
- lp++;
- }
- return (int)(lp-lpStr); // ==lstrlen(lpStr)
- #else
- SetLastErrorEx(ERROR_CALL_NOT_IMPLEMENTED, SLE_WARNING);
- return -1;
- #endif
- }
- /*
- * StrCmpN - Compare n bytes
- *
- * returns See lstrcmp return values.
- * BUGBUG, won't work if source strings are in ROM
- */
- int FAR PASCAL StrCmpNA(LPCSTR lpStr1, LPCSTR lpStr2, int nChar)
- {
- char sz1[4];
- char sz2[4];
- LPCSTR lpszEnd = lpStr1 + nChar;
- //DebugMsg(DM_TRACE, "StrCmpN: %s %s %d returns:", lpStr1, lpStr2, nChar);
- for ( ; (lpszEnd > lpStr1) && (*lpStr1 || *lpStr2); lpStr1 = AnsiNext(lpStr1), lpStr2 = AnsiNext(lpStr2)) {
- WORD wMatch;
- wMatch = (WORD) (*lpStr2 | (*(lpStr2+1)<<8));
- if (ChrCmpA_inline(READNATIVEWORD(lpStr1), wMatch)) {
- int iRet;
- (*(WORD FAR *)sz1) = READNATIVEWORD(lpStr1);
- (*(WORD FAR *)sz2) = wMatch;
- #ifndef UNIX
- *AnsiNext(sz1) = 0;
- *AnsiNext(sz2) = 0;
- #else
- *AnsiNext((LPWORD)sz1) = 0;
- *AnsiNext((LPWORD)sz2) = 0;
- #endif
- iRet = lstrcmpA(sz1, sz2);
- //DebugMsg(DM_TRACE, ".................... %d", iRet);
- return iRet;
- }
- }
- //DebugMsg(DM_TRACE, ".................... 0");
- return 0;
- }
- int FAR PASCAL StrCmpNW(LPCWSTR lpStr1, LPCWSTR lpStr2, int nChar)
- {
- #ifdef UNICODE
- WCHAR sz1[2];
- WCHAR sz2[2];
- int i;
- LPCWSTR lpszEnd = lpStr1 + nChar;
- //DebugMsg(DM_TRACE, "StrCmpN: %s %s %d returns:", lpStr1, lpStr2, nChar);
- for ( ; (lpszEnd > lpStr1) && (*lpStr1 || *lpStr2); lpStr1++, lpStr2++) {
- i = ChrCmpW_inline(*lpStr1, *lpStr2);
- if (i) {
- int iRet;
- sz1[0] = *lpStr1;
- sz2[0] = *lpStr2;
- sz1[1] = TEXT('');
- sz2[1] = TEXT('');
- iRet = lstrcmpW(sz1, sz2);
- //DebugMsg(DM_TRACE, ".................... %d", iRet);
- return iRet;
- }
- }
- //DebugMsg(DM_TRACE, ".................... 0");
- return 0;
- #else
- SetLastErrorEx(ERROR_CALL_NOT_IMPLEMENTED, SLE_WARNING);
- return -1;
- #endif
- }
- /*
- * StrCmpNI - Compare n bytes, case insensitive
- *
- * returns See lstrcmpi return values.
- */
- #ifndef WINNT
- __inline BOOL IsAsciiA(char ch)
- {
- return !(ch & 0x80);
- }
- __inline char Ascii_ToLowerA(char ch)
- {
- return (ch >= 'A' && ch <= 'Z') ? (ch - 'A' + 'a') : ch;
- }
- #ifdef UNICODE
- __inline BOOL IsAsciiW(WCHAR ch)
- {
- return ch < 128;
- }
- __inline WCHAR Ascii_ToLowerW(WCHAR ch)
- {
- return (ch >= L'A' && ch <= L'Z') ? (ch - L'A' + L'a') : ch;
- }
- #endif
- int FAR PASCAL StrCmpNIA(LPCSTR lpStr1, LPCSTR lpStr2, int nChar)
- {
- int i;
- LPCSTR lpszEnd = lpStr1 + nChar;
- //DebugMsg(DM_TRACE, "StrCmpNI: %s %s %d returns:", lpStr1, lpStr2, nChar);
- for ( ; (lpszEnd > lpStr1) && (*lpStr1 || *lpStr2); (lpStr1 = AnsiNext(lpStr1)), (lpStr2 = AnsiNext(lpStr2))) {
- WORD wMatch;
- if (IsAsciiA(*lpStr1) && IsAsciiA(*lpStr2))
- {
- i = Ascii_ToLowerA(*lpStr1) - Ascii_ToLowerA(*lpStr2);
- }
- else
- {
- #ifndef UNIX
- wMatch = (UINT)(IsDBCSLeadByte(*lpStr2)) ? *(WORD FAR *)lpStr2 : (WORD)(BYTE)(*lpStr2);
- #else
- wMatch = (UINT)(IsDBCSLeadByte(*lpStr2)) ? (*lpStr2 | (*(lpStr2+1)<<8)) : (WORD)(BYTE)(*lpStr2);
- #endif
- i = ChrCmpIA(READNATIVEWORD(lpStr1), wMatch);
- }
- if (i) {
- //DebugMsg(DM_TRACE, ".................... %d", i);
- if (i < 0)
- {
- return -1;
- }
- else
- {
- return 1;
- }
- }
- }
- //DebugMsg(DM_TRACE, ".................... 0");
- return 0;
- }
- int FAR PASCAL StrCmpNIW(LPCWSTR lpStr1, LPCWSTR lpStr2, int nChar)
- {
- #ifdef UNICODE
- int i;
- LPCWSTR lpszEnd = lpStr1 + nChar;
- //DebugMsg(DM_TRACE, "StrCmpNI: %s %s %d returns:", lpStr1, lpStr2, nChar);
- for ( ; (lpszEnd > lpStr1) && (*lpStr1 || *lpStr2); lpStr1++, lpStr2++) {
- if (IsAsciiW(*lpStr1) && IsAsciiW(*lpStr2))
- {
- i = Ascii_ToLowerW(*lpStr1) - Ascii_ToLowerW(*lpStr2);
- }
- else
- {
- i = ChrCmpIW(*lpStr1, *lpStr2);
- }
- if (i) {
- //DebugMsg(DM_TRACE, ".................... %d", i);
- if (i < 0)
- {
- return -1;
- }
- else
- {
- return 1;
- }
- return i;
- }
- }
- //DebugMsg(DM_TRACE, ".................... 0");
- return 0;
- #else
- SetLastErrorEx(ERROR_CALL_NOT_IMPLEMENTED, SLE_WARNING);
- return -1;
- #endif
- }
- #else // WINNT
- int StrCmpNIA(LPCSTR lpStr1, LPCSTR lpStr2, int nChar)
- {
- int i;
- // Win95 doesn't support NORM_STOP_ON_NULL
- i = CompareStringA(GetThreadLocale(), NORM_IGNORECASE | NORM_STOP_ON_NULL,
- lpStr1, nChar, lpStr2, nChar);
- if (!i)
- {
- i = CompareStringA(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
- lpStr1, nChar, lpStr2, nChar);
- }
- return i - CSTR_EQUAL;
- }
- int StrCmpNIW(LPCWSTR lpStr1, LPCWSTR lpStr2, int nChar)
- {
- int i;
- // Win95 doesn't support NORM_STOP_ON_NULL
- i = CompareStringW(GetThreadLocale(), NORM_IGNORECASE | NORM_STOP_ON_NULL,
- lpStr1, nChar, lpStr2, nChar);
- if (!i)
- {
- i = CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
- lpStr1, nChar, lpStr2, nChar);
- }
- return i - CSTR_EQUAL;
- }
- #endif // WINNT
- /*
- * IntlStrEq
- *
- * returns TRUE if strings are equal, FALSE if not
- */
- BOOL IntlStrEqWorkerA(BOOL fCaseSens, LPCSTR lpString1, LPCSTR lpString2, int nChar) {
- int retval;
- DWORD dwFlags = fCaseSens ? LOCALE_USE_CP_ACP : (NORM_IGNORECASE | LOCALE_USE_CP_ACP);
- #ifdef WINNT
- //
- // On NT we can tell CompareString to stop at a '' if one is found before nChar chars
- //
- dwFlags |= NORM_STOP_ON_NULL;
- #else
- //
- // On Win9x we have to do the check manually
- //
- if (nChar != -1) {
- LPCSTR psz1, psz2;
- int cch = 0;
- psz1 = lpString1;
- psz2 = lpString2;
- while( *psz1 != '' && *psz2 != '' && cch < nChar) {
- #ifdef DBCS
- psz1 = CharNextA(psz1);
- psz2 = CharNextA(psz2);
- cch = min(psz1 - lpString1, psz2 - lpString2);
- #else
- psz1++;
- psz2++;
- cch++;
- #endif
- }
- // add one in for terminating ''
- cch++;
- if (cch < nChar) {
- nChar = cch;
- }
- }
- #endif
- retval = CompareStringA( GetThreadLocale(),
- dwFlags,
- lpString1,
- nChar,
- lpString2,
- nChar );
- if (retval == 0)
- {
- //
- // The caller is not expecting failure. Try the system
- // default locale id.
- //
- retval = CompareStringA( GetSystemDefaultLCID(),
- dwFlags,
- lpString1,
- nChar,
- lpString2,
- nChar );
- }
- if (retval == 0)
- {
- if (lpString1 && lpString2)
- {
- //
- // The caller is not expecting failure. We've never had a
- // failure indicator before. We'll do a best guess by calling
- // the C runtimes to do a non-locale sensitive compare.
- //
- if (fCaseSens)
- retval = StrCmpNA(lpString1, lpString2, nChar) + 2;
- else {
- retval = StrCmpNIA(lpString1, lpString2, nChar) + 2;
- }
- }
- else
- {
- retval = 2;
- }
- }
- return (retval == 2);
- }
- BOOL IntlStrEqWorkerW(BOOL fCaseSens, LPCWSTR lpString1, LPCWSTR lpString2, int nChar) {
- #ifdef UNICODE
- int retval;
- DWORD dwFlags = fCaseSens ? 0 : NORM_IGNORECASE;
- #ifdef WINNT
- //
- // On NT we can tell CompareString to stop at a '' if one is found before nChar chars
- //
- dwFlags |= NORM_STOP_ON_NULL;
- #else
- //
- // On Win9x we have to do the check manually
- //
- if (nChar != -1) {
- LPCWSTR psz1, psz2;
- int cch = 0;
- psz1 = lpString1;
- psz2 = lpString2;
- while( *psz1 != TEXT('') && *psz2 != TEXT('') && cch < nChar) {
- psz1++;
- psz2++;
- cch++;
- }
- // add one in for terminating ''
- cch++;
- if (cch < nChar) {
- nChar = cch;
- }
- }
- #endif
- retval = CompareStringW( GetThreadLocale(),
- dwFlags,
- lpString1,
- nChar,
- lpString2,
- nChar );
- if (retval == 0)
- {
- //
- // The caller is not expecting failure. Try the system
- // default locale id.
- //
- retval = CompareStringW( GetSystemDefaultLCID(),
- dwFlags,
- lpString1,
- nChar,
- lpString2,
- nChar );
- }
- if (retval == 0)
- {
- if (lpString1 && lpString2)
- {
- //
- // The caller is not expecting failure. We've never had a
- // failure indicator before. We'll do a best guess by calling
- // the C runtimes to do a non-locale sensitive compare.
- //
- if (fCaseSens)
- retval = StrCmpNW(lpString1, lpString2, nChar) + 2;
- else {
- retval = StrCmpNIW(lpString1, lpString2, nChar) + 2;
- }
- }
- else
- {
- retval = 2;
- }
- }
- return (retval == 2);
- #else
- SetLastErrorEx(ERROR_CALL_NOT_IMPLEMENTED, SLE_WARNING);
- return FALSE;
- #endif
- }
- /*
- * StrRStrI - Search for last occurrence of a substring
- *
- * Assumes lpSource points to the null terminated source string
- * lpLast points to where to search from in the source string
- * lpLast is not included in the search
- * lpSrch points to string to search for
- * returns last occurrence of string if successful; NULL otherwise
- */
- LPSTR FAR PASCAL StrRStrIA(LPCSTR lpSource, LPCSTR lpLast, LPCSTR lpSrch)
- {
- LPCSTR lpFound = NULL;
- LPSTR lpEnd;
- char cHold;
- if (!lpLast)
- lpLast = lpSource + lstrlenA(lpSource);
- if (lpSource >= lpLast || *lpSrch == 0)
- return NULL;
- lpEnd = lstrfns_StrEndNA(lpLast, (UINT)(lstrlenA(lpSrch)-1));
- cHold = *lpEnd;
- *lpEnd = 0;
- while ((lpSource = StrStrIA(lpSource, lpSrch))!=0 &&
- OFFSETOF(lpSource) < OFFSETOF(lpLast))
- {
- lpFound = lpSource;
- lpSource = AnsiNext(lpSource);
- }
- *lpEnd = cHold;
- return((LPSTR)lpFound);
- }
- LPWSTR FAR PASCAL StrRStrIW(LPCWSTR lpSource, LPCWSTR lpLast, LPCWSTR lpSrch)
- {
- #ifdef UNICODE
- LPCWSTR lpFound = NULL;
- LPWSTR lpEnd;
- WCHAR cHold;
- if (!lpLast)
- lpLast = lpSource + lstrlenW(lpSource);
- if (lpSource >= lpLast || *lpSrch == 0)
- return NULL;
- lpEnd = lstrfns_StrEndNW(lpLast, (UINT)(lstrlenW(lpSrch)-1));
- cHold = *lpEnd;
- *lpEnd = 0;
- while ((lpSource = StrStrIW(lpSource, lpSrch))!=0 &&
- lpSource < lpLast)
- {
- lpFound = lpSource;
- lpSource++;
- }
- *lpEnd = cHold;
- return((LPWSTR)lpFound);
- #else
- SetLastErrorEx(ERROR_CALL_NOT_IMPLEMENTED, SLE_WARNING);
- return NULL;
- #endif
- }
- /*
- * StrStr - Search for first occurrence of a substring
- *
- * Assumes lpSource points to source string
- * lpSrch points to string to search for
- * returns first occurrence of string if successful; NULL otherwise
- */
- LPSTR FAR PASCAL StrStrA(LPCSTR lpFirst, LPCSTR lpSrch)
- {
- UINT uLen;
- WORD wMatch;
- uLen = (UINT)lstrlenA(lpSrch);
- wMatch = READNATIVEWORD(lpSrch);
- for ( ; (lpFirst=StrChrA(lpFirst, wMatch))!=0 && !IntlStrEqNA(lpFirst, lpSrch, uLen);
- lpFirst=AnsiNext(lpFirst))
- continue; /* continue until we hit the end of the string or get a match */
- return((LPSTR)lpFirst);
- }
- LPWSTR FAR PASCAL StrStrW(LPCWSTR lpFirst, LPCWSTR lpSrch)
- {
- #ifdef UNICODE
- UINT uLen;
- WCHAR wMatch;
- uLen = (UINT)lstrlenW(lpSrch);
- wMatch = *lpSrch;
- for ( ; (lpFirst=StrChrW(lpFirst, wMatch))!=0 && !IntlStrEqNW(lpFirst, lpSrch, uLen);
- lpFirst++)
- continue; /* continue until we hit the end of the string or get a match */
- return((LPWSTR)lpFirst);
- #else
- SetLastErrorEx(ERROR_CALL_NOT_IMPLEMENTED, SLE_WARNING);
- return NULL;
- #endif
- }
- /*
- * StrChrI - Find first occurrence of character in string, case insensitive
- * Assumes lpStart points to start of null terminated string
- * wMatch is the character to match
- * returns ptr to the first occurrence of ch in str, NULL if not found.
- */
- LPSTR FAR PASCAL StrChrIA(LPCSTR lpStart, WORD wMatch)
- {
- wMatch = (UINT)(IsDBCSLeadByte(LOBYTE(wMatch)) ? wMatch : LOBYTE(wMatch));
- for ( ; *lpStart; lpStart = AnsiNext(lpStart))
- {
- if (!ChrCmpIA(READNATIVEWORD(lpStart), wMatch))
- return((LPSTR)lpStart);
- }
- return (NULL);
- }
- LPWSTR FAR PASCAL StrChrIW(LPCWSTR lpStart, WCHAR wMatch)
- {
- for ( ; *lpStart; lpStart++)
- {
- if (!ChrCmpIW(*lpStart, wMatch))
- return((LPWSTR)lpStart);
- }
- return (NULL);
- }
- /*
- * StrStrI - Search for first occurrence of a substring, case insensitive
- *
- * Assumes lpFirst points to source string
- * lpSrch points to string to search for
- * returns first occurrence of string if successful; NULL otherwise
- */
- LPSTR FAR PASCAL StrStrIA(LPCSTR lpFirst, LPCSTR lpSrch)
- {
- UINT uLen;
- WORD wMatch;
- uLen = (UINT)lstrlenA(lpSrch);
- wMatch = READNATIVEWORD(lpSrch);
- for ( ; (lpFirst = StrChrIA(lpFirst, wMatch)) != 0 && !IntlStrEqNIA(lpFirst, lpSrch, uLen);
- lpFirst=AnsiNext(lpFirst))
- continue; /* continue until we hit the end of the string or get a match */
- return((LPSTR)lpFirst);
- }
- LPWSTR FAR PASCAL StrStrIW(LPCWSTR lpFirst, LPCWSTR lpSrch)
- {
- #ifdef UNICODE
- UINT uLen;
- WCHAR wMatch;
- uLen = (UINT)lstrlenW(lpSrch);
- wMatch = *lpSrch;
- for ( ; (lpFirst = StrChrIW(lpFirst, wMatch)) != 0 && !IntlStrEqNIW(lpFirst, lpSrch, uLen);
- lpFirst++)
- continue; /* continue until we hit the end of the string or get a match */
- return((LPWSTR)lpFirst);
- #else
- SetLastErrorEx(ERROR_CALL_NOT_IMPLEMENTED, SLE_WARNING);
- return NULL;
- #endif
- }
- #ifndef UNICODE
- // TruncateString - bugbug: the same logic in shdocvw
- //
- // purpose: cut a string at the given length in dbcs safe manner
- // the string may be truncated at cch-1 if the sz[cch] points
- // to a lead byte that would result in cutting in the middle
- // of double byte character.
- // It is caller's responsibility to reserve enough buffer for
- // sz so we can put sz[cch]=0 safely.
- //
- // *Note this logic is not much perf hit when called with sbcs
- // string, as it just bails out at the tail character always.
- //
- void TruncateString(char *sz, int cchBufferSize)
- {
- int cch = cchBufferSize - 1;
- LPSTR psz = &sz[cch];
- if (!sz || cchBufferSize <= 0) return;
- while (psz > sz)
- {
- psz--;
- if (!IsDBCSLeadByte(*psz))
- {
- // Found non-leadbyte for the first time.
- // This is either a trail byte of double byte char
- // or a single byte character we've first seen.
- // Thus, the next pointer must be at either of a leadbyte
- // or &sz[cch]
- psz++;
- break;
- }
- }
- if (((&sz[cch] - psz) & 1) && cch > 0)
- {
- // we're truncating the string in the middle of dbcs
- cch--;
- }
- sz[cch] = '';
- return;
- }
- #endif