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.

169 lines
5.6 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. //----------------------------------------------------------------------------
  4. #ifndef _STRINGLST_H
  5. #define _STRINGLST_H
  6. // Helper functions to properly create CWCStringList.
  7. class CWCStringList;
  8. CWCStringList *CreateCWCStringList(int iInitBufSize=4096);
  9. // BSTR is DWORD length followed by null-term OLECHAR (WCHAR) data
  10. //
  11. //----------------------------------------------------------------------------
  12. // CWCStringList is used to store array of non-duplicate strings. Used for
  13. // dependency and link storage.
  14. //
  15. // Limitations:
  16. // 1) Strings can only be added and never removed from list
  17. // 2) No duplicate strings can ever be stored
  18. //
  19. // Stores all strings in one big block of memory
  20. // It's efficient at ensuring there are no duplicate strings.
  21. // Scalable. Uses hash. Expands to the limit of memory.
  22. //
  23. // Usage:
  24. // Create the class. Call Init() and destroy if it fails.
  25. // Add the strings with AddString
  26. // Use NumStrings() and GetString() to iterate through all of the stored strings.
  27. //
  28. // The state can be saved and restored with IPersistStream operations
  29. //
  30. // We take up memory when we're loaded. Don't initialize one of these objects
  31. // until you're going to use it.
  32. //----------------------------------------------------------------------------
  33. const int STRING_HASH_SIZE = 127; // should be prime
  34. const TCHAR PARSE_STRING_DELIM = TEXT('\n'); // To separate URLs
  35. // We're not an OLE object but support IPersistStream members to make saving
  36. // & restoring easier
  37. class CWCStringList {
  38. public:
  39. CWCStringList();
  40. virtual ~CWCStringList();
  41. // Return from AddString
  42. enum { STRLST_FAIL=0, STRLST_DUPLICATE=1, STRLST_ADDED=2 };
  43. // iInitBufSize is minimum starting buffer size, or -1 for default
  44. virtual BOOL Init(int iInitBufSize=-1);
  45. virtual int AddString(LPCWSTR lpwstr, DWORD_PTR dwData = 0, int *piNum = NULL);
  46. virtual DWORD_PTR GetStringData(int iNum) { return 0; }
  47. virtual void SetStringData(int iNum, DWORD_PTR dw) { return; }
  48. int NumStrings() { return m_iNumStrings; }
  49. // iLen must be length in characters of string, not counting null term.
  50. // -1 if unknown.
  51. BOOL FindString(LPCWSTR lpwstr, int iLen, int *piNum=NULL);
  52. // Returns const pointer to within stringlist's memory
  53. LPCWSTR GetString (int iNum)
  54. {
  55. ASSERT(iNum < m_iNumStrings);
  56. return m_psiStrings[iNum].lpwstr;
  57. }
  58. // Returns length of string in characters
  59. int GetStringLen (int iNum)
  60. {
  61. ASSERT(iNum < m_iNumStrings);
  62. return m_psiStrings[iNum].iLen;
  63. }
  64. // Returns new BSTR. Free with SysFreeString when you're done.
  65. BSTR GetBSTR (int iNum);
  66. // IUnknown members
  67. // STDMETHODIMP QueryInterface(REFIID riid, void **punk);
  68. // STDMETHODIMP_(ULONG) AddRef(void);
  69. // STDMETHODIMP_(ULONG) Release(void);
  70. // IPersistStream members
  71. // STDMETHODIMP GetClassID(CLSID *pClassID);
  72. STDMETHODIMP IsDirty(void); // Always returns TRUE
  73. STDMETHODIMP Load(IStream *pStm);
  74. STDMETHODIMP Save(IStream *pStm, BOOL fClearDirty);
  75. STDMETHODIMP GetSizeMax(ULARGE_INTEGER *pcbSize);
  76. enum { DEFAULT_INIT_BUF_SIZE = 4096 };
  77. protected:
  78. void CleanUp();
  79. void Clear();
  80. void Reset();
  81. BOOL InitializeFromBuffer();
  82. BOOL m_fValid; // Are our buffers initialized?
  83. int m_iNumStrings; // # of strings so far.
  84. int m_iMaxStrings; // # of elements in m_psiStrings
  85. private:
  86. typedef struct tagStringIndex {
  87. LPCWSTR lpwstr; // pointer to string text in m_pBuffer
  88. int iLen; // length of this string in characters w/o null term
  89. tagStringIndex* psiNext; // index of next string with same hash value
  90. } STRING_INDEX, *PSTRING_INDEX, *LPSTRING_INDEX;
  91. LPSTR m_pBuffer; // Holds all strings
  92. int m_iBufEnd; // Last byte used in buffer
  93. int m_iBufSize;
  94. LPSTRING_INDEX m_psiStrings; // dynamically allocated array
  95. LPSTRING_INDEX m_Hash[STRING_HASH_SIZE]; // hash table (array of ptrs within m_psiStrings)
  96. int m_iLastHash; // used to avoid recalculating hashes
  97. BOOL InsertToHash(LPCWSTR lpwstr, int iLen, BOOL fAlreadyHashed);
  98. int Hash(LPCWSTR lpwstr, int iLen)
  99. {
  100. unsigned long hash=0;
  101. while (iLen--)
  102. {
  103. hash = (hash<<5) + hash + *lpwstr++;
  104. }
  105. return m_iLastHash = (int)(hash % STRING_HASH_SIZE);
  106. }
  107. #ifdef DEBUG
  108. void SpewHashStats(BOOL fVerbose);
  109. #endif
  110. };
  111. // Helper macros to create the string lists
  112. inline CWCStringList *CreateCWCStringList(int iInitBufSize)
  113. {
  114. CWCStringList *pRet = new CWCStringList();
  115. if (pRet->Init(iInitBufSize))
  116. {
  117. return pRet;
  118. }
  119. delete pRet;
  120. return NULL;
  121. }
  122. // CWCDwordStringList stores an extra DWORD of data along with each string.
  123. // This data does not get persisted
  124. class CWCDwordStringList : public CWCStringList {
  125. public:
  126. CWCDwordStringList();
  127. ~CWCDwordStringList();
  128. // these are all virtual
  129. BOOL Init(int iInitBufSize=-1);
  130. int AddString(LPCWSTR psz, DWORD_PTR dwData = 0, int *piNum = NULL);
  131. DWORD_PTR GetStringData(int iNum) { return m_pData[iNum]; }
  132. void SetStringData(int iNum, DWORD_PTR dw) { m_pData[iNum] = dw; }
  133. private:
  134. DWORD_PTR *m_pData; // data our caller wants attached to the strings
  135. };
  136. #endif // _STRINGLST_H