Dict.h (12062B)
1 /* 2 =========================================================================== 3 4 Doom 3 BFG Edition GPL Source Code 5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 6 7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). 8 9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation, either version 3 of the License, or 12 (at your option) any later version. 13 14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>. 21 22 In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below. 23 24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. 25 26 =========================================================================== 27 */ 28 29 #ifndef __DICT_H__ 30 #define __DICT_H__ 31 32 class idSerializer; 33 34 /* 35 =============================================================================== 36 37 Key/value dictionary 38 39 This is a dictionary class that tracks an arbitrary number of key / value 40 pair combinations. It is used for map entity spawning, GUI state management, 41 and other things. 42 43 Keys are compared case-insensitive. 44 45 Does not allocate memory until the first key/value pair is added. 46 47 =============================================================================== 48 */ 49 50 class idKeyValue { 51 friend class idDict; 52 53 public: 54 const idStr & GetKey() const { return *key; } 55 const idStr & GetValue() const { return *value; } 56 57 size_t Allocated() const { return key->Allocated() + value->Allocated(); } 58 size_t Size() const { return sizeof( *this ) + key->Size() + value->Size(); } 59 60 bool operator==( const idKeyValue &kv ) const { return ( key == kv.key && value == kv.value ); } 61 62 private: 63 const idPoolStr * key; 64 const idPoolStr * value; 65 }; 66 67 /* 68 ================================================ 69 idSort_KeyValue 70 ================================================ 71 */ 72 class idSort_KeyValue : public idSort_Quick< idKeyValue, idSort_KeyValue > { 73 public: 74 int Compare( const idKeyValue & a, const idKeyValue & b ) const { return a.GetKey().Icmp( b.GetKey() ); } 75 }; 76 77 class idDict { 78 public: 79 idDict(); 80 idDict( const idDict &other ); // allow declaration with assignment 81 ~idDict(); 82 83 // set the granularity for the index 84 void SetGranularity( int granularity ); 85 // set hash size 86 void SetHashSize( int hashSize ); 87 // clear existing key/value pairs and copy all key/value pairs from other 88 idDict & operator=( const idDict &other ); 89 // copy from other while leaving existing key/value pairs in place 90 void Copy( const idDict &other ); 91 // clear existing key/value pairs and transfer key/value pairs from other 92 void TransferKeyValues( idDict &other ); 93 // parse dict from parser 94 bool Parse( idParser &parser ); 95 // copy key/value pairs from other dict not present in this dict 96 void SetDefaults( const idDict *dict ); 97 // clear dict freeing up memory 98 void Clear(); 99 // print the dict 100 void Print() const; 101 102 size_t Allocated() const; 103 size_t Size() const { return sizeof( *this ) + Allocated(); } 104 105 void Set( const char *key, const char *value ); 106 void SetFloat( const char *key, float val ); 107 void SetInt( const char *key, int val ); 108 void SetBool( const char *key, bool val ); 109 void SetVector( const char *key, const idVec3 &val ); 110 void SetVec2( const char *key, const idVec2 &val ); 111 void SetVec4( const char *key, const idVec4 &val ); 112 void SetAngles( const char *key, const idAngles &val ); 113 void SetMatrix( const char *key, const idMat3 &val ); 114 115 // these return default values of 0.0, 0 and false 116 const char * GetString( const char *key, const char *defaultString = "" ) const; 117 float GetFloat( const char *key, const char *defaultString ) const; 118 int GetInt( const char *key, const char *defaultString ) const; 119 bool GetBool( const char *key, const char *defaultString ) const; 120 float GetFloat( const char *key, const float defaultFloat = 0.0f ) const; 121 int GetInt( const char *key, const int defaultInt = 0 ) const; 122 bool GetBool( const char *key, const bool defaultBool = false ) const; 123 idVec3 GetVector( const char *key, const char *defaultString = NULL ) const; 124 idVec2 GetVec2( const char *key, const char *defaultString = NULL ) const; 125 idVec4 GetVec4( const char *key, const char *defaultString = NULL ) const; 126 idAngles GetAngles( const char *key, const char *defaultString = NULL ) const; 127 idMat3 GetMatrix( const char *key, const char *defaultString = NULL ) const; 128 129 bool GetString( const char *key, const char *defaultString, const char **out ) const; 130 bool GetString( const char *key, const char *defaultString, idStr &out ) const; 131 bool GetFloat( const char *key, const char *defaultString, float &out ) const; 132 bool GetInt( const char *key, const char *defaultString, int &out ) const; 133 bool GetBool( const char *key, const char *defaultString, bool &out ) const; 134 bool GetFloat( const char *key, const float defaultFloat, float &out ) const; 135 bool GetInt( const char *key, const int defaultInt, int &out ) const; 136 bool GetBool( const char *key, const bool defaultBool, bool &out ) const; 137 bool GetVector( const char *key, const char *defaultString, idVec3 &out ) const; 138 bool GetVec2( const char *key, const char *defaultString, idVec2 &out ) const; 139 bool GetVec4( const char *key, const char *defaultString, idVec4 &out ) const; 140 bool GetAngles( const char *key, const char *defaultString, idAngles &out ) const; 141 bool GetMatrix( const char *key, const char *defaultString, idMat3 &out ) const; 142 143 int GetNumKeyVals() const; 144 const idKeyValue * GetKeyVal( int index ) const; 145 // returns the key/value pair with the given key 146 // returns NULL if the key/value pair does not exist 147 const idKeyValue * FindKey( const char *key ) const; 148 // returns the index to the key/value pair with the given key 149 // returns -1 if the key/value pair does not exist 150 int FindKeyIndex( const char *key ) const; 151 // delete the key/value pair with the given key 152 void Delete( const char *key ); 153 // finds the next key/value pair with the given key prefix. 154 // lastMatch can be used to do additional searches past the first match. 155 const idKeyValue * MatchPrefix( const char *prefix, const idKeyValue *lastMatch = NULL ) const; 156 // randomly chooses one of the key/value pairs with the given key prefix and returns it's value 157 const char * RandomPrefix( const char *prefix, idRandom &random ) const; 158 159 void WriteToFileHandle( idFile *f ) const; 160 void ReadFromFileHandle( idFile *f ); 161 162 void WriteToIniFile( idFile * f ) const; 163 bool ReadFromIniFile( idFile * f ); 164 165 void Serialize( idSerializer & ser ); 166 167 // returns a unique checksum for this dictionary's content 168 int Checksum() const; 169 170 static void Init(); 171 static void Shutdown(); 172 173 static void ShowMemoryUsage_f( const idCmdArgs &args ); 174 static void ListKeys_f( const idCmdArgs &args ); 175 static void ListValues_f( const idCmdArgs &args ); 176 177 private: 178 idList<idKeyValue> args; 179 idHashIndex argHash; 180 181 static idStrPool globalKeys; 182 static idStrPool globalValues; 183 }; 184 185 186 ID_INLINE idDict::idDict() { 187 args.SetGranularity( 16 ); 188 argHash.SetGranularity( 16 ); 189 argHash.Clear( 128, 16 ); 190 } 191 192 ID_INLINE idDict::idDict( const idDict &other ) { 193 *this = other; 194 } 195 196 ID_INLINE idDict::~idDict() { 197 Clear(); 198 } 199 200 ID_INLINE void idDict::SetGranularity( int granularity ) { 201 args.SetGranularity( granularity ); 202 argHash.SetGranularity( granularity ); 203 } 204 205 ID_INLINE void idDict::SetHashSize( int hashSize ) { 206 if ( args.Num() == 0 ) { 207 argHash.Clear( hashSize, 16 ); 208 } 209 } 210 211 ID_INLINE void idDict::SetFloat( const char *key, float val ) { 212 Set( key, va( "%f", val ) ); 213 } 214 215 ID_INLINE void idDict::SetInt( const char *key, int val ) { 216 Set( key, va( "%i", val ) ); 217 } 218 219 ID_INLINE void idDict::SetBool( const char *key, bool val ) { 220 Set( key, va( "%i", val ) ); 221 } 222 223 ID_INLINE void idDict::SetVector( const char *key, const idVec3 &val ) { 224 Set( key, val.ToString() ); 225 } 226 227 ID_INLINE void idDict::SetVec4( const char *key, const idVec4 &val ) { 228 Set( key, val.ToString() ); 229 } 230 231 ID_INLINE void idDict::SetVec2( const char *key, const idVec2 &val ) { 232 Set( key, val.ToString() ); 233 } 234 235 ID_INLINE void idDict::SetAngles( const char *key, const idAngles &val ) { 236 Set( key, val.ToString() ); 237 } 238 239 ID_INLINE void idDict::SetMatrix( const char *key, const idMat3 &val ) { 240 Set( key, val.ToString() ); 241 } 242 243 ID_INLINE bool idDict::GetString( const char *key, const char *defaultString, const char **out ) const { 244 const idKeyValue *kv = FindKey( key ); 245 if ( kv ) { 246 *out = kv->GetValue(); 247 return true; 248 } 249 *out = defaultString; 250 return false; 251 } 252 253 ID_INLINE bool idDict::GetString( const char *key, const char *defaultString, idStr &out ) const { 254 const idKeyValue *kv = FindKey( key ); 255 if ( kv ) { 256 out = kv->GetValue(); 257 return true; 258 } 259 out = defaultString; 260 return false; 261 } 262 263 ID_INLINE const char *idDict::GetString( const char *key, const char *defaultString ) const { 264 const idKeyValue *kv = FindKey( key ); 265 if ( kv ) { 266 return kv->GetValue(); 267 } 268 return defaultString; 269 } 270 271 ID_INLINE float idDict::GetFloat( const char *key, const char *defaultString ) const { 272 return atof( GetString( key, defaultString ) ); 273 } 274 275 ID_INLINE int idDict::GetInt( const char *key, const char *defaultString ) const { 276 return atoi( GetString( key, defaultString ) ); 277 } 278 279 ID_INLINE bool idDict::GetBool( const char *key, const char *defaultString ) const { 280 return ( atoi( GetString( key, defaultString ) ) != 0 ); 281 } 282 283 ID_INLINE float idDict::GetFloat( const char *key, const float defaultFloat ) const { 284 const idKeyValue *kv = FindKey( key ); 285 if ( kv ) { 286 return atof( kv->GetValue() ); 287 } 288 return defaultFloat; 289 } 290 291 ID_INLINE int idDict::GetInt( const char *key, int defaultInt ) const { 292 const idKeyValue *kv = FindKey( key ); 293 if ( kv ) { 294 return atoi( kv->GetValue() ); 295 } 296 return defaultInt; 297 } 298 299 ID_INLINE bool idDict::GetBool( const char *key, const bool defaultBool ) const { 300 const idKeyValue *kv = FindKey( key ); 301 if ( kv ) { 302 return atoi( kv->GetValue() ) != 0; 303 } 304 return defaultBool; 305 } 306 307 ID_INLINE idVec3 idDict::GetVector( const char *key, const char *defaultString ) const { 308 idVec3 out; 309 GetVector( key, defaultString, out ); 310 return out; 311 } 312 313 ID_INLINE idVec2 idDict::GetVec2( const char *key, const char *defaultString ) const { 314 idVec2 out; 315 GetVec2( key, defaultString, out ); 316 return out; 317 } 318 319 ID_INLINE idVec4 idDict::GetVec4( const char *key, const char *defaultString ) const { 320 idVec4 out; 321 GetVec4( key, defaultString, out ); 322 return out; 323 } 324 325 ID_INLINE idAngles idDict::GetAngles( const char *key, const char *defaultString ) const { 326 idAngles out; 327 GetAngles( key, defaultString, out ); 328 return out; 329 } 330 331 ID_INLINE idMat3 idDict::GetMatrix( const char *key, const char *defaultString ) const { 332 idMat3 out; 333 GetMatrix( key, defaultString, out ); 334 return out; 335 } 336 337 ID_INLINE int idDict::GetNumKeyVals() const { 338 return args.Num(); 339 } 340 341 ID_INLINE const idKeyValue *idDict::GetKeyVal( int index ) const { 342 if ( index >= 0 && index < args.Num() ) { 343 return &args[ index ]; 344 } 345 return NULL; 346 } 347 348 #endif /* !__DICT_H__ */