windows-nt/Source/XPSP1/NT/shell/ext/webcheck/strlist.h
2020-09-26 16:20:57 +08:00

170 lines
5.6 KiB
C++

//----------------------------------------------------------------------------
//
//----------------------------------------------------------------------------
#ifndef _STRINGLST_H
#define _STRINGLST_H
// Helper functions to properly create CWCStringList.
class CWCStringList;
CWCStringList *CreateCWCStringList(int iInitBufSize=4096);
// BSTR is DWORD length followed by null-term OLECHAR (WCHAR) data
//
//----------------------------------------------------------------------------
// CWCStringList is used to store array of non-duplicate strings. Used for
// dependency and link storage.
//
// Limitations:
// 1) Strings can only be added and never removed from list
// 2) No duplicate strings can ever be stored
//
// Stores all strings in one big block of memory
// It's efficient at ensuring there are no duplicate strings.
// Scalable. Uses hash. Expands to the limit of memory.
//
// Usage:
// Create the class. Call Init() and destroy if it fails.
// Add the strings with AddString
// Use NumStrings() and GetString() to iterate through all of the stored strings.
//
// The state can be saved and restored with IPersistStream operations
//
// We take up memory when we're loaded. Don't initialize one of these objects
// until you're going to use it.
//----------------------------------------------------------------------------
const int STRING_HASH_SIZE = 127; // should be prime
const TCHAR PARSE_STRING_DELIM = TEXT('\n'); // To separate URLs
// We're not an OLE object but support IPersistStream members to make saving
// & restoring easier
class CWCStringList {
public:
CWCStringList();
virtual ~CWCStringList();
// Return from AddString
enum { STRLST_FAIL=0, STRLST_DUPLICATE=1, STRLST_ADDED=2 };
// iInitBufSize is minimum starting buffer size, or -1 for default
virtual BOOL Init(int iInitBufSize=-1);
virtual int AddString(LPCWSTR lpwstr, DWORD_PTR dwData = 0, int *piNum = NULL);
virtual DWORD_PTR GetStringData(int iNum) { return 0; }
virtual void SetStringData(int iNum, DWORD_PTR dw) { return; }
int NumStrings() { return m_iNumStrings; }
// iLen must be length in characters of string, not counting null term.
// -1 if unknown.
BOOL FindString(LPCWSTR lpwstr, int iLen, int *piNum=NULL);
// Returns const pointer to within stringlist's memory
LPCWSTR GetString (int iNum)
{
ASSERT(iNum < m_iNumStrings);
return m_psiStrings[iNum].lpwstr;
}
// Returns length of string in characters
int GetStringLen (int iNum)
{
ASSERT(iNum < m_iNumStrings);
return m_psiStrings[iNum].iLen;
}
// Returns new BSTR. Free with SysFreeString when you're done.
BSTR GetBSTR (int iNum);
// IUnknown members
// STDMETHODIMP QueryInterface(REFIID riid, void **punk);
// STDMETHODIMP_(ULONG) AddRef(void);
// STDMETHODIMP_(ULONG) Release(void);
// IPersistStream members
// STDMETHODIMP GetClassID(CLSID *pClassID);
STDMETHODIMP IsDirty(void); // Always returns TRUE
STDMETHODIMP Load(IStream *pStm);
STDMETHODIMP Save(IStream *pStm, BOOL fClearDirty);
STDMETHODIMP GetSizeMax(ULARGE_INTEGER *pcbSize);
enum { DEFAULT_INIT_BUF_SIZE = 4096 };
protected:
void CleanUp();
void Clear();
void Reset();
BOOL InitializeFromBuffer();
BOOL m_fValid; // Are our buffers initialized?
int m_iNumStrings; // # of strings so far.
int m_iMaxStrings; // # of elements in m_psiStrings
private:
typedef struct tagStringIndex {
LPCWSTR lpwstr; // pointer to string text in m_pBuffer
int iLen; // length of this string in characters w/o null term
tagStringIndex* psiNext; // index of next string with same hash value
} STRING_INDEX, *PSTRING_INDEX, *LPSTRING_INDEX;
LPSTR m_pBuffer; // Holds all strings
int m_iBufEnd; // Last byte used in buffer
int m_iBufSize;
LPSTRING_INDEX m_psiStrings; // dynamically allocated array
LPSTRING_INDEX m_Hash[STRING_HASH_SIZE]; // hash table (array of ptrs within m_psiStrings)
int m_iLastHash; // used to avoid recalculating hashes
BOOL InsertToHash(LPCWSTR lpwstr, int iLen, BOOL fAlreadyHashed);
int Hash(LPCWSTR lpwstr, int iLen)
{
unsigned long hash=0;
while (iLen--)
{
hash = (hash<<5) + hash + *lpwstr++;
}
return m_iLastHash = (int)(hash % STRING_HASH_SIZE);
}
#ifdef DEBUG
void SpewHashStats(BOOL fVerbose);
#endif
};
// Helper macros to create the string lists
inline CWCStringList *CreateCWCStringList(int iInitBufSize)
{
CWCStringList *pRet = new CWCStringList();
if (pRet->Init(iInitBufSize))
{
return pRet;
}
delete pRet;
return NULL;
}
// CWCDwordStringList stores an extra DWORD of data along with each string.
// This data does not get persisted
class CWCDwordStringList : public CWCStringList {
public:
CWCDwordStringList();
~CWCDwordStringList();
// these are all virtual
BOOL Init(int iInitBufSize=-1);
int AddString(LPCWSTR psz, DWORD_PTR dwData = 0, int *piNum = NULL);
DWORD_PTR GetStringData(int iNum) { return m_pData[iNum]; }
void SetStringData(int iNum, DWORD_PTR dw) { m_pData[iNum] = dw; }
private:
DWORD_PTR *m_pData; // data our caller wants attached to the strings
};
#endif // _STRINGLST_H