|
|
//+----------------------------------------------------------------------------
//
// File: strings.cpp
//
// Module: CMUTIL.DLL
//
// Synopsis: Basic string manipulation routines
//
// Copyright (c) 1997-1999 Microsoft Corporation
//
// Author: henryt Created 03/01/98
//
//+----------------------------------------------------------------------------
#include "cmmaster.h"
//
// Include the locale-safe replacement for lstrcmpi
//
#define _CMUTIL_STRINGS_CPP_
#include "CompareString.cpp"
//+----------------------------------------------------------------------------
//
// Function: WzToSz
//
// Synopsis: Standard conversion function for converting Wide Characters to
// Ansi Characters
//
// Arguments: IN LPCWSTR pszwStrIn - Input Unicode string
// OUT LPSTR pszStrOut - Ansi Ouput Buffer
// IN int nOutBufferSize - number of Chars in pszStrOut
//
// Returns: int - 0 on failure, if return Value is > nOutBufferSize then the
// buffer is too small. Otherwise the number of chars copied
// to pszStrOut.
//
// History: Created Header 4/22/99
//
//+----------------------------------------------------------------------------
CMUTILAPI int WzToSz(IN LPCWSTR pszwStrIn, OUT LPSTR pszStrOut, IN int nOutBufferSize) { int nReturn = 0;
//
// nOutBufferSize could be 0 and pszStrOut could be NULL (passing zero size and a NULL out
// buffer causes WideCharToMultiByte to return the number of chars needed to convert the
// input string. It is used as a sizing technique). Only check pszwStrIn
//
if (pszwStrIn) { nReturn = WideCharToMultiByte(CP_ACP, 0, pszwStrIn, -1, pszStrOut, nOutBufferSize, NULL, NULL); } else { SetLastError(ERROR_INVALID_PARAMETER); }
return nReturn; }
//+----------------------------------------------------------------------------
//
// Function: SzToWz
//
// Synopsis: Standard Wrapper for converting from an Ansi string to a Wide String
//
// Arguments: IN LPCSTR pszInput - Ansi String to Convert
// OUT LPWSTR pszwOutput - Wide string output buffer
// IN int nBufferSize - number of chars in Wide String buffer
//
// Returns: int - 0 on failure, otherwise if return is < nBufferSize then insufficient
// buffer space. Otherwise the number of chars copied to the buffer.
//
// History: quintinb Created 4/22/99
//
//+----------------------------------------------------------------------------
CMUTILAPI int SzToWz(IN LPCSTR pszInput, OUT LPWSTR pszwOutput, IN int nBufferSize) { int nReturn = 0;
if (pszInput) { return MultiByteToWideChar(CP_ACP, 0, pszInput, -1, pszwOutput, nBufferSize); } else { SetLastError(ERROR_INVALID_PARAMETER); }
return nReturn; }
//+----------------------------------------------------------------------------
//
// Function: SzToWzWithAlloc
//
// Synopsis: Simple wrapper to encapsulate converting a string from
// MultiByte To Wide Char that Allocates memory using the sizing
// capabilities of the MultiByteToWideChar Api.
//
// Arguments: LPCSTR pszAnsiString - Source string to be converted.
//
// Returns: LPWSTR - returns NULL on failure, otherwise the converted string.
// The caller is responsible for freeing the Alloc-ed Memory.
//
// History: quintinb Created 4/8/99
//
//+----------------------------------------------------------------------------
CMUTILAPI LPWSTR SzToWzWithAlloc(LPCSTR pszAnsiString) { LPWSTR pszwString = NULL; DWORD dwSize = 0; //
// Find out how large the string is by calling MultiByteToWideChar with
// Zero for the size field.
//
if (NULL != pszAnsiString) { dwSize = SzToWz(pszAnsiString, NULL, 0); CMASSERTMSG((dwSize != 0), TEXT("SzToWzWithAlloc -- First MultiByteToWideChar Failed.")); if (0 != dwSize) { pszwString = (LPWSTR)CmMalloc(dwSize*sizeof(WCHAR));
CMASSERTMSG(pszwString, TEXT("SzToWzWithAlloc -- CmMalloc of pszwString Failed."));
if (pszwString) { if (!SzToWz(pszAnsiString, pszwString, dwSize)) { //
// Make sure to return a NULL string if we fail.
//
CMASSERTMSG(FALSE, TEXT("SzToWzWithAlloc -- Second MultiByteToWideChar Failed.")); CmFree(pszwString); pszwString = NULL; } #ifdef DEBUG
else { //
// If this is a debug build then we want to take the Wide string that we are going to
// return, convert it to Ansi and compare it to the original ansi string passed in.
//
LPSTR pszString;
dwSize = WzToSz(pszwString, NULL, 0);
if (0 != dwSize) { pszString = (LPSTR)CmMalloc(dwSize*sizeof(CHAR)); CMASSERTMSG(pszString, TEXT("SzToWzWithAlloc -- conversion of return value back to original Ansi string failed. Unable to allocate memory."));
if (pszString) { if (WzToSz(pszwString, pszString, dwSize)) { MYDBGASSERT(0 == lstrcmpA(pszString, pszAnsiString)); } else { CMASSERTMSG(FALSE, TEXT("SzToWzWithAlloc -- conversion of return value back to original Ansi string failed.")); } CmFree(pszString); } } else { CMASSERTMSG(FALSE, TEXT("SzToWzWithAlloc -- conversion of return value back to original Ansi string failed. Unable to properly size the string.")); } } #endif
} } }
return pszwString; }
//+----------------------------------------------------------------------------
//
// Function: WzToSzWithAlloc
//
// Synopsis: Simple wrapper to encapsulate converting a string from
// Unicode to MBCS that allocates memory using the sizing
// capabilities of the WideCharToMultiByte Api.
//
// Arguments: LPCWSTR pszwWideString - Source string to be converted.
//
// Returns: LPSTR - returns NULL on failure, otherwise the converted string.
// The caller is responsible for freeing the Alloc-ed Memory.
//
// History: quintinb Created 4/8/99
//
//+----------------------------------------------------------------------------
CMUTILAPI LPSTR WzToSzWithAlloc(LPCWSTR pszwWideString) { LPSTR pszString = NULL; DWORD dwSize = 0;
//
// Find out how large the string is by calling WideCharToMultiByte with
// Zero for the size field.
//
if (NULL != pszwWideString) { dwSize = WzToSz(pszwWideString, NULL, 0);
CMASSERTMSG((0 != dwSize), TEXT("WzToSzWithAlloc -- First WzToSz Failed."));
if (0 != dwSize) { pszString = (LPSTR)CmMalloc(dwSize*sizeof(CHAR));
CMASSERTMSG(pszString, TEXT("WzToSzWithAlloc -- CmMalloc failed to alloc pszString."));
if (pszString) { if (!WzToSz(pszwWideString, pszString, dwSize)) { //
// Make sure to return a NULL string if we fail.
//
CMASSERTMSG(FALSE, TEXT("WzToSzWithAlloc -- Second WzToSz Failed.")); CmFree(pszString); pszString = NULL; } #ifdef DEBUG
else { //
// If this is a debug build then we want to take the Ansi string that we are
// going to return, convert it to Unicode and compare it to the original Unicode
// string passed in.
//
LPWSTR pszwString; dwSize = SzToWz(pszString, NULL, 0); if (0 != dwSize) { pszwString = (LPWSTR)CmMalloc(dwSize*sizeof(WCHAR));
CMASSERTMSG(pszwString, TEXT("WzToSzWithAlloc -- conversion of return value back to original Ansi string failed. Unable to allocate memory."));
if (pszwString) { if (SzToWz(pszString, pszwString, dwSize)) { MYDBGASSERT(0 == lstrcmpU(pszwString, pszwWideString)); } else { CMASSERTMSG(FALSE, TEXT("WzToSzWithAlloc -- conversion of return value back to original Ansi string failed.")); } CmFree(pszwString); } } else { CMASSERTMSG(FALSE, TEXT("WzToSzWithAlloc -- conversion of return value back to original Ansi string failed. Unable to properly size the string.")); } } #endif
} } }
return pszString; }
//+----------------------------------------------------------------------------
//
// Function: CmStrTrimA
//
// Synopsis: Helper function to trim leading and trailing blanks from a
// string
//
// Arguments: LPTSTR pszStr - The string to be trimmed
//
// Returns: void WINAPI - Nothing
//
// History: nickball Created Header 3/11/98
//
//+----------------------------------------------------------------------------
CMUTILAPI void WINAPI CmStrTrimA(LPSTR pszStr) { //
// first, skip all the spaces at the begining of the string
//
MYDBGASSERT(pszStr);
if (pszStr) { LPSTR pszTmp = pszStr;
while (CmIsSpaceA(pszTmp)) { pszTmp = CharNextA(pszTmp); } if (pszTmp != pszStr) { CmMoveMemory(pszStr, pszTmp, lstrlenA(pszTmp)+1); }
//
// secondly, delete all the spaces at the end of the string
//
pszTmp = CmEndOfStrA(pszStr); while (pszTmp != pszStr) { pszTmp = CharPrevA(pszStr, pszTmp); if (!CmIsSpaceA(pszTmp)) { break; } *pszTmp = TEXT('\0'); } } }
//+----------------------------------------------------------------------------
//
// Function: CmStrTrimW
//
// Synopsis: Helper function to trim leading and trailing blanks from a
// string.
//
// Arguments: LPTSTR pszStr - The string to be trimmed
//
// Returns: void WINAPI - Nothing
//
// History: quintinb Created 2/27/99
//
//+----------------------------------------------------------------------------
CMUTILAPI void WINAPI CmStrTrimW(LPWSTR pszStr) { //
// first, skip all the spaces at the begining of the string
//
MYDBGASSERT(pszStr);
if (pszStr) { LPWSTR pszTmp = pszStr;
while (CmIsSpaceW(pszTmp)) { pszTmp = CharNextU(pszTmp); }
if (pszTmp != pszStr) { CmMoveMemory(pszStr, pszTmp, (lstrlenU(pszTmp)+1)*sizeof(WCHAR)); }
//
// secondly, delete all the spaces at the end of the string
//
pszTmp = CmEndOfStrW(pszStr);
while (pszTmp != pszStr) { pszTmp = CharPrevU(pszStr, pszTmp);
if (!CmIsSpaceW(pszTmp)) { break; }
*pszTmp = TEXT('\0'); } } }
//+----------------------------------------------------------------------------
//
// Function: CmIsSpaceA
//
// Synopsis: Checks to see if the char is a space. Note that spaces, new line chars,
// line feed chars, tabs, and most other forms of whitespace are considered
// spaces.
//
// Arguments: psz - an ansi or dbcs char
//
// Returns: TRUE or FALSE
//
//+----------------------------------------------------------------------------
CMUTILAPI BOOL WINAPI CmIsSpaceA(LPSTR psz) { WORD wType = 0;
MYDBGASSERT(psz);
if (psz) { if (IsDBCSLeadByte(*psz)) { MYVERIFY(GetStringTypeExA(LOCALE_USER_DEFAULT, CT_CTYPE1, psz, 2, &wType)); } else { MYVERIFY(GetStringTypeExA(LOCALE_USER_DEFAULT, CT_CTYPE1, psz, 1, &wType)); } }
return (wType & C1_SPACE); }
//+----------------------------------------------------------------------------
//
// Function: CmIsSpaceW
//
// Synopsis: Checks to see if the char is a space. Note that spaces, new line chars,
// line feed chars, tabs, and most other forms of whitespace are considered
// spaces.
//
// Arguments: psz - pointer to a string
//
// Returns: TRUE or FALSE
//
//+----------------------------------------------------------------------------
CMUTILAPI BOOL WINAPI CmIsSpaceW(LPWSTR pszwStr) { WORD wType = 0; LPWSTR pszwNextChar; int iCharCount;
MYDBGASSERT(pszwStr);
if (pszwStr) { pszwNextChar = CharNextU(pszwStr);
iCharCount = (INT)(pszwNextChar - pszwStr);
if (0 == GetStringTypeExU(LOCALE_USER_DEFAULT, CT_CTYPE1, pszwStr, iCharCount, &wType)) { CMTRACE3(TEXT("CmIsSpaceW -- GetStringTypeExW failed on %s, iCharCount is %d, GLE=%u"), pszwStr, iCharCount, GetLastError()); return FALSE; } } return (wType & C1_SPACE); }
//+----------------------------------------------------------------------------
//
// Function: CmIsDigitA
//
// Synopsis: Checks to see if the char is a digit.
//
// Arguments: psz - an ansi or dbcs char
//
// Returns: TRUE or FALSE
//
//+----------------------------------------------------------------------------
CMUTILAPI BOOL WINAPI CmIsDigitA(LPSTR psz) { WORD wType = 0;
MYDBGASSERT(psz);
if (psz) { if (IsDBCSLeadByte(*psz)) { MYVERIFY(GetStringTypeExA(LOCALE_USER_DEFAULT, CT_CTYPE1, psz, 2, &wType)); } else { MYVERIFY(GetStringTypeExA(LOCALE_USER_DEFAULT, CT_CTYPE1, psz, 1, &wType)); } }
return (wType & C1_DIGIT); }
//+----------------------------------------------------------------------------
//
// Function: CmIsDigitW
//
// Synopsis: Checks to see if the WCHAR is a digit.
//
// Arguments: pszwStr -- WCHAR string
//
// Returns: TRUE or FALSE
//
//+----------------------------------------------------------------------------
CMUTILAPI BOOL WINAPI CmIsDigitW(LPWSTR pszwStr) { WORD wType = 0; LPWSTR pszwNextChar; int iCharCount;
MYDBGASSERT(pszwStr);
if (pszwStr) { pszwNextChar = CharNextU(pszwStr);
iCharCount = (INT)(pszwNextChar - pszwStr);
if (0 == GetStringTypeExU(LOCALE_USER_DEFAULT, CT_CTYPE1, pszwStr, iCharCount, &wType)) { CMTRACE1(TEXT("CmIsDigitW -- GetStringTypeExU failed, GLE=%u"), GetLastError()); return FALSE; } }
return (wType & C1_DIGIT); }
//+----------------------------------------------------------------------------
//
// Function: CmEndOfStrA
//
// Synopsis: Given a string, returns the ptr to the end of the string(null char).
//
// Arguments: psz - an ansi or dbcs char
//
// Returns: LPSTR ptr to null char
//
//+----------------------------------------------------------------------------
CMUTILAPI LPSTR WINAPI CmEndOfStrA(LPSTR psz) { MYDBGASSERT(psz);
if (psz) { while (*psz) { psz = CharNextA(psz); } }
return psz; }
//+----------------------------------------------------------------------------
//
// Function: CmEndOfStrW
//
// Synopsis: Given a string, returns the ptr to the end of the string(null char).
//
// Arguments: pszwStr - a WCHAR
//
// Returns: LPWSTR ptr to null char
//
//+----------------------------------------------------------------------------
CMUTILAPI LPWSTR WINAPI CmEndOfStrW(LPWSTR pszwStr) { MYDBGASSERT(pszwStr);
if (pszwStr) { while (*pszwStr) { pszwStr = CharNextU(pszwStr); } }
return pszwStr; }
//+----------------------------------------------------------------------------
//
// Function: CmStrCpyAllocA
//
// Synopsis: Copies pszSrc into a newly allocated buffer (using CmMalloc) and
// returns the buffer to its caller who is responsible for freeing
// the buffer.
//
// Arguments: LPCSTR pszSrc - source string
//
// Returns: LPSTR - returns NULL if pszSrc is NULL or the Alloc fails,
// otherwise it returns the newly allocated buffer with
// a copy of pszSrc in it.
//
// History: quintinb Created Header and changed name to include Alloc 4/9/99
//
//+----------------------------------------------------------------------------
CMUTILAPI LPSTR CmStrCpyAllocA(LPCSTR pszSrc) { LPSTR pszBuffer = NULL;
if (pszSrc) { pszBuffer = (LPSTR) CmMalloc(lstrlenA(pszSrc) + 1);
if (pszBuffer) { lstrcpyA(pszBuffer, pszSrc); } }
return (pszBuffer); }
//+----------------------------------------------------------------------------
//
// Function: CmStrCpyAllocW
//
// Synopsis: Copies pszSrc into a newly allocated buffer (using CmMalloc) and
// returns the buffer to its caller who is responsible for freeing
// the buffer.
//
// Arguments: LPCSTR pszSrc - source string
//
// Returns: LPSTR - returns NULL if pszSrc is NULL or the Alloc fails,
// otherwise it returns the newly allocated buffer with
// a copy of pszSrc in it.
//
// History: quintinb Created Header and changed name to include Alloc 4/9/99
//
//+----------------------------------------------------------------------------
CMUTILAPI LPWSTR CmStrCpyAllocW(LPCWSTR pszSrc) { LPWSTR pszBuffer = NULL;
if (pszSrc) { size_t nLen = lstrlenU(pszSrc) + 1;
pszBuffer = (LPWSTR) CmMalloc(nLen*sizeof(WCHAR));
if (pszBuffer) { lstrcpyU(pszBuffer, pszSrc); } }
return (pszBuffer); }
//+----------------------------------------------------------------------------
//
// Function: CmStrCatAllocA
//
// Synopsis: This function reallocs the passed in string to a size large enough
// to hold the original data and the concatenates the new string onto
// the original string.
//
// Arguments: LPSTR *ppszDst - original string
// LPCSTR pszSrc - new piece of string to concatenate
//
// Returns: LPSTR - pointer to the concatenated string
//
// History: quintinb Created Header 4/9/99
//
//+----------------------------------------------------------------------------
CMUTILAPI LPSTR CmStrCatAllocA(LPSTR *ppszDst, LPCSTR pszSrc) { if (!ppszDst) { return NULL; }
if (pszSrc && *pszSrc) { DWORD dwSize = (lstrlenA(*ppszDst) + lstrlenA(pszSrc) + 1); LPSTR pszTmp = (LPSTR)CmRealloc((LPVOID)*ppszDst, dwSize);
if (NULL != pszTmp) { lstrcatA(pszTmp, pszSrc); *ppszDst = pszTmp; } }
return (*ppszDst); }
//+----------------------------------------------------------------------------
//
// Function: CmStrCatAllocW
//
// Synopsis: This function reallocs the passed in string to a size large enough
// to hold the original data and the concatenates the new string onto
// the original string.
//
// Arguments: LPWSTR *ppszDst - original string
// LPCWSTR pszSrc - new piece of string to concatenate
//
// Returns: LPWSTR - pointer to the concatenated string
//
// History: quintinb Created Header 4/9/99
//
//+----------------------------------------------------------------------------
CMUTILAPI LPWSTR CmStrCatAllocW(LPWSTR *ppszDst, LPCWSTR pszSrc) { if (!ppszDst) { return NULL; }
if (pszSrc && *pszSrc) { DWORD dwSize = (lstrlenU(*ppszDst) + lstrlenU(pszSrc) + 1)*sizeof(WCHAR); LPWSTR pszTmp = (LPWSTR)CmRealloc((LPVOID)*ppszDst, dwSize);
if (NULL != pszTmp) { lstrcatU(pszTmp, pszSrc); *ppszDst = pszTmp; } }
return (*ppszDst); }
//+----------------------------------------------------------------------------
//
// Function: CmStrchrA
//
// Synopsis: This function returns the first occurence of ch in the string pszString.
//
// Arguments: LPCSTR pszString - String to search in
// CHAR ch - character to look for
//
// Returns: LPSTR - pointer to the first occurence of the Character ch in pszString
//
// History: quintinb Created Header 4/9/99
//
//+----------------------------------------------------------------------------
CMUTILAPI LPSTR WINAPI CmStrchrA(LPCSTR pszString, const char ch) { LPSTR pszTmp = (LPSTR)pszString;
if (NULL == pszTmp) { CMASSERTMSG(FALSE, TEXT("CmStrchr - NULL pointer passed")); return NULL; }
while (*pszTmp && (*pszTmp != ch)) { pszTmp = CharNextA(pszTmp); }
if (*pszTmp == ch) { return pszTmp; }
return NULL; }
//+----------------------------------------------------------------------------
//
// Function: CmStrchrW
//
// Synopsis: This function returns the first occurence of ch in the string pszString.
//
// Arguments: LPCWSTR pszString - String to search in
// WCHAR ch - character to look for
//
// Returns: LPWSTR - pointer to the first occurence of the Character ch in pszString
//
// History: quintinb Created Header 4/9/99
//
//+----------------------------------------------------------------------------
CMUTILAPI LPWSTR WINAPI CmStrchrW(LPCWSTR pszString, const WCHAR ch) { LPWSTR pszTmp = (LPWSTR)pszString;
if (NULL == pszTmp) { CMASSERTMSG(FALSE, TEXT("CmStrchr - NULL pointer passed")); return NULL; }
while (*pszTmp && (*pszTmp != ch)) { pszTmp = CharNextU(pszTmp); }
if (*pszTmp == ch) { return pszTmp; }
return NULL; }
//+----------------------------------------------------------------------------
//
// Function: CmStrrchrA
//
// Synopsis: Find the last occurence of a character in a string
//
// Arguments: LPCSTR pszString - string to search in
// CHAR ch - character to look for
//
// Returns: LPSTR - NULL if the char is not found, a pointer to the char in
// the string otherwise
//
// History: quintinb Created Header and cleaned up 4/9/99
//
//+----------------------------------------------------------------------------
CMUTILAPI LPSTR CmStrrchrA (LPCSTR pszString, const char ch) { LPSTR pszTmp = NULL; LPSTR pszCurrent = (LPSTR)pszString; if (NULL == pszString) { CMASSERTMSG(FALSE, TEXT("CmStrrchr - NULL pointer passed")); } else { while (TEXT('\0') != *pszCurrent) { if (ch == (*pszCurrent)) { pszTmp = pszCurrent; } pszCurrent = CharNextA(pszCurrent); } }
return pszTmp; }
//+----------------------------------------------------------------------------
//
// Function: CmStrrchrW
//
// Synopsis: Find the last occurence of a character in a string
//
// Arguments: LPCWSTR pszString - string to search in
// WCHAR ch - character to look for
//
// Returns: LPWSTR - NULL if the char is not found, a pointer to the char in
// the string otherwise
//
// History: quintinb Created Header and cleaned up 4/9/99
//
//+----------------------------------------------------------------------------
CMUTILAPI LPWSTR CmStrrchrW (LPCWSTR pszString, const WCHAR ch) { LPWSTR pszTmp = NULL; LPWSTR pszCurrent = (LPWSTR)pszString;
if (NULL == pszString) { CMASSERTMSG(FALSE, TEXT("CmStrrchr - NULL pointer passed")); } else { while (TEXT('\0') != *pszCurrent) { if (ch == (*pszCurrent)) { pszTmp = pszCurrent; } pszCurrent = CharNextU(pszCurrent); } }
return pszTmp; }
//+----------------------------------------------------------------------------
//
// Function: CmStrtokA
//
// Synopsis: CM implementation of strtok
//
// Arguments: LPSTR pszStr - string to tokenize or NULL if getting a second token
// LPCSTR pszControl - set of token chars
//
// Returns: LPSTR - NULL if no token could be found or a pointer to a token string.
//
// History: quintinb Created Header and cleaned up for UNICODE conversion 4/9/99
//
//+----------------------------------------------------------------------------
CMUTILAPI LPSTR CmStrtokA(LPSTR pszStr, LPCSTR pszControl) { LPSTR pszToken; LPSTR pszTmpStr; LPCSTR pszTmpCtl; LPSTR pszTmpDelim;
//
// If the pszStr param is NULL, then we need to retrieve the stored string
//
if (NULL != pszStr) { pszTmpStr = pszStr; } else { pszTmpStr = (LPSTR)TlsGetValue(g_dwTlsIndex); }
//
// Find beginning of token (skip over leading delimiters). Note that
// there is no token if this loop sets string to point to the terminal
// null (*string == '\0')
//
while (*pszTmpStr) { for (pszTmpCtl = pszControl; *pszTmpCtl && *pszTmpCtl != *pszTmpStr; pszTmpCtl = CharNextA(pszTmpCtl)) { ; // do nothing
}
if (!*pszTmpCtl) { break; }
pszTmpStr = CharNextA(pszTmpStr); }
pszToken = pszTmpStr;
//
// Find the end of the token. If it is not the end of the string,
// put a null there.
//
for ( ; *pszTmpStr ; pszTmpStr = CharNextA(pszTmpStr)) { for (pszTmpCtl = pszControl; *pszTmpCtl && *pszTmpCtl != *pszTmpStr; pszTmpCtl = CharNextA(pszTmpCtl)) { ; // Do nothing
}
if (*pszTmpCtl) { pszTmpDelim = pszTmpStr; pszTmpStr = CharNextA(pszTmpStr); *pszTmpDelim = '\0'; break; } }
//
// Update nextoken (or the corresponding field in the per-thread data structure
//
TlsSetValue(g_dwTlsIndex, (LPVOID)pszTmpStr);
//
// Determine if a token has been found.
//
if (pszToken == pszTmpStr) { return NULL; } else { return pszToken; } }
//+----------------------------------------------------------------------------
//
// Function: CmStrtokW
//
// Synopsis: CM implementation of strtok
//
// Arguments: LPWSTR pszStr - string to tokenize or NULL if getting a second tokey
// LPCWSTR pszControl - set of token chars
//
// Returns: LPWSTR - NULL if no token could be found or a pointer to a token string.
//
// History: quintinb Created Header and cleaned up for UNICODE conversion 4/9/99
//
//+----------------------------------------------------------------------------
CMUTILAPI LPWSTR CmStrtokW(LPWSTR pszStr, LPCWSTR pszControl) { LPWSTR pszToken; LPWSTR pszTmpStr; LPWSTR pszTmpCtl; LPWSTR pszTmpDelim;
//
// If the pszStr param is NULL, then we need to retrieve the stored string
//
if (NULL != pszStr) { pszTmpStr = pszStr; } else { pszTmpStr = (LPWSTR)TlsGetValue(g_dwTlsIndex); }
//
// Find beginning of token (skip over leading delimiters). Note that
// there is no token iff this loop sets string to point to the terminal
// null (*string == '\0')
//
while (*pszTmpStr) { for (pszTmpCtl = (LPWSTR)pszControl; *pszTmpCtl && *pszTmpCtl != *pszTmpStr; pszTmpCtl = CharNextU(pszTmpCtl)) { ; // do nothing
}
if (!*pszTmpCtl) { break; }
pszTmpStr = CharNextU(pszTmpStr); }
pszToken = pszTmpStr; //
// Find the end of the token. If it is not the end of the string,
// put a null there.
//
for ( ; *pszTmpStr ; pszTmpStr = CharNextU(pszTmpStr)) { for (pszTmpCtl = (LPWSTR)pszControl; *pszTmpCtl && *pszTmpCtl != *pszTmpStr; pszTmpCtl = CharNextU(pszTmpCtl)) { ; // Do nothing
}
if (*pszTmpCtl) { pszTmpDelim = pszTmpStr; pszTmpStr = CharNextU(pszTmpStr); *pszTmpDelim = L'\0'; break; } }
//
// Update nextoken (or the corresponding field in the per-thread data structure
//
TlsSetValue(g_dwTlsIndex, (LPVOID)pszTmpStr);
//
// Determine if a token has been found.
//
if (pszToken == pszTmpStr) { return NULL; } else { return pszToken; } }
//+----------------------------------------------------------------------------
//
// Function: CmStrStrA
//
// Synopsis: Simple replacement for StrStr from C runtime
//
// Arguments: LPCTSTR pszString - The string to search in
// LPCTSTR pszSubString - The string to search for
//
// Returns: LPTSTR - Ptr to the first occurence of pszSubString in pszString.
// NULL if pszSubString does not occur in pszString
//
//
// History: nickball Created Header 04/01/98
// nickball Added ptr check 02/21/99
// quintinb rewrote for unicode conversion 04/08/99
//
//+----------------------------------------------------------------------------
CMUTILAPI LPSTR CmStrStrA(LPCSTR pszString, LPCSTR pszSubString) { //
// Check the inputs
//
MYDBGASSERT(pszString); MYDBGASSERT(pszSubString);
if (NULL == pszSubString || NULL == pszString) { return NULL; }
//
// Check to make sure we have something to look for
//
if (TEXT('\0') == pszSubString[0]) { return((LPSTR)pszString); }
//
// Okay, start looking for the string
//
LPSTR pszCurrent = (LPSTR)pszString; LPSTR pszTmp1; LPSTR pszTmp2;
while (*pszCurrent) { pszTmp1 = pszCurrent; pszTmp2 = (LPSTR) pszSubString;
while (*pszTmp1 && *pszTmp2 && ((*pszTmp1) == (*pszTmp2))) { pszTmp1 = CharNextA(pszTmp1); pszTmp2 = CharNextA(pszTmp2); }
if (TEXT('\0') == *pszTmp2) { return pszCurrent; }
pszCurrent = CharNextA(pszCurrent); }
return NULL; }
//+----------------------------------------------------------------------------
//
// Function: CmStrStrW
//
// Synopsis: Simple replacement for StrStr from C runtime
//
// Arguments: LPCTSTR pszString - The string to search in
// LPCTSTR pszSubString - The string to search for
//
// Returns: LPTSTR - Ptr to the first occurence of pszSubString in pszString.
// NULL if pszSubString does not occur in pszString
//
//
// History: nickball Created Header 04/01/98
// nickball Added ptr check 02/21/99
// quintinb rewrote for unicode conversion 04/08/99
//
//+----------------------------------------------------------------------------
CMUTILAPI LPWSTR CmStrStrW(LPCWSTR pszString, LPCWSTR pszSubString) {
//
// Check the inputs
//
MYDBGASSERT(pszString); MYDBGASSERT(pszSubString);
if (NULL == pszSubString || NULL == pszString) { return NULL; }
//
// Check to make sure we have something to look for
//
if (TEXT('\0') == pszSubString[0]) { return((LPWSTR)pszString); }
//
// Okay, start looking for the string
//
LPWSTR pszCurrent = (LPWSTR)pszString; LPWSTR pszTmp1; LPWSTR pszTmp2;
while (*pszCurrent) { pszTmp1 = pszCurrent; pszTmp2 = (LPWSTR) pszSubString;
while (*pszTmp1 && *pszTmp2 && ((*pszTmp1) == (*pszTmp2))) { pszTmp1 = CharNextU(pszTmp1); pszTmp2 = CharNextU(pszTmp2); }
if (TEXT('\0') == *pszTmp2) { return pszCurrent; }
pszCurrent = CharNextU(pszCurrent); }
return NULL; }
//+----------------------------------------------------------------------------
//
// Function: CmCompareStringA
//
// Synopsis: redirected to function in CompareString.cpp
//
//+----------------------------------------------------------------------------
CMUTILAPI int CmCompareStringA(LPCSTR lpString1, LPCSTR lpString2) { return SafeCompareStringA(lpString1, lpString2); }
//+----------------------------------------------------------------------------
//
// Function: CmCompareStringW
//
// Synopsis: redirected to function in CompareString.cpp
//
//+----------------------------------------------------------------------------
CMUTILAPI int CmCompareStringW(LPCWSTR lpString1, LPCWSTR lpString2) { return SafeCompareStringW(lpString1, lpString2); }
|