mirror of
https://github.com/0TheSpy/Seaside.git
synced 2025-01-07 10:03:29 +08:00
210 lines
4.4 KiB
C++
210 lines
4.4 KiB
C++
#ifndef UTLSYMBOL_H
|
|
#define UTLSYMBOL_H
|
|
|
|
#ifdef _WIN32
|
|
#pragma once
|
|
#endif
|
|
|
|
#include "threadtools.h"
|
|
#include "utlrbtree.h"
|
|
#include "utlvector.h"
|
|
|
|
|
|
class CUtlSymbolTable;
|
|
class CUtlSymbolTableMT;
|
|
|
|
|
|
typedef unsigned short UtlSymId_t;
|
|
|
|
#define UTL_INVAL_SYMBOL ((UtlSymId_t)~0)
|
|
|
|
class CUtlSymbol
|
|
{
|
|
public:
|
|
CUtlSymbol() : m_Id(UTL_INVAL_SYMBOL) {}
|
|
CUtlSymbol(UtlSymId_t id) : m_Id(id) {}
|
|
CUtlSymbol(const char* pStr);
|
|
CUtlSymbol(CUtlSymbol const& sym) : m_Id(sym.m_Id) {}
|
|
|
|
CUtlSymbol& operator=(CUtlSymbol const& src) { m_Id = src.m_Id; return *this; }
|
|
|
|
bool operator==(CUtlSymbol const& src) const { return m_Id == src.m_Id; }
|
|
bool operator==(const char* pStr) const;
|
|
|
|
bool IsValid() const { return m_Id != UTL_INVAL_SYMBOL; }
|
|
|
|
operator UtlSymId_t const() const { return m_Id; }
|
|
|
|
const char* String() const;
|
|
|
|
static void DisableStaticSymbolTable();
|
|
|
|
protected:
|
|
UtlSymId_t m_Id;
|
|
|
|
static void Initialize();
|
|
|
|
static CUtlSymbolTableMT* CurrTable();
|
|
|
|
static CUtlSymbolTableMT* s_pSymbolTable;
|
|
|
|
static bool s_bAllowStaticSymbolTable;
|
|
|
|
friend class CCleanupUtlSymbolTable;
|
|
};
|
|
|
|
|
|
class CUtlSymbolTable
|
|
{
|
|
public:
|
|
CUtlSymbolTable(int growSize = 0, int initSize = 32, bool caseInsensitive = false);
|
|
~CUtlSymbolTable();
|
|
|
|
CUtlSymbol AddString(const char* pString);
|
|
|
|
CUtlSymbol Find(const char* pString) const;
|
|
|
|
const char* String(CUtlSymbol id) const;
|
|
|
|
void RemoveAll();
|
|
|
|
int GetNumStrings(void) const
|
|
{
|
|
return m_Lookup.Count();
|
|
}
|
|
|
|
protected:
|
|
class CStringPoolIndex
|
|
{
|
|
public:
|
|
inline CStringPoolIndex()
|
|
{
|
|
}
|
|
|
|
inline CStringPoolIndex(unsigned short iPool, unsigned short iOffset)
|
|
{
|
|
m_iPool = iPool;
|
|
m_iOffset = iOffset;
|
|
}
|
|
|
|
inline bool operator==(const CStringPoolIndex& other) const
|
|
{
|
|
return m_iPool == other.m_iPool && m_iOffset == other.m_iOffset;
|
|
}
|
|
|
|
unsigned short m_iPool;
|
|
unsigned short m_iOffset;
|
|
};
|
|
|
|
class CLess
|
|
{
|
|
public:
|
|
CLess(int ignored = 0) {}
|
|
bool operator!() const { return false; }
|
|
bool operator()(const CStringPoolIndex& left, const CStringPoolIndex& right) const;
|
|
};
|
|
|
|
class CTree : public CUtlRBTree<CStringPoolIndex, unsigned short, CLess>
|
|
{
|
|
public:
|
|
CTree(int growSize, int initSize) : CUtlRBTree<CStringPoolIndex, unsigned short, CLess>(growSize, initSize) {}
|
|
friend class CUtlSymbolTable::CLess;
|
|
};
|
|
|
|
struct StringPool_t
|
|
{
|
|
int m_TotalLen;
|
|
int m_SpaceUsed;
|
|
char m_Data[1];
|
|
};
|
|
|
|
CTree m_Lookup;
|
|
bool m_bInsensitive;
|
|
mutable const char* m_pUserSearchString;
|
|
|
|
CUtlVector<StringPool_t*> m_StringPools;
|
|
|
|
private:
|
|
int FindPoolWithSpace(int len) const;
|
|
const char* StringFromIndex(const CStringPoolIndex& index) const;
|
|
|
|
friend class CLess;
|
|
};
|
|
|
|
class CUtlSymbolTableMT : private CUtlSymbolTable
|
|
{
|
|
public:
|
|
CUtlSymbolTableMT(int growSize = 0, int initSize = 32, bool caseInsensitive = false)
|
|
: CUtlSymbolTable(growSize, initSize, caseInsensitive)
|
|
{
|
|
}
|
|
|
|
CUtlSymbol AddString(const char* pString)
|
|
{
|
|
m_lock.LockForWrite();
|
|
CUtlSymbol result = CUtlSymbolTable::AddString(pString);
|
|
m_lock.UnlockWrite();
|
|
return result;
|
|
}
|
|
|
|
CUtlSymbol Find(const char* pString) const
|
|
{
|
|
m_lock.LockForRead();
|
|
CUtlSymbol result = CUtlSymbolTable::Find(pString);
|
|
m_lock.UnlockRead();
|
|
return result;
|
|
}
|
|
|
|
const char* String(CUtlSymbol id) const
|
|
{
|
|
m_lock.LockForRead();
|
|
const char* pszResult = CUtlSymbolTable::String(id);
|
|
m_lock.UnlockRead();
|
|
return pszResult;
|
|
}
|
|
|
|
private:
|
|
#if defined(WIN32) || defined(_WIN32)
|
|
mutable CThreadSpinRWLock m_lock;
|
|
#else
|
|
mutable CThreadRWLock m_lock;
|
|
#endif
|
|
};
|
|
|
|
|
|
|
|
typedef void* FileNameHandle_t;
|
|
#define FILENAMEHANDLE_INVALID 0
|
|
|
|
class CUtlFilenameSymbolTable
|
|
{
|
|
struct FileNameHandleInternal_t
|
|
{
|
|
FileNameHandleInternal_t()
|
|
{
|
|
path = 0;
|
|
file = 0;
|
|
}
|
|
|
|
unsigned short path;
|
|
unsigned short file;
|
|
};
|
|
|
|
class HashTable;
|
|
|
|
public:
|
|
CUtlFilenameSymbolTable();
|
|
~CUtlFilenameSymbolTable();
|
|
FileNameHandle_t FindOrAddFileName(const char* pFileName);
|
|
FileNameHandle_t FindFileName(const char* pFileName);
|
|
int PathIndex(const FileNameHandle_t& handle) { return ((const FileNameHandleInternal_t*)&handle)->path; }
|
|
bool String(const FileNameHandle_t& handle, char* buf, int buflen);
|
|
void RemoveAll();
|
|
|
|
private:
|
|
HashTable* m_Strings;
|
|
mutable CThreadSpinRWLock m_lock;
|
|
};
|
|
|
|
|
|
#endif |