windows-nt/Source/XPSP1/NT/multimedia/directx/dmusic/dmscript/englookup.cpp
2020-09-26 16:20:57 +08:00

116 lines
2.4 KiB
C++

// 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;
}