|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1997.
//
// File: N C S T R I N G . H
//
// Contents: Common string routines.
//
// Notes:
//
// Author: shaunco 24 Mar 1997
//
//----------------------------------------------------------------------------
#pragma once
#include "ncdebug.h"
#include "ncvalid.h"
#include "ncmsz.h"
#include "ncstl.h"
const int c_cchGuidWithTerm = 39; // includes terminating null
const int c_cbGuidWithTerm = c_cchGuidWithTerm * sizeof(WCHAR);
inline ULONG CbOfSz (PCWSTR psz) { AssertH(psz); return wcslen (psz) * sizeof(WCHAR); } inline ULONG CbOfSza (PCSTR psza) { AssertH(psza); return strlen (psza) * sizeof(CHAR); }
inline ULONG CbOfSzAndTerm (PCWSTR psz) { AssertH(psz); return (wcslen (psz) + 1) * sizeof(WCHAR); } inline ULONG CbOfSzaAndTerm (PCSTR psza) { AssertH(psza); return (strlen (psza) + 1) * sizeof(CHAR); }
ULONG CbOfSzSafe (PCWSTR psz); ULONG CbOfSzaSafe (PCSTR psza);
ULONG CbOfSzAndTermSafe (PCWSTR psz); ULONG CbOfSzaAndTermSafe (PCSTR psza);
ULONG CchOfSzSafe ( PCWSTR psz);
inline ULONG CchToCb (ULONG cch) { return cch * sizeof(WCHAR); }
struct MAP_SZ_DWORD { PCWSTR pszValue; DWORD dwValue; };
PWSTR PszAllocateAndCopyPsz ( PCWSTR pszSrc);
extern const WCHAR c_szEmpty[];
template<class T> VOID ConvertStringToColString ( IN PCWSTR psz, IN const WCHAR chSeparator, OUT T& coll) { AssertSz(chSeparator, "Separator can not be \0");
FreeCollectionAndItem(coll);
if (NULL == psz) { return; }
PWSTR pszBuf = new WCHAR[wcslen(psz) + 1];
wcscpy(pszBuf, psz); WCHAR* pchString = pszBuf; WCHAR* pchSeparator; while (*pchString) { pchSeparator = wcschr(pchString, chSeparator); if (pchSeparator) { *pchSeparator = 0; }
if (*pchString) { coll.push_back(new tstring(pchString)); }
if (pchSeparator) { pchString = pchSeparator + 1; } else { break; } }
delete [] pszBuf; }
template<class T> VOID ConvertColStringToString ( IN const T& coll, IN const WCHAR chSeparator, OUT tstring& str) { AssertSz(chSeparator, "Separator can not be \0");
if (chSeparator) { T::const_iterator iter = coll.begin();
while (iter != coll.end()) { str += (*iter)->c_str();
++iter; if (iter != coll.end()) { str += chSeparator; } } } }
DWORD WINAPIV DwFormatString ( PCWSTR pszFmt, PWSTR pszBuf, DWORD cchBuf, ...);
DWORD WINAPIV DwFormatStringWithLocalAlloc ( PCWSTR pszFmt, PWSTR* ppszBuf, ...);
enum NC_IGNORE_SPACES { NC_IGNORE, NC_DONT_IGNORE, };
BOOL FFindStringInCommaSeparatedList ( PCWSTR pszSubString, PCWSTR pszList, NC_IGNORE_SPACES eIgnoreSpaces, DWORD* pdwPosition);
enum NC_FIND_ACTION { NC_NO_ACTION, NC_REMOVE_FIRST_MATCH, NC_REMOVE_ALL_MATCHES, };
inline BOOL FFindFirstMatch ( NC_FIND_ACTION eAction) { return (NC_NO_ACTION == eAction) || (NC_REMOVE_FIRST_MATCH == eAction); }
//+---------------------------------------------------------------------------
//
// Function: FIsBstrEmpty
//
// Purpose: Determines if the given BSTR is "empty" meaning the pointer
// is NULL or the string is 0-length.
//
// Arguments:
// bstr [in] BSTR to check.
//
// Returns: TRUE if the BSTR is empty, FALSE if not.
//
// Author: danielwe 20 May 1997
//
// Notes:
//
inline BOOL FIsBstrEmpty ( BSTR bstr) { return !(bstr && *bstr); }
//+---------------------------------------------------------------------------
//
// Function: FIsStrEmpty
//
// Purpose: Determines if the given PCWSTR is "empty" meaning the pointer
// is NULL or the string is 0-length.
//
// Arguments:
// bstr [in] BSTR to check.
//
// Returns: TRUE if the BSTR is empty, FALSE if not.
//
// Author: danielwe 20 May 1997
//
// Notes:
//
inline BOOL FIsStrEmpty ( PCWSTR psz) { return !(psz && *psz); }
//+---------------------------------------------------------------------------
//
// Function: FIsPrefix
//
// Purpose: Returns whether a string is a prefix of another string.
//
// Arguments:
// pszPrefix [in] Potential prefix
// pszString [in] String that may begin with the prefix
//
// Returns: TRUE if given prefix string is a prefix of the target string.
//
// Author: danielwe 24 Mar 1997
//
// Notes: Uses CompareString with the default locale.
//
inline BOOL FIsPrefix ( PCWSTR pszPrefix, PCWSTR pszString) { Assert (pszPrefix); Assert (pszString);
return (0 == _wcsnicmp(pszPrefix, pszString, wcslen(pszPrefix))); }
BOOL FIsSubstr ( PCWSTR pszSubString, PCWSTR pszString);
HRESULT HrAddStringToDelimitedSz ( PCWSTR pszAddString, PCWSTR pszIn, WCHAR chDelimiter, DWORD dwFlags, DWORD dwStringIndex, PWSTR* ppszOut);
HRESULT HrRemoveStringFromDelimitedSz ( PCWSTR pszRemove, PCWSTR pszIn, WCHAR chDelimiter, DWORD dwFlags, PWSTR* ppszOut);
//+---------------------------------------------------------------------------
//
// Function: template<class T> ColStringToMultiSz
//
// Purpose: Convert an STL collection of tstring pointers to a multi-sz.
//
// Arguments:
// listStr [in] list of tstring pointers to put in the multi-sz.
// ppszOut [out] the returned multi-sz.
//
// Returns: nothing.
//
// Author: shaunco 10 Apr 1997
//
// Notes: The output multi-sz should be freed using delete.
//
template<class T> VOID ColStringToMultiSz ( const T& colStr, PWSTR* ppszOut) { Assert (ppszOut);
// Count up the count of characters consumed by the list of strings.
// This count includes the null terminator of each string.
//
T::const_iterator iter; UINT cch = 0; for (iter = colStr.begin(); iter != colStr.end(); iter++) { tstring* pstr = *iter; if (!pstr->empty()) { cch += (UINT)(pstr->length() + 1); } }
if (cch) { // Allocate the multi-sz. Assumes new will throw on error.
//
PWSTR pszOut = new WCHAR [cch + 1]; *ppszOut = pszOut;
// Copy the strings to the multi-sz.
//
for (iter = colStr.begin(); iter != colStr.end(); iter++) { tstring* pstr = *iter; if (!pstr->empty()) { lstrcpyW (pszOut, pstr->c_str()); pszOut += pstr->length() + 1; } }
// Null terminate the multi-sz.
Assert (pszOut == *ppszOut + cch); *pszOut = 0; } else { *ppszOut = NULL; } }
//+---------------------------------------------------------------------------
//
// Function: template<class T> DeleteColString
//
// Purpose: Empty a list of tstring and delete each tstring as it is
// removed.
//
// Arguments:
// pcolstr [inout] Collection of tstring pointers to delete and empty
//
// Returns: nothing
//
// Author: mikemi 30 Apr 1997
//
// Notes:
//
// template<class T>
// VOID
// DeleteColString (
// T* pcolstr)
VOID DeleteColString ( list<tstring*>* pcolstr);
VOID DeleteColString ( vector<tstring*>* pcolstr);
//+---------------------------------------------------------------------------
//
// Function: template<class T> MultiSzToColString
//
// Purpose: Convert an multi-sz buffer to a STL collection of tstring
// pointers.
//
// Arguments:
// pmsz [in] the multi-sz to convert (Can be NULL)
// pcolstr [out] list of tstring pointers to add allocated tstrings to
//
// Returns: nothing
//
// Author: mikemi 30 Apr 1997
//
// Notes: The output collection should be freed using DeleteColString.
// This function will delete the collection list passed
//
template<class T> VOID MultiSzToColString ( PCWSTR pmsz, T* pcolstr) { Assert (pcolstr);
if (!pcolstr->empty()) { DeleteColString (pcolstr); }
if (pmsz) { while (*pmsz) { tstring* pstr = new tstring; if (pstr) { *pstr = pmsz; pcolstr->push_back (pstr); } // get the next string even if new failed
pmsz += lstrlen (pmsz) + 1; } } }
//+---------------------------------------------------------------------------
//
// Function: template<class T> RemoveDupsInColPtr
//
// Purpose: Remove all duplicate entries in an STL collection of pointers
// to objects.
//
// Arguments:
// pcol [inout] Collection of pointers to objects.
//
// Returns: nothing
//
// Author: mikemi 03 May 1997
//
// Notes: The objects pointed at should have a comparison operator
//
template<class T> VOID RemoveDupsInColPtr ( T* pcol) { Assert (pcol);
// remove duplicates
//
T::iterator posItem; T::iterator pos; T::value_type pItem; T::value_type p;
posItem = pcol->begin(); while (posItem != pcol->end()) { pItem = *posItem;
// for every other item, remove the duplicates
pos = posItem; pos++; while (pos != pcol->end()) { p = *pos;
if ( *pItem == *p ) { pos = pcol->erase( pos ); delete p; } else { pos++; } } // increment afterwards due to fact that we are removing,
// and otherwise could have removed the item it pointed to
posItem++; } }
//+---------------------------------------------------------------------------
//
// Function: template<class T> CopyColPtr
//
// Purpose: Copies one collection of pointers into another.
//
// Arguments:
// pcolDest [out] Collection of pointers to objects.
// pcolSrc [in] Collection of pointers to objects.
//
// Returns: nothing
//
// Author: BillBe 13 Jun 1998
//
// Notes:
//
template<class T> VOID CopyColPtr (T* pcolDest, const T& colSrc) { Assert (pcolDest);
T::iterator posItem;
// Clear out destination
pcolDest->erase(pcolDest->begin(), pcolDest->end());
// Go through each item in pcolSrc and add to pcolDest
//
posItem = colSrc.begin(); while (posItem != colSrc.end()) { pcolDest->push_back(*posItem); posItem++; } }
PCWSTR SzLoadStringPcch ( HINSTANCE hinst, UINT unId, int* pcch);
//+---------------------------------------------------------------------------
//
// Function: SzLoadString
//
// Purpose: Load a resource string. (This function will never return NULL.)
//
// Arguments:
// hinst [in] Instance handle of module with the string resource.
// unId [in] Resource ID of the string to load.
//
// Returns: Pointer to the constant string.
//
// Author: shaunco 24 Mar 1997
//
// Notes: See SzLoadStringPcch()
//
inline PCWSTR SzLoadString ( HINSTANCE hinst, UINT unId) { int cch; return SzLoadStringPcch(hinst, unId, &cch); }
PSTR SzaDupSza ( IN PCSTR pszaSrc);
PWSTR SzDupSz ( IN PCWSTR pszSrc);
#define GetNextCommaSeparatedToken(pStart, pEnd, cch) \
pStart = pEnd; \ while (*pStart && (*pStart == L' ' || *pStart == L',')) \ { \ pStart++; \ } \ \ pEnd = pStart; \ while (*pEnd && *pEnd != L' ' && *pEnd != L',') \ { \ pEnd++; \ } \ \ cch = (DWORD)(pEnd - pStart);
BOOL FSubstringMatch ( IN PCWSTR pStr1, IN PCWSTR pStr2, OUT const WCHAR** ppStart, OUT ULONG* pcch);
|