Source code of Windows XP (NT5)
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
//----------------------------------------------------------------------------
//
//----------------------------------------------------------------------------
#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
|