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.
|
|
// Copyright (c) 1999 Microsoft Corporation. All rights reserved.
//
// Implementation of Strings and Hash.
//
#include "stdinc.h"
#include "englookup.h"
#include "englex.h"
//////////////////////////////////////////////////////////////////////
// Strings
// Note: Actually this is half the initial size since the first time will realloc and double.
const Strings::index Strings::ms_iInitialSize = 256; // �� Tune this. 16 chars * 32 items / 2 -> 256.
Strings::Strings() : m_pszBuf(NULL), m_iCur(0), m_iSize(ms_iInitialSize) { m_iBase = 0; }
Strings::~Strings(){ char* p = m_pszBuf; while(p){ char* p2 = *(char**) p; delete [] p; p = p2; } }
union PointerIndex { Strings::index i; char* p; };
HRESULT Strings::Add(const char *psz, index &i) { assert(ms_iInitialSize * 2 >= g_iMaxBuffer); // the initial size (doubled) must be large enough to hold the biggest possible identifier
int cch = strlen(psz) + 1; // including the null
if (!m_pszBuf || m_iCur + cch > m_iSize) { // realloc
m_iSize *= 2; DWORD newAlloc = m_iSize - m_iBase; char *pszBuf = new char[newAlloc + sizeof(char*)]; if (!pszBuf) return E_OUTOFMEMORY; m_iBase = m_iCur;
// thread new allocation
*(char**) pszBuf = m_pszBuf; m_pszBuf = pszBuf; }
// append the string
char* pDest = m_pszBuf + m_iCur - m_iBase + sizeof(char*); strcpy(pDest, psz); PointerIndex Convert; Convert.i = 0; Convert.p = pDest; i = Convert.i; // Yep, i is really a pointer.
m_iCur += cch;
return S_OK; }
const char * Strings::operator[](index i) { if (!m_pszBuf || ! i) { assert(false); return NULL; }
PointerIndex Convert; Convert.i = i; return Convert.p; // Yep, i is really a pointer.
}
//////////////////////////////////////////////////////////////////////
// Lookup
HRESULT Lookup::FindOrAddInternal(bool fAdd, const char *psz, slotindex &iSlot, Strings::index &iString) { StrKey k; k.psz = psz;
stringhash::entry &e = m_h.Find(k); if (e.fFound()) { assert(!fAdd || iSlot > e.v.iSlot); iSlot = e.v.iSlot; iString = e.v.iString; return S_OK; }
if (!fAdd) return S_FALSE;
indices v; v.iSlot = iSlot; HRESULT hr = m_strings.Add(psz, iString); if (FAILED(hr)) return hr; v.iString = iString; k.psz = m_strings[v.iString]; // need to save key with the string from the permanent store
hr = m_h.Add(e, k, v); if (FAILED(hr)) return hr;
return S_FALSE; }
|