|
|
//*******************************************************************************************
//
// Filename : strings.c
//
// DBCS aware string routines...
//
// Copyright (c) 1994 - 1996 Microsoft Corporation. All rights reserved
//
//*******************************************************************************************
#include "pch.h"
#include "strings.h"
#ifdef UNICODE
#define _StrEndN _StrEndNW
#define ChrCmp ChrCmpW
#define ChrCmpI ChrCmpIW
#else
#define _StrEndN _StrEndNA
#define ChrCmp ChrCmpA
#define ChrCmpI ChrCmpIA
#endif
/*
* StrEndN - Find the end of a string, but no more than n bytes * Assumes pStart points to start of null terminated string * nBufSize is the maximum length * returns ptr to just after the last byte to be included */ LPSTR _StrEndNA(LPCSTR pStart, int nBufSize) { LPCSTR pEnd;
for (pEnd = pStart + nBufSize; *pStart && pStart < pEnd; pStart = AnsiNext(pStart)) continue; /* just getting to the end of the string */ if (pStart > pEnd) { /* We can only get here if the last byte before pEnd was a lead byte
*/ pStart -= 2; } return (LPSTR)pStart; }
LPWSTR _StrEndNW(LPCWSTR pStart, int nBufSize) { #ifdef UNICODE
LPCWSTR pEnd;
for (pEnd = pStart + nBufSize; *pStart && (pStart < pEnd); pStart++) continue; /* just getting to the end of the string */
return((LPWSTR)pStart);
#else
SetLastErrorEx(ERROR_CALL_NOT_IMPLEMENTED, SLE_WARNING); return NULL;
#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 */ BOOL ChrCmpA(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 ChrCmpW(WORD w1, WORD wMatch) { #ifdef UNICODE
return(!(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] = '\0'; } else sz1[1] = '\0';
*(WORD *)sz2 = wMatch; sz2[2] = '\0'; return lstrcmpiA(sz1, sz2); }
BOOL ChrCmpIW(WORD w1, WORD wMatch) { #ifdef UNICODE
TCHAR sz1[2], sz2[2];
sz1[0] = w1; sz1[1] = TEXT('\0'); sz2[0] = wMatch; sz2[1] = TEXT('\0');
return lstrcmpiW(sz1, sz2);
#else
SetLastErrorEx(ERROR_CALL_NOT_IMPLEMENTED, SLE_WARNING); return FALSE;
#endif
}
/*
* StrChr - Find first occurrence of character in string * Assumes pStart 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 StrChrA(LPCSTR pStart, WORD wMatch) { for ( ; *pStart; pStart = AnsiNext(pStart)) { if (!ChrCmpA(*(UNALIGNED WORD *)pStart, wMatch)) { return((LPSTR)pStart); } } return (NULL); }
LPWSTR StrChrW(LPCWSTR pStart, WORD wMatch) { #ifdef UNICODE
for ( ; *pStart; pStart = AnsiNext(pStart)) { // Need a tmp word since casting ptr to WORD * will
// fault on MIPS, ALPHA
WORD wTmp; memcpy(&wTmp, pStart, sizeof(WORD));
if (!ChrCmpW(wTmp, wMatch)) { return((LPWSTR)pStart); } } return (NULL);
#else
SetLastErrorEx(ERROR_CALL_NOT_IMPLEMENTED, SLE_WARNING); return NULL;
#endif
}
/*
* StrRChr - Find last occurrence of character in string * Assumes pStart points to start of string * pEnd 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 StrRChrA(LPCSTR pStart, LPCSTR pEnd, WORD wMatch) { LPCSTR lpFound = NULL;
if (!pEnd) pEnd = pStart + lstrlenA(pStart);
for ( ; pStart < pEnd; pStart = AnsiNext(pStart)) { if (!ChrCmpA(*(UNALIGNED WORD *)pStart, wMatch)) lpFound = pStart; } return ((LPSTR)lpFound); }
LPWSTR StrRChrW(LPCWSTR pStart, LPCWSTR pEnd, WORD wMatch) { #ifdef UNICODE
LPCWSTR lpFound = NULL;
if (!pEnd) pEnd = pStart + lstrlenW(pStart);
for ( ; pStart < pEnd; pStart++) { if (!ChrCmpW(*(UNALIGNED WORD *)pStart, wMatch)) lpFound = pStart; } return ((LPWSTR)lpFound);
#else
SetLastErrorEx(ERROR_CALL_NOT_IMPLEMENTED, SLE_WARNING); return NULL;
#endif
}
/*
* StrChrI - Find first occurrence of character in string, case insensitive * Assumes pStart 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 StrChrIA(LPCSTR pStart, WORD wMatch) { wMatch = (UINT)(IsDBCSLeadByte(LOBYTE(wMatch)) ? wMatch : LOBYTE(wMatch));
for ( ; *pStart; pStart = AnsiNext(pStart)) { if (!ChrCmpIA(*(UNALIGNED WORD *)pStart, wMatch)) return((LPSTR)pStart); } return (NULL); }
LPWSTR StrChrIW(LPCWSTR pStart, WORD wMatch) { #ifdef UNICODE
for ( ; *pStart; pStart++) { if (!ChrCmpIW(*(WORD *)pStart, wMatch)) return((LPWSTR)pStart); } return (NULL);
#else
SetLastErrorEx(ERROR_CALL_NOT_IMPLEMENTED, SLE_WARNING); return NULL;
#endif
}
/*
* StrRChrI - Find last occurrence of character in string, case insensitive * Assumes pStart points to start of string * pEnd 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 StrRChrIA(LPCSTR pStart, LPCSTR pEnd, WORD wMatch) { LPCSTR lpFound = NULL;
if (!pEnd) pEnd = pStart + lstrlenA(pStart);
wMatch = (UINT)(IsDBCSLeadByte(LOBYTE(wMatch)) ? wMatch : LOBYTE(wMatch));
for ( ; pStart < pEnd; pStart = AnsiNext(pStart)) { if (!ChrCmpIA(*(UNALIGNED WORD *)pStart, wMatch)) lpFound = pStart; } return ((LPSTR)lpFound); }
LPWSTR StrRChrIW(LPCWSTR pStart, LPCWSTR pEnd, WORD wMatch) { #ifdef UNICODE
LPCWSTR lpFound = NULL;
if (!pEnd) pEnd = pStart + lstrlenW(pStart);
for ( ; pStart < pEnd; pStart++) { if (!ChrCmpIW(*(WORD *)pStart, wMatch)) lpFound = pStart; } 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 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, *(UNALIGNED WORD *)lp)) return (int)(lp-lpStr); lp = AnsiNext(lp); }
return (int)(lp-lpStr); // ==lstrlen(lpStr)
}
int 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, *(WORD *)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 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, *(UNALIGNED WORD *)lp)) return (int)(lp-lpStr); lp = AnsiNext(lp); }
return (int)(lp-lpStr); // ==lstrlen(lpStr)
}
int 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, *(WORD *)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. * won't work if source strings are in ROM */ int StrCmpNA(LPCSTR lpStr1, LPCSTR lpStr2, int nChar) { char sz1[4]; char sz2[4]; int i; 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;
if (IsDBCSLeadByte(*lpStr2)) lpStr2++;
wMatch = (WORD) *lpStr2;
i = ChrCmpA(*(UNALIGNED WORD *)lpStr1, wMatch); if (i) { int iRet;
(*(WORD *)sz1) = *(UNALIGNED WORD *)lpStr1; (*(WORD *)sz2) = *(UNALIGNED WORD *)lpStr2; *AnsiNext(sz1) = 0; *AnsiNext(sz2) = 0; iRet = lstrcmpA(sz1, sz2); //DebugMsg(DM_TRACE, ".................... %d", iRet);
return iRet; } }
//DebugMsg(DM_TRACE, ".................... 0");
return 0; }
int 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(*lpStr1, *lpStr2); if (i) { int iRet;
sz1[0] = *lpStr1; sz2[0] = *lpStr2; sz1[1] = TEXT('\0'); sz2[1] = TEXT('\0'); 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. */ int 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;
wMatch = (UINT)(IsDBCSLeadByte(*lpStr2)) ? *(WORD *)lpStr2 : (WORD)(BYTE)(*lpStr2);
i = ChrCmpIA(*(UNALIGNED WORD *)lpStr1, wMatch); if (i) { //DebugMsg(DM_TRACE, ".................... %d", i);
return i; } } //DebugMsg(DM_TRACE, ".................... 0");
return 0; }
int 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++) { i = ChrCmpIW(*lpStr1, *lpStr2); if (i) { //DebugMsg(DM_TRACE, ".................... %d", i);
return i; } } //DebugMsg(DM_TRACE, ".................... 0");
return 0;
#else
SetLastErrorEx(ERROR_CALL_NOT_IMPLEMENTED, SLE_WARNING); return -1;
#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 StrRStrIA(LPCSTR lpSource, LPCSTR lpLast, LPCSTR lpSrch) { LPCSTR lpFound = NULL; LPSTR pEnd; char cHold;
if (!lpLast) lpLast = lpSource + lstrlenA(lpSource);
if (lpSource >= lpLast || *lpSrch == 0) return NULL;
pEnd = _StrEndNA(lpLast, (UINT)(lstrlenA(lpSrch)-1)); cHold = *pEnd; *pEnd = 0;
while ((lpSource = StrStrIA(lpSource, lpSrch)) != 0 && lpSource < lpLast) { lpFound = lpSource; lpSource = AnsiNext(lpSource); } *pEnd = cHold; return((LPSTR)lpFound); }
LPWSTR StrRStrIW(LPCWSTR lpSource, LPCWSTR lpLast, LPCWSTR lpSrch) { #ifdef UNICODE
LPCWSTR lpFound = NULL; LPWSTR pEnd; WCHAR cHold;
if (!lpLast) lpLast = lpSource + lstrlenW(lpSource);
if (lpSource >= lpLast || *lpSrch == 0) return NULL;
pEnd = _StrEndNW(lpLast, (UINT)(lstrlenW(lpSrch)-1)); cHold = *pEnd; *pEnd = 0;
while ((lpSource = StrStrIW(lpSource, lpSrch))!=0 && lpSource < lpLast) { lpFound = lpSource; lpSource++; } *pEnd = 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 StrStrA(LPCSTR lpFirst, LPCSTR lpSrch) { UINT uLen; WORD wMatch;
uLen = (UINT)lstrlenA(lpSrch); wMatch = *(UNALIGNED WORD *)lpSrch;
for ( ; (lpFirst=StrChrA(lpFirst, wMatch))!=0 && StrCmpNA(lpFirst, lpSrch, uLen); lpFirst=AnsiNext(lpFirst)) continue; /* continue until we hit the end of the string or get a match */
return((LPSTR)lpFirst); }
LPWSTR StrStrW(LPCWSTR lpFirst, LPCWSTR lpSrch) { #ifdef UNICODE
UINT uLen; WORD wMatch;
uLen = (UINT)lstrlenW(lpSrch); wMatch = *(WORD *)lpSrch;
for ( ; (lpFirst=StrChrW(lpFirst, wMatch))!=0 && StrCmpNW(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
}
/*
* 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 StrStrIA(LPCSTR lpFirst, LPCSTR lpSrch) { UINT uLen; WORD wMatch;
uLen = (UINT)lstrlenA(lpSrch); wMatch = *(UNALIGNED WORD *)lpSrch;
for ( ; (lpFirst = StrChrIA(lpFirst, wMatch)) != 0 && StrCmpNIA(lpFirst, lpSrch, uLen); lpFirst=AnsiNext(lpFirst)) continue; /* continue until we hit the end of the string or get a match */
return((LPSTR)lpFirst); }
LPWSTR StrStrIW(LPCWSTR lpFirst, LPCWSTR lpSrch) { #ifdef UNICODE
UINT uLen; WORD wMatch;
uLen = (UINT)lstrlenW(lpSrch); wMatch = *(WORD *)lpSrch;
for ( ; (lpFirst = StrChrIW(lpFirst, wMatch)) != 0 && StrCmpNIW(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
}
|