Team Fortress 2 Source Code as on 22/4/2020
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.

269 lines
7.2 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Defines a symbol table
  4. //
  5. // $Header: $
  6. // $NoKeywords: $
  7. //===========================================================================//
  8. #ifndef UTLSYMBOL_H
  9. #define UTLSYMBOL_H
  10. #ifdef _WIN32
  11. #pragma once
  12. #endif
  13. #include "tier0/threadtools.h"
  14. #include "tier1/utlrbtree.h"
  15. #include "tier1/utlvector.h"
  16. //-----------------------------------------------------------------------------
  17. // forward declarations
  18. //-----------------------------------------------------------------------------
  19. class CUtlSymbolTable;
  20. class CUtlSymbolTableMT;
  21. //-----------------------------------------------------------------------------
  22. // This is a symbol, which is a easier way of dealing with strings.
  23. //-----------------------------------------------------------------------------
  24. typedef unsigned short UtlSymId_t;
  25. #define UTL_INVAL_SYMBOL ((UtlSymId_t)~0)
  26. class CUtlSymbol
  27. {
  28. public:
  29. // constructor, destructor
  30. CUtlSymbol() : m_Id(UTL_INVAL_SYMBOL) {}
  31. CUtlSymbol( UtlSymId_t id ) : m_Id(id) {}
  32. CUtlSymbol( const char* pStr );
  33. CUtlSymbol( CUtlSymbol const& sym ) : m_Id(sym.m_Id) {}
  34. // operator=
  35. CUtlSymbol& operator=( CUtlSymbol const& src ) { m_Id = src.m_Id; return *this; }
  36. // operator==
  37. bool operator==( CUtlSymbol const& src ) const { return m_Id == src.m_Id; }
  38. bool operator==( const char* pStr ) const;
  39. // Is valid?
  40. bool IsValid() const { return m_Id != UTL_INVAL_SYMBOL; }
  41. // Gets at the symbol
  42. operator UtlSymId_t const() const { return m_Id; }
  43. // Gets the string associated with the symbol
  44. const char* String( ) const;
  45. // Modules can choose to disable the static symbol table so to prevent accidental use of them.
  46. static void DisableStaticSymbolTable();
  47. protected:
  48. UtlSymId_t m_Id;
  49. // Initializes the symbol table
  50. static void Initialize();
  51. // returns the current symbol table
  52. static CUtlSymbolTableMT* CurrTable();
  53. // The standard global symbol table
  54. static CUtlSymbolTableMT* s_pSymbolTable;
  55. static bool s_bAllowStaticSymbolTable;
  56. friend class CCleanupUtlSymbolTable;
  57. };
  58. //-----------------------------------------------------------------------------
  59. // CUtlSymbolTable:
  60. // description:
  61. // This class defines a symbol table, which allows us to perform mappings
  62. // of strings to symbols and back. The symbol class itself contains
  63. // a static version of this class for creating global strings, but this
  64. // class can also be instanced to create local symbol tables.
  65. //-----------------------------------------------------------------------------
  66. class CUtlSymbolTable
  67. {
  68. public:
  69. // constructor, destructor
  70. CUtlSymbolTable( int growSize = 0, int initSize = 32, bool caseInsensitive = false );
  71. ~CUtlSymbolTable();
  72. // Finds and/or creates a symbol based on the string
  73. CUtlSymbol AddString( const char* pString );
  74. // Finds the symbol for pString
  75. CUtlSymbol Find( const char* pString ) const;
  76. // Look up the string associated with a particular symbol
  77. const char* String( CUtlSymbol id ) const;
  78. // Remove all symbols in the table.
  79. void RemoveAll();
  80. int GetNumStrings( void ) const
  81. {
  82. return m_Lookup.Count();
  83. }
  84. protected:
  85. class CStringPoolIndex
  86. {
  87. public:
  88. inline CStringPoolIndex()
  89. {
  90. }
  91. inline CStringPoolIndex( unsigned short iPool, unsigned short iOffset )
  92. {
  93. m_iPool = iPool;
  94. m_iOffset = iOffset;
  95. }
  96. inline bool operator==( const CStringPoolIndex &other ) const
  97. {
  98. return m_iPool == other.m_iPool && m_iOffset == other.m_iOffset;
  99. }
  100. unsigned short m_iPool; // Index into m_StringPools.
  101. unsigned short m_iOffset; // Index into the string pool.
  102. };
  103. class CLess
  104. {
  105. public:
  106. CLess( int ignored = 0 ) {} // permits default initialization to NULL in CUtlRBTree
  107. bool operator!() const { return false; }
  108. bool operator()( const CStringPoolIndex &left, const CStringPoolIndex &right ) const;
  109. };
  110. // Stores the symbol lookup
  111. class CTree : public CUtlRBTree<CStringPoolIndex, unsigned short, CLess>
  112. {
  113. public:
  114. CTree( int growSize, int initSize ) : CUtlRBTree<CStringPoolIndex, unsigned short, CLess>( growSize, initSize ) {}
  115. friend class CUtlSymbolTable::CLess; // Needed to allow CLess to calculate pointer to symbol table
  116. };
  117. struct StringPool_t
  118. {
  119. int m_TotalLen; // How large is
  120. int m_SpaceUsed;
  121. char m_Data[1];
  122. };
  123. CTree m_Lookup;
  124. bool m_bInsensitive;
  125. mutable const char* m_pUserSearchString;
  126. // stores the string data
  127. CUtlVector<StringPool_t*> m_StringPools;
  128. private:
  129. int FindPoolWithSpace( int len ) const;
  130. const char* StringFromIndex( const CStringPoolIndex &index ) const;
  131. friend class CLess;
  132. };
  133. class CUtlSymbolTableMT : private CUtlSymbolTable
  134. {
  135. public:
  136. CUtlSymbolTableMT( int growSize = 0, int initSize = 32, bool caseInsensitive = false )
  137. : CUtlSymbolTable( growSize, initSize, caseInsensitive )
  138. {
  139. }
  140. CUtlSymbol AddString( const char* pString )
  141. {
  142. m_lock.LockForWrite();
  143. CUtlSymbol result = CUtlSymbolTable::AddString( pString );
  144. m_lock.UnlockWrite();
  145. return result;
  146. }
  147. CUtlSymbol Find( const char* pString ) const
  148. {
  149. m_lock.LockForRead();
  150. CUtlSymbol result = CUtlSymbolTable::Find( pString );
  151. m_lock.UnlockRead();
  152. return result;
  153. }
  154. const char* String( CUtlSymbol id ) const
  155. {
  156. m_lock.LockForRead();
  157. const char *pszResult = CUtlSymbolTable::String( id );
  158. m_lock.UnlockRead();
  159. return pszResult;
  160. }
  161. private:
  162. #if defined(WIN32) || defined(_WIN32)
  163. mutable CThreadSpinRWLock m_lock;
  164. #else
  165. mutable CThreadRWLock m_lock;
  166. #endif
  167. };
  168. //-----------------------------------------------------------------------------
  169. // CUtlFilenameSymbolTable:
  170. // description:
  171. // This class defines a symbol table of individual filenames, stored more
  172. // efficiently than a standard symbol table. Internally filenames are broken
  173. // up into file and path entries, and a file handle class allows convenient
  174. // access to these.
  175. //-----------------------------------------------------------------------------
  176. // The handle is a CUtlSymbol for the dirname and the same for the filename, the accessor
  177. // copies them into a static char buffer for return.
  178. typedef void* FileNameHandle_t;
  179. #define FILENAMEHANDLE_INVALID 0
  180. // Symbol table for more efficiently storing filenames by breaking paths and filenames apart.
  181. // Refactored from BaseFileSystem.h
  182. class CUtlFilenameSymbolTable
  183. {
  184. // Internal representation of a FileHandle_t
  185. // If we get more than 64K filenames, we'll have to revisit...
  186. // Right now CUtlSymbol is a short, so this packs into an int/void * pointer size...
  187. struct FileNameHandleInternal_t
  188. {
  189. FileNameHandleInternal_t()
  190. {
  191. path = 0;
  192. file = 0;
  193. }
  194. // Part before the final '/' character
  195. unsigned short path;
  196. // Part after the final '/', including extension
  197. unsigned short file;
  198. };
  199. class HashTable;
  200. public:
  201. CUtlFilenameSymbolTable();
  202. ~CUtlFilenameSymbolTable();
  203. FileNameHandle_t FindOrAddFileName( const char *pFileName );
  204. FileNameHandle_t FindFileName( const char *pFileName );
  205. int PathIndex(const FileNameHandle_t &handle) { return (( const FileNameHandleInternal_t * )&handle)->path; }
  206. bool String( const FileNameHandle_t& handle, char *buf, int buflen );
  207. void RemoveAll();
  208. private:
  209. //CCountedStringPool m_StringPool;
  210. HashTable* m_Strings;
  211. mutable CThreadSpinRWLock m_lock;
  212. };
  213. #endif // UTLSYMBOL_H