etqw-sdk/source/idlib/Dict.h

337 lines
11 KiB
C++

// Copyright (C) 2007 Id Software, Inc.
//
#ifndef __DICT_H__
#define __DICT_H__
/*
===============================================================================
Key/value dictionary
This is a dictionary class that tracks an arbitrary number of key / value
pair combinations. It is used for map entity spawning, GUI state management,
and other things.
Keys are compared case-insensitive.
Does not allocate memory until the first key/value pair is added.
===============================================================================
*/
class idKeyValue {
friend class idDict;
public:
const idStr & GetKey( void ) const { return *key; }
const idStr & GetValue( void ) const { return *value; }
size_t Allocated( void ) const { return key->Allocated() + value->Allocated(); }
size_t Size( void ) const { return sizeof( *this ) + key->Size() + value->Size(); }
bool operator==( const idKeyValue &kv ) const { return ( key == kv.key && value == kv.value ); }
private:
const idPoolStr * key;
const idPoolStr * value;
};
class idDict {
public:
idDict( void );
idDict( const idDict &other ); // allow declaration with assignment
~idDict( void );
// set the granularity for the index
void SetGranularity( int granularity );
// set hash size
void SetHashSize( int hashSize );
// clear existing key/value pairs and copy all key/value pairs from other
idDict & operator=( const idDict &other );
// copy from other while leaving existing key/value pairs in place
void Copy( const idDict &other );
// clear existing key/value pairs and transfer key/value pairs from other
void TransferKeyValues( idDict &other );
// parse dict from parser
bool Parse( idParser &parser );
// parse dict from lexer
bool Parse( idLexer &parser );
// write the key value pairs to a file
bool WriteIndented( idFile* file, bool indentFirst = false ) const;
// copy key/value pairs from other dict not present in this dict
void SetDefaults( const idDict *dict );
// clear dict freeing up memory
void Clear( void );
// print the dict
void Print() const;
size_t Allocated( void ) const;
size_t Size( void ) const { return sizeof( *this ) + Allocated(); }
bool Set( const char *key, const char *value );
bool SetFloat( const char *key, float val );
bool SetInt( const char *key, int val );
bool SetBool( const char *key, bool val );
bool SetVector( const char *key, const idVec3 &val );
bool SetVec2( const char *key, const idVec2 &val );
bool SetVec4( const char *key, const idVec4 &val );
bool SetAngles( const char *key, const idAngles &val );
bool SetMatrix( const char *key, const idMat3 &val );
bool Set( int index, const char *value );
bool SetFloat( int index, float val );
bool SetInt( int index, int val );
bool SetBool( int index, bool val );
bool SetVector( int index, const idVec3 &val );
bool SetVec2( int index, const idVec2 &val );
bool SetVec4( int index, const idVec4 &val );
bool SetAngles( int index, const idAngles &val );
bool SetMatrix( int index, const idMat3 &val );
// these return default values of 0.0, 0 and false
const char * GetString( const char *key, const char *defaultString = "" ) const;
float GetFloat( const char *key, const char *defaultString = "0" ) const;
int GetInt( const char *key, const char *defaultString = "0" ) const;
bool GetBool( const char *key, const char *defaultString = "0" ) const;
idVec3 GetVector( const char *key, const char *defaultString = NULL ) const;
idVec2 GetVec2( const char *key, const char *defaultString = NULL ) const;
idVec4 GetVec4( const char *key, const char *defaultString = NULL ) const;
idAngles GetAngles( const char *key, const char *defaultString = NULL ) const;
idMat3 GetMatrix( const char *key, const char *defaultString = NULL ) const;
bool GetString( const char *key, const char *defaultString, const char **out ) const;
bool GetString( const char *key, const char *defaultString, idStr &out ) const;
bool GetFloat( const char *key, const char *defaultString, float &out ) const;
bool GetInt( const char *key, const char *defaultString, int &out ) const;
bool GetBool( const char *key, const char *defaultString, bool &out ) const;
bool GetVector( const char *key, const char *defaultString, idVec3 &out ) const;
bool GetVec2( const char *key, const char *defaultString, idVec2 &out ) const;
bool GetVec4( const char *key, const char *defaultString, idVec4 &out ) const;
bool GetAngles( const char *key, const char *defaultString, idAngles &out ) const;
bool GetMatrix( const char *key, const char *defaultString, idMat3 &out ) const;
int GetNumKeyVals( void ) const;
const idKeyValue * GetKeyVal( int index ) const;
// returns the key/value pair with the given key
// returns NULL if the key/value pair does not exist
const idKeyValue * FindKey( const char *key ) const;
// returns the index to the key/value pair with the given key
// returns -1 if the key/value pair does not exist
int FindKeyIndex( const char *key ) const;
// returns the index to the k/v pair with the given key, creates an empty one if not found
int GenerateKey( const char *key );
// delete the key/value pair with the given key
void Delete( const char *key );
// finds the next key/value pair with the given key prefix.
// lastMatch can be used to do additional searches past the first match.
const idKeyValue * MatchPrefix( const char *prefix, const idKeyValue *lastMatch = NULL ) const;
// randomly chooses one of the key/value pairs with the given key prefix and returns it's value
const char * RandomPrefix( const char *prefix, idRandom &random ) const;
void WriteToFileHandle( idFile *f ) const;
void ReadFromFileHandle( idFile *f );
// returns a unique checksum for this dictionary's content
unsigned int Checksum( void ) const;
void Swap( idDict& rhs );
static void SetGlobalPools( idStrPool* globalKeys, idStrPool* globalValues );
static void GetGlobalPools( idStrPool*& _globalKeys, idStrPool*& _globalValues );
static void Init( void );
static void Shutdown( void );
static void ShowMemoryUsage_f( const idCmdArgs &args );
static void ListKeys_f( const idCmdArgs &args );
static void ListValues_f( const idCmdArgs &args );
private:
idList<idKeyValue> args;
idHashIndex argHash;
static idStrPool* globalKeys;
static idStrPool* globalValues;
};
ID_INLINE idDict::idDict( void ) {
args.SetGranularity( 16 );
argHash.SetGranularity( 16 );
argHash.Clear( 128, 16 );
}
ID_INLINE idDict::idDict( const idDict &other ) {
*this = other;
}
ID_INLINE idDict::~idDict( void ) {
Clear();
}
ID_INLINE void idDict::SetGranularity( int granularity ) {
args.SetGranularity( granularity );
argHash.SetGranularity( granularity );
}
ID_INLINE void idDict::SetHashSize( int hashSize ) {
if ( args.Num() == 0 ) {
argHash.Clear( hashSize, 16 );
}
}
ID_INLINE bool idDict::SetFloat( int index, float val ) {
return Set( index, va( "%f", val ) );
}
ID_INLINE bool idDict::SetInt( int index, int val ) {
return Set( index, va( "%i", val ) );
}
ID_INLINE bool idDict::SetBool( int index, bool val ) {
return Set( index, val ? "1" : "0" );
}
ID_INLINE bool idDict::SetVector( int index, const idVec3 &val ) {
return Set( index, val.ToString() );
}
ID_INLINE bool idDict::SetVec4( int index, const idVec4 &val ) {
return Set( index, val.ToString() );
}
ID_INLINE bool idDict::SetVec2( int index, const idVec2 &val ) {
return Set( index, val.ToString() );
}
ID_INLINE bool idDict::SetAngles( int index, const idAngles &val ) {
return Set( index, val.ToString() );
}
ID_INLINE bool idDict::SetMatrix( int index, const idMat3 &val ) {
return Set( index, val.ToString( 6 ) );
}
ID_INLINE bool idDict::SetFloat( const char *key, float val ) {
return Set( key, va( "%f", val ) );
}
ID_INLINE bool idDict::SetInt( const char *key, int val ) {
return Set( key, va( "%i", val ) );
}
ID_INLINE bool idDict::SetBool( const char *key, bool val ) {
return Set( key, val ? "1" : "0" );
}
ID_INLINE bool idDict::SetVector( const char *key, const idVec3 &val ) {
return Set( key, val.ToString() );
}
ID_INLINE bool idDict::SetVec4( const char *key, const idVec4 &val ) {
return Set( key, val.ToString() );
}
ID_INLINE bool idDict::SetVec2( const char *key, const idVec2 &val ) {
return Set( key, val.ToString() );
}
ID_INLINE bool idDict::SetAngles( const char *key, const idAngles &val ) {
return Set( key, val.ToString() );
}
ID_INLINE bool idDict::SetMatrix( const char *key, const idMat3 &val ) {
return Set( key, val.ToString( 6 ) );
}
ID_INLINE bool idDict::GetString( const char *key, const char *defaultString, const char **out ) const {
const idKeyValue *kv = FindKey( key );
if ( kv ) {
*out = kv->GetValue();
return true;
}
*out = defaultString;
return false;
}
ID_INLINE bool idDict::GetString( const char *key, const char *defaultString, idStr &out ) const {
const idKeyValue *kv = FindKey( key );
if ( kv ) {
out = kv->GetValue();
return true;
}
out = defaultString;
return false;
}
ID_INLINE const char *idDict::GetString( const char *key, const char *defaultString ) const {
const idKeyValue *kv = FindKey( key );
if ( kv ) {
return kv->GetValue();
}
return defaultString;
}
ID_INLINE float idDict::GetFloat( const char *key, const char *defaultString ) const {
return static_cast< float >( atof( GetString( key, defaultString ) ) );
}
ID_INLINE int idDict::GetInt( const char *key, const char *defaultString ) const {
return atoi( GetString( key, defaultString ) );
}
ID_INLINE bool idDict::GetBool( const char *key, const char *defaultString ) const {
return ( atoi( GetString( key, defaultString ) ) != 0 );
}
ID_INLINE idVec3 idDict::GetVector( const char *key, const char *defaultString ) const {
idVec3 out;
GetVector( key, defaultString, out );
return out;
}
ID_INLINE idVec2 idDict::GetVec2( const char *key, const char *defaultString ) const {
idVec2 out;
GetVec2( key, defaultString, out );
return out;
}
ID_INLINE idVec4 idDict::GetVec4( const char *key, const char *defaultString ) const {
idVec4 out;
GetVec4( key, defaultString, out );
return out;
}
ID_INLINE idAngles idDict::GetAngles( const char *key, const char *defaultString ) const {
idAngles out;
GetAngles( key, defaultString, out );
return out;
}
ID_INLINE idMat3 idDict::GetMatrix( const char *key, const char *defaultString ) const {
idMat3 out;
GetMatrix( key, defaultString, out );
return out;
}
ID_INLINE int idDict::GetNumKeyVals( void ) const {
return args.Num();
}
ID_INLINE const idKeyValue *idDict::GetKeyVal( int index ) const {
if ( index >= 0 && index < args.Num() ) {
return &args[ index ];
}
return NULL;
}
ID_INLINE void idDict::Swap( idDict& rhs ) {
args.Swap( rhs.args );
argHash.Swap( rhs.argHash );
}
#endif /* !__DICT_H__ */