windows-nt/Source/XPSP1/NT/net/rras/cm/cmutil/strings.cpp
2020-09-26 16:20:57 +08:00

1196 lines
32 KiB
C++

//+----------------------------------------------------------------------------
//
// 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"
//+----------------------------------------------------------------------------
//
// 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;
//
// Find out how large the string is by calling MultiByteToWideChar with
// Zero for the size field.
//
if (NULL != pszAnsiString)
{
DWORD 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;
DWORD 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;
//
// Find out how large the string is by calling WideCharToMultiByte with
// Zero for the size field.
//
if (NULL != pszwWideString)
{
DWORD 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;
DWORD 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;
}