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.

115 lines
2.4 KiB

  1. // Copyright (c) 1999 Microsoft Corporation. All rights reserved.
  2. //
  3. // Implementation of Strings and Hash.
  4. //
  5. #include "stdinc.h"
  6. #include "englookup.h"
  7. #include "englex.h"
  8. //////////////////////////////////////////////////////////////////////
  9. // Strings
  10. // Note: Actually this is half the initial size since the first time will realloc and double.
  11. const Strings::index Strings::ms_iInitialSize = 256; // �� Tune this. 16 chars * 32 items / 2 -> 256.
  12. Strings::Strings() : m_pszBuf(NULL), m_iCur(0), m_iSize(ms_iInitialSize)
  13. {
  14. m_iBase = 0;
  15. }
  16. Strings::~Strings(){
  17. char* p = m_pszBuf;
  18. while(p){
  19. char* p2 = *(char**) p;
  20. delete [] p;
  21. p = p2;
  22. }
  23. }
  24. union PointerIndex
  25. {
  26. Strings::index i;
  27. char* p;
  28. };
  29. HRESULT
  30. Strings::Add(const char *psz, index &i)
  31. {
  32. assert(ms_iInitialSize * 2 >= g_iMaxBuffer); // the initial size (doubled) must be large enough to hold the biggest possible identifier
  33. int cch = strlen(psz) + 1; // including the null
  34. if (!m_pszBuf || m_iCur + cch > m_iSize)
  35. {
  36. // realloc
  37. m_iSize *= 2;
  38. DWORD newAlloc = m_iSize - m_iBase;
  39. char *pszBuf = new char[newAlloc + sizeof(char*)];
  40. if (!pszBuf)
  41. return E_OUTOFMEMORY;
  42. m_iBase = m_iCur;
  43. // thread new allocation
  44. *(char**) pszBuf = m_pszBuf;
  45. m_pszBuf = pszBuf;
  46. }
  47. // append the string
  48. char* pDest = m_pszBuf + m_iCur - m_iBase + sizeof(char*);
  49. strcpy(pDest, psz);
  50. PointerIndex Convert;
  51. Convert.i = 0;
  52. Convert.p = pDest;
  53. i = Convert.i; // Yep, i is really a pointer.
  54. m_iCur += cch;
  55. return S_OK;
  56. }
  57. const char *
  58. Strings::operator[](index i)
  59. {
  60. if (!m_pszBuf || ! i)
  61. {
  62. assert(false);
  63. return NULL;
  64. }
  65. PointerIndex Convert;
  66. Convert.i = i;
  67. return Convert.p; // Yep, i is really a pointer.
  68. }
  69. //////////////////////////////////////////////////////////////////////
  70. // Lookup
  71. HRESULT Lookup::FindOrAddInternal(bool fAdd, const char *psz, slotindex &iSlot, Strings::index &iString)
  72. {
  73. StrKey k;
  74. k.psz = psz;
  75. stringhash::entry &e = m_h.Find(k);
  76. if (e.fFound())
  77. {
  78. assert(!fAdd || iSlot > e.v.iSlot);
  79. iSlot = e.v.iSlot;
  80. iString = e.v.iString;
  81. return S_OK;
  82. }
  83. if (!fAdd)
  84. return S_FALSE;
  85. indices v;
  86. v.iSlot = iSlot;
  87. HRESULT hr = m_strings.Add(psz, iString);
  88. if (FAILED(hr))
  89. return hr;
  90. v.iString = iString;
  91. k.psz = m_strings[v.iString]; // need to save key with the string from the permanent store
  92. hr = m_h.Add(e, k, v);
  93. if (FAILED(hr))
  94. return hr;
  95. return S_FALSE;
  96. }