2010-07-22 01:46:14 -05:00
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
# ifndef KEYVALUES_H
# define KEYVALUES_H
# ifdef _WIN32
# pragma once
# endif
# ifndef NULL
# ifdef __cplusplus
# define NULL 0
# else
# define NULL ((void *)0)
# endif
# endif
# include "utlvector.h"
2012-05-21 02:49:35 -05:00
# include "Color.h"
2010-07-22 01:46:14 -05:00
# include "exprevaluator.h"
2015-10-08 12:54:18 -04:00
# include <vstdlib/IKeyValuesSystem.h>
2010-07-22 01:46:14 -05:00
2022-09-04 12:40:16 -04:00
class IFileSystem ;
2010-07-22 01:46:14 -05:00
class CUtlBuffer ;
class Color ;
class KeyValues ;
class IKeyValuesDumpContext ;
2022-09-04 12:40:16 -04:00
class IKeyValuesErrorSpew ;
2023-09-17 22:23:40 +08:00
typedef void * FileHandle_t ;
2010-07-22 01:46:14 -05:00
// single byte identifies a xbox kv file in binary format
// strings are pooled from a searchpath/zip mounted symbol table
# define KV_BINARY_POOLED_FORMAT 0xAA
# define FOR_EACH_SUBKEY( kvRoot, kvSubKey ) \
for ( KeyValues * kvSubKey = kvRoot - > GetFirstSubKey ( ) ; kvSubKey ! = NULL ; kvSubKey = kvSubKey - > GetNextKey ( ) )
# define FOR_EACH_TRUE_SUBKEY( kvRoot, kvSubKey ) \
for ( KeyValues * kvSubKey = kvRoot - > GetFirstTrueSubKey ( ) ; kvSubKey ! = NULL ; kvSubKey = kvSubKey - > GetNextTrueSubKey ( ) )
# define FOR_EACH_VALUE( kvRoot, kvValue ) \
for ( KeyValues * kvValue = kvRoot - > GetFirstValue ( ) ; kvValue ! = NULL ; kvValue = kvValue - > GetNextValue ( ) )
2023-09-17 22:23:40 +08:00
DECLARE_POINTER_HANDLE ( HTemporaryKeyValueAllocationScope ) ;
class CTemporaryKeyValues
{
CTemporaryKeyValues ( ) : m_pKeyValues ( nullptr ) , m_hScope ( ) { }
~ CTemporaryKeyValues ( )
{
// GAMMACASE: TODO: Complete with actual KeyValuesSystem call once it's reversed too.
#if 0
KeyValuesSystem ( ) - > ReleaseTemporaryAllocationScope ( m_hScope ) ;
# endif
}
private :
KeyValues * m_pKeyValues ;
HTemporaryKeyValueAllocationScope m_hScope ;
} ;
class CKeyValues_Data
{
public :
// Data type
enum types_t
{
TYPE_NONE = 0 ,
TYPE_STRING ,
TYPE_INT ,
TYPE_FLOAT ,
TYPE_PTR ,
TYPE_WSTRING ,
TYPE_COLOR ,
TYPE_UINT64 ,
TYPE_COMPILED_INT_BYTE , // hack to collapse 1 byte ints in the compiled format
TYPE_COMPILED_INT_0 , // hack to collapse 0 in the compiled format
TYPE_COMPILED_INT_1 , // hack to collapse 1 in the compiled format
TYPE_NUMTYPES ,
} ;
private :
IKeyValuesSystem * KVSystem ( ) const ;
Color ResolveColorValue ( ) const ;
float ResolveFloatValue ( ) const ;
int ResolveIntValue ( ) const ;
uint64 ResolveUint64Value ( ) const ;
const char * ResolveStringValue ( ) const ;
const wchar_t * ResolveWStringValue ( ) const ;
KeyValues * ResolveSubKeyValue ( ) const ;
void Internal_ClearAll ( ) ;
void Internal_ClearData ( ) ;
void Internal_CopyData ( const CKeyValues_Data & kv ) ;
void Internal_CopyName ( const CKeyValues_Data & kv ) ;
bool Internal_IsEqual ( CKeyValues_Data * pOther ) ;
const char * Internal_GetName ( ) const ;
KeyValues * Internal_GetSubKey ( ) const ;
void Internal_SetSubKey ( KeyValues * subkey ) ;
HKeySymbol Internal_GetNameSymbol ( ) const ;
HKeySymbol Internal_GetNameSymbolCaseSensitive ( ) const ;
void Internal_SetName ( char const * szName ) ;
void Internal_SetNameFrom ( CKeyValues_Data const & pOther ) ;
Color Internal_GetColor ( Color defaultClr ) const ;
float Internal_GetFloat ( ) const ;
int Internal_GetInt ( ) const ;
uint64 Internal_GetUint64 ( ) const ;
char const * Internal_GetString ( const char * defaultValue , char * szBuf , size_t maxlen ) ;
const wchar_t * Internal_GetWString ( const wchar_t * defaultValue , wchar_t * szBuf , size_t maxlen ) ;
void * Internal_GetPtr ( ) const ;
void Internal_SetColor ( Color value ) ;
void Internal_SetFloat ( float value ) ;
void Internal_SetInt ( int value ) ;
void Internal_SetUint64 ( uint64 value ) ;
void Internal_SetString ( const char * value ) ;
void Internal_SetWString ( const wchar_t * value ) ;
void Internal_SetPtr ( void * value ) ;
void Internal_SetFromString ( types_t type , const char * value ) ;
bool Internal_HasEscapeSequences ( ) const ;
void Internal_SetHasEscapeSequences ( bool state ) ;
union
{
int m_iValue ;
float m_flValue ;
void * m_pValue ;
unsigned char m_Color [ 4 ] ;
uintp m_uValue ;
const char * m_sValue ;
const wchar_t * m_wsValue ;
KeyValues * m_pSub ;
} ;
void * m_pUnk ;
uint32 m_iKeyNameCaseSensitive : 24 ;
uint32 m_iDataType : 3 ;
uint32 m_bHasEscapeSequences : 1 ;
uint32 m_bAllocatedExternalMemory : 1 ;
uint32 m_bKeySymbolCaseSensitiveMatchesCaseInsensitive : 1 ;
uint32 m_bStoredSubKey : 1 ;
} ;
2010-07-22 01:46:14 -05:00
//-----------------------------------------------------------------------------
// Purpose: Simple recursive data access class
// Used in vgui for message parameters and resource files
// Destructor deletes all child KeyValues nodes
// Data is stored in key (string names) - (string/int/float)value pairs called nodes.
//
// About KeyValues Text File Format:
// It has 3 control characters '{', '}' and '"'. Names and values may be quoted or
// not. The quote '"' charater must not be used within name or values, only for
// quoting whole tokens. You may use escape sequences wile parsing and add within a
// quoted token a \" to add quotes within your name or token. When using Escape
// Sequence the parser must now that by setting KeyValues::UsesEscapeSequences( true ),
// which it's off by default. Non-quoted tokens ends with a whitespace, '{', '}' and '"'.
// So you may use '{' and '}' within quoted tokens, but not for non-quoted tokens.
// An open bracket '{' after a key name indicates a list of subkeys which is finished
// with a closing bracket '}'. Subkeys use the same definitions recursively.
// Whitespaces are space, return, newline and tabulator. Allowed Escape sequences
// are \n, \t, \\, \n and \". The number character '#' is used for macro purposes
// (eg #include), don't use it as first charater in key names.
//-----------------------------------------------------------------------------
2023-09-17 22:23:40 +08:00
# pragma pack(push, 1)
class KeyValues : public CKeyValues_Data
2010-07-22 01:46:14 -05:00
{
public :
//
// AutoDelete class to automatically free the keyvalues.
// Simply construct it with the keyvalues you allocated and it will free them when falls out of scope.
// When you decide that keyvalues shouldn't be deleted call Assign(NULL) on it.
// If you constructed AutoDelete(NULL) you can later assign the keyvalues to be deleted with Assign(pKeyValues).
//
class AutoDelete
{
public :
explicit inline AutoDelete ( KeyValues * pKeyValues ) : m_pKeyValues ( pKeyValues ) { }
explicit inline AutoDelete ( const char * pchKVName ) : m_pKeyValues ( new KeyValues ( pchKVName ) ) { }
2023-09-17 22:23:40 +08:00
inline ~ AutoDelete ( void ) { if ( m_pKeyValues ) delete m_pKeyValues ; }
2010-07-22 01:46:14 -05:00
inline void Assign ( KeyValues * pKeyValues ) { m_pKeyValues = pKeyValues ; }
2023-09-17 22:23:40 +08:00
KeyValues * operator - > ( ) { return m_pKeyValues ; }
operator KeyValues * ( ) { return m_pKeyValues ; }
2010-07-22 01:46:14 -05:00
private :
AutoDelete ( AutoDelete const & x ) ; // forbid
2023-09-17 22:23:40 +08:00
AutoDelete & operator = ( AutoDelete const & x ) ; // forbid
2010-07-22 01:46:14 -05:00
protected :
KeyValues * m_pKeyValues ;
} ;
//
// AutoDeleteInline is useful when you want to hold your keyvalues object inside
// and delete it right after using.
// You can also pass temporary KeyValues object as an argument to a function by wrapping it into KeyValues::AutoDeleteInline
// instance: call_my_function( KeyValues::AutoDeleteInline( new KeyValues( "test" ) ) )
//
class AutoDeleteInline : public AutoDelete
{
public :
explicit inline AutoDeleteInline ( KeyValues * pKeyValues ) : AutoDelete ( pKeyValues ) { }
inline operator KeyValues * ( ) const { return m_pKeyValues ; }
2023-09-17 22:23:40 +08:00
inline KeyValues * Get ( ) const { return m_pKeyValues ; }
2010-07-22 01:46:14 -05:00
} ;
// Quick setup constructors
2023-09-17 22:23:40 +08:00
KeyValues ( const char * setName , IKeyValuesSystem * kvsystem = NULL , bool unkState = false ) ;
2010-07-22 01:46:14 -05:00
KeyValues ( const char * setName , const char * firstKey , const char * firstValue ) ;
KeyValues ( const char * setName , const char * firstKey , const wchar_t * firstValue ) ;
KeyValues ( const char * setName , const char * firstKey , int firstValue ) ;
KeyValues ( const char * setName , const char * firstKey , const char * firstValue , const char * secondKey , const char * secondValue ) ;
KeyValues ( const char * setName , const char * firstKey , int firstValue , const char * secondKey , int secondValue ) ;
2023-09-17 22:23:40 +08:00
~ KeyValues ( ) ;
2010-07-22 01:46:14 -05:00
// Section name
const char * GetName ( ) const ;
2023-09-17 22:23:40 +08:00
void SetName ( const char * setName ) ;
2010-07-22 01:46:14 -05:00
// gets the name as a unique int
2015-10-08 12:54:18 -04:00
HKeySymbol GetNameSymbol ( ) const ;
HKeySymbol GetNameSymbolCaseSensitive ( ) const ;
2010-07-22 01:46:14 -05:00
// File access. Set UsesEscapeSequences true, if resource file/buffer uses Escape Sequences (eg \n, \t)
2023-09-17 22:23:40 +08:00
void UsesEscapeSequences ( bool state ) ; // default false
bool LoadFromFile ( IFileSystem * filesystem , const char * resourceName , const char * pathID = NULL , GetSymbolProc_t pfnEvaluateSymbolProc = NULL , void * pUnk1 = NULL , const char * pUnk2 = NULL ) ;
bool SaveToFile ( IFileSystem * filesystem , const char * resourceName , const char * pathID = NULL , bool bAllowEmptyString = false ) ;
2010-07-22 01:46:14 -05:00
// Read from a buffer... Note that the buffer must be null terminated
2023-09-17 22:23:40 +08:00
bool LoadFromBuffer ( char const * resourceName , const char * pBuffer , IFileSystem * pFileSystem = NULL , const char * pPathID = NULL , GetSymbolProc_t pfnEvaluateSymbolProc = NULL , IKeyValuesErrorSpew * pErrorSpew = NULL , void * pUnk1 = NULL , const char * pUnk2 = NULL ) ;
2010-07-22 01:46:14 -05:00
// Read from a utlbuffer...
2023-09-17 22:23:40 +08:00
bool LoadFromBuffer ( char const * resourceName , CUtlBuffer & buf , IFileSystem * pFileSystem = NULL , const char * pPathID = NULL , GetSymbolProc_t pfnEvaluateSymbolProc = NULL , IKeyValuesErrorSpew * pErrorSpew = NULL , void * pUnk1 = NULL , const char * pUnk2 = NULL ) ;
CTemporaryKeyValues * LoadTemporaryFromBuffer ( bool , char const * resourceName , const char * pBuffer , IFileSystem * pFileSystem = NULL , const char * pPathID = NULL , GetSymbolProc_t pfnEvaluateSymbolProc = NULL , IKeyValuesErrorSpew * pErrorSpew = NULL , void * pUnk1 = NULL , const char * pUnk2 = NULL ) ;
CTemporaryKeyValues * LoadTemporaryFromBuffer ( bool , char const * resourceName , CUtlBuffer & buf , IFileSystem * pFileSystem = NULL , const char * pPathID = NULL , GetSymbolProc_t pfnEvaluateSymbolProc = NULL , void * pUnk1 = NULL , const char * pUnk2 = NULL ) ;
CTemporaryKeyValues * LoadTemporaryFromFile ( bool , IFileSystem * filesystem , const char * resourceName , const char * pathID = NULL , GetSymbolProc_t pfnEvaluateSymbolProc = NULL , void * pUnk1 = NULL , const char * pUnk2 = NULL ) ;
2010-07-22 01:46:14 -05:00
// Find a keyValue, create it if it is not found.
// Set bCreate to true to create the key if it doesn't already exist (which ensures a valid pointer will be returned)
2023-09-17 22:23:40 +08:00
KeyValues * FindKey ( const char * keyName , bool bCreate ) ;
KeyValues * FindKey ( const char * keyName ) const ;
KeyValues * FindKey ( HKeySymbol keySymbol ) const ;
KeyValues * FindKeyAndParent ( const char * keyName , KeyValues * * pParent , bool ) ;
bool FindAndDeleteSubKey ( const char * keyName ) ;
2010-07-22 01:46:14 -05:00
KeyValues * CreateNewKey ( ) ; // creates a new key, with an autogenerated name. name is guaranteed to be an integer, of value 1 higher than the highest other integer key name
2023-09-17 22:23:40 +08:00
KeyValues * CreatePeerKey ( const char * keyName ) ;
KeyValues * AddKey ( const char * keyName ) ;
2010-07-22 01:46:14 -05:00
void AddSubKey ( KeyValues * pSubkey ) ; // Adds a subkey. Make sure the subkey isn't a child of some other keyvalues
2023-09-17 22:23:40 +08:00
void AddSubkeyUsingKnownLastChild ( KeyValues * pSubkey , KeyValues * pChild ) ;
KeyValues * CreateKeyUsingKnownLastChild ( const char * keyName , KeyValues * pChild ) ;
void RemoveSubKey ( KeyValues * subKey , bool , bool ) ; // removes a subkey from the list, DOES NOT DELETE IT
void RemoveOptionalSubKey ( KeyValues * subKey ) ;
2010-07-22 01:46:14 -05:00
void InsertSubKey ( int nIndex , KeyValues * pSubKey ) ; // Inserts the given sub-key before the Nth child location
bool ContainsSubKey ( KeyValues * pSubKey ) ; // Returns true if this key values contains the specified sub key, false otherwise.
void SwapSubKey ( KeyValues * pExistingSubKey , KeyValues * pNewSubKey ) ; // Swaps an existing subkey for a new one, DOES NOT DELETE THE OLD ONE but takes ownership of the new one
void ElideSubKey ( KeyValues * pSubKey ) ; // Removes a subkey but inserts all of its children in its place, in-order (flattens a tree, like firing a manager!)
2023-09-17 22:23:40 +08:00
2010-07-22 01:46:14 -05:00
// Key iteration.
//
// NOTE: GetFirstSubKey/GetNextKey will iterate keys AND values. Use the functions
// below if you want to iterate over just the keys or just the values.
//
2023-09-17 22:23:40 +08:00
KeyValues * GetFirstSubKey ( ) const ; // returns the first subkey in the list
KeyValues * FindLastSubKey ( ) const ;
KeyValues * GetNextKey ( ) const ; // returns the next subkey
void SetNextKey ( KeyValues * pDat ) ;
2010-07-22 01:46:14 -05:00
//
// These functions can be used to treat it like a true key/values tree instead of
// confusing values with keys.
//
// So if you wanted to iterate all subkeys, then all values, it would look like this:
// for ( KeyValues *pKey = pRoot->GetFirstTrueSubKey(); pKey; pKey = pKey->GetNextTrueSubKey() )
// {
// Msg( "Key name: %s\n", pKey->GetName() );
// }
// for ( KeyValues *pValue = pRoot->GetFirstValue(); pKey; pKey = pKey->GetNextValue() )
// {
// Msg( "Int value: %d\n", pValue->GetInt() ); // Assuming pValue->GetDataType() == TYPE_INT...
// }
2023-09-17 22:23:40 +08:00
KeyValues * GetFirstTrueSubKey ( ) const ;
KeyValues * GetNextTrueSubKey ( ) const ;
2010-07-22 01:46:14 -05:00
2023-09-17 22:23:40 +08:00
KeyValues * GetFirstValue ( ) const ; // When you get a value back, you can use GetX and pass in NULL to get the value.
KeyValues * GetNextValue ( ) const ;
2010-07-22 01:46:14 -05:00
// Data access
2023-09-17 22:23:40 +08:00
int GetInt ( const char * keyName = NULL , int defaultValue = 0 ) const ;
uint64 GetUint64 ( const char * keyName = NULL , uint64 defaultValue = 0 ) const ;
float GetFloat ( const char * keyName = NULL , float defaultValue = 0.0f ) const ;
const char * GetString ( const char * keyName , const char * defaultValue = " " , char * pszOut = NULL , size_t maxlen = 0 ) ;
const wchar_t * GetWString ( const char * keyName = NULL , const wchar_t * defaultValue = L " " , wchar_t * pszOut = NULL , size_t maxlen = 0 ) ;
void * GetPtr ( const char * keyName = NULL , void * defaultValue = ( void * ) 0 ) const ;
Color GetColor ( const char * keyName = NULL , const Color & defaultColor = Color ( 0 , 0 , 0 , 0 ) ) const ;
bool GetBool ( const char * keyName = NULL , bool defaultValue = false ) const { return GetInt ( keyName , defaultValue ? 1 : 0 ) ? true : false ; }
bool IsEmpty ( const char * keyName = NULL ) const ;
2010-07-22 01:46:14 -05:00
// Data access
2023-09-17 22:23:40 +08:00
int GetInt ( HKeySymbol keySymbol , int defaultValue = 0 ) const ;
uint64 GetUint64 ( HKeySymbol keySymbol , uint64 defaultValue = 0 ) const ;
float GetFloat ( HKeySymbol keySymbol , float defaultValue = 0.0f ) const ;
const char * GetString ( HKeySymbol keySymbol , const char * defaultValue = " " , char * pszOut = NULL , size_t maxlen = 0 ) ;
const wchar_t * GetWString ( HKeySymbol keySymbol , const wchar_t * defaultValue = L " " , wchar_t * pszOut = NULL , size_t maxlen = 0 ) ;
void * GetPtr ( HKeySymbol keySymbol , void * defaultValue = ( void * ) 0 ) const ;
Color GetColor ( HKeySymbol keySymbol , const Color & defaultColor = Color ( 0 , 0 , 0 , 0 ) ) const ;
bool GetBool ( HKeySymbol keySymbol , bool defaultValue = false ) const { return GetInt ( keySymbol , defaultValue ? 1 : 0 ) ? true : false ; }
bool IsEmpty ( HKeySymbol keySymbol ) const ;
2010-07-22 01:46:14 -05:00
// Key writing
void SetWString ( const char * keyName , const wchar_t * value ) ;
void SetString ( const char * keyName , const char * value ) ;
void SetInt ( const char * keyName , int value ) ;
void SetUint64 ( const char * keyName , uint64 value ) ;
void SetFloat ( const char * keyName , float value ) ;
void SetPtr ( const char * keyName , void * value ) ;
2023-09-17 22:23:40 +08:00
void SetColor ( const char * keyName , Color value ) ;
2010-07-22 01:46:14 -05:00
void SetBool ( const char * keyName , bool value ) { SetInt ( keyName , value ? 1 : 0 ) ; }
2023-09-17 22:23:40 +08:00
// Adds key value pair
void AddString ( const char * keyName , const char * value ) ;
void AddInt ( const char * keyName , int value ) ;
void AddUint64 ( const char * keyName , uint64 value ) ;
void AddFloat ( const char * keyName , float value ) ;
void AddPtr ( const char * keyName , void * value ) ;
2010-07-22 01:46:14 -05:00
// Memory allocation (optimized)
2023-09-17 22:23:40 +08:00
void * operator new ( size_t iAllocSize ) ;
void * operator new ( size_t iAllocSize , int nBlockUse , const char * pFileName , int nLine ) ;
void operator delete ( void * pMem ) ;
void operator delete ( void * pMem , int nBlockUse , const char * pFileName , int nLine ) ;
2010-07-22 01:46:14 -05:00
2023-09-17 22:23:40 +08:00
KeyValues & operator = ( KeyValues & src ) ;
2010-07-22 01:46:14 -05:00
2023-09-17 22:23:40 +08:00
void RecursiveSaveToFile ( CUtlBuffer & buf , int indentLevel , bool bSortKeys = false , bool bAllowEmptyString = false ) ;
void RecursiveSaveToLocalizationFile ( IFileSystem * filesystem , void * buf , int indentLevel , bool bAllowEmptyString = false ) ;
2010-07-22 01:46:14 -05:00
bool WriteAsBinary ( CUtlBuffer & buffer ) ;
2023-09-17 22:23:40 +08:00
bool WriteAsBinaryFiltered ( CUtlBuffer & buffer ) ;
2010-07-22 01:46:14 -05:00
bool ReadAsBinary ( CUtlBuffer & buffer ) ;
2023-09-17 22:23:40 +08:00
bool ReadAsBinaryFiltered ( CUtlBuffer & buffer ) ;
CTemporaryKeyValues * ReadTemporaryAsBinary ( bool , CUtlBuffer & buffer ) ;
2010-07-22 01:46:14 -05:00
// Allocate & create a new copy of the keys
KeyValues * MakeCopy ( void ) const ;
// Make a new copy of all subkeys, add them all to the passed-in keyvalues
void CopySubkeys ( KeyValues * pParent ) const ;
// Clear out all subkeys, and the current value
void Clear ( void ) ;
2023-09-17 22:23:40 +08:00
bool IsEqual ( KeyValues * pOther ) ;
int Count ( void ) const ;
2010-07-22 01:46:14 -05:00
2023-09-17 22:23:40 +08:00
KeyValues * Element ( int nIndex ) const ;
CKeyValues_Data : : types_t GetDataType ( const char * keyName = NULL ) ;
2010-07-22 01:46:14 -05:00
// unpack a key values list into a structure
void UnpackIntoStructure ( struct KeyValuesUnpackStructure const * pUnpackTable , void * pDest ) ;
// Process conditional keys for widescreen support.
bool ProcessResolutionKeys ( const char * pResString ) ;
// Dump keyvalues recursively into a dump context
bool Dump ( IKeyValuesDumpContext * pDump , int nIndentLevel = 0 ) ;
// Merge operations describing how two keyvalues can be combined
enum MergeKeyValuesOp_t
{
MERGE_KV_ALL ,
MERGE_KV_UPDATE , // update values are copied into storage, adding new keys to storage or updating existing ones
MERGE_KV_DELETE , // update values specify keys that get deleted from storage
MERGE_KV_BORROW , // update values only update existing keys in storage, keys in update that do not exist in storage are discarded
2023-09-17 22:23:40 +08:00
MERGE_KV_ADD_ONLY
2010-07-22 01:46:14 -05:00
} ;
2023-09-17 22:23:40 +08:00
void MergeFrom ( const KeyValues * kvMerge , MergeKeyValuesOp_t eOp = MERGE_KV_ALL ) ;
CTemporaryKeyValues * MergeFromTemporary ( const KeyValues * kvMerge , MergeKeyValuesOp_t eOp = MERGE_KV_ALL ) const ;
2010-07-22 01:46:14 -05:00
2023-09-17 22:23:40 +08:00
// Assign keyvalues from a string
static KeyValues * FromString ( char const * szName , char const * szStringVal , char const * * ppEndOfParse = NULL ) ;
2010-07-22 01:46:14 -05:00
2023-09-17 22:23:40 +08:00
private :
KeyValues ( KeyValues & ) ; // prevent copy constructor being used
2010-07-22 01:46:14 -05:00
KeyValues * m_pPeer ; // pointer to next key in list
} ;
2023-09-17 22:23:40 +08:00
# pragma pack(pop)
2010-07-22 01:46:14 -05:00
typedef KeyValues : : AutoDelete KeyValuesAD ;
enum KeyValuesUnpackDestinationTypes_t
{
UNPACK_TYPE_FLOAT , // dest is a float
UNPACK_TYPE_VECTOR , // dest is a Vector
UNPACK_TYPE_VECTOR_COLOR , // dest is a vector, src is a color
UNPACK_TYPE_STRING , // dest is a char *. unpacker will allocate.
UNPACK_TYPE_INT , // dest is an int
UNPACK_TYPE_FOUR_FLOATS , // dest is an array of 4 floats. source is a string like "1 2 3 4"
UNPACK_TYPE_TWO_FLOATS , // dest is an array of 2 floats. source is a string like "1 2"
} ;
# define UNPACK_FIXED( kname, kdefault, dtype, ofs ) { kname, kdefault, dtype, ofs, 0 }
# define UNPACK_VARIABLE( kname, kdefault, dtype, ofs, sz ) { kname, kdefault, dtype, ofs, sz }
# define UNPACK_END_MARKER { NULL, NULL, UNPACK_TYPE_FLOAT, 0 }
struct KeyValuesUnpackStructure
{
char const * m_pKeyName ; // null to terminate tbl
char const * m_pKeyDefault ; // null ok
KeyValuesUnpackDestinationTypes_t m_eDataType ; // UNPACK_TYPE_INT, ..
size_t m_nFieldOffset ; // use offsetof to set
size_t m_nFieldSize ; // for strings or other variable length
} ;
//-----------------------------------------------------------------------------
// inline methods
//-----------------------------------------------------------------------------
2023-09-17 22:23:40 +08:00
inline int KeyValues : : GetInt ( HKeySymbol keySymbol , int defaultValue ) const
2010-07-22 01:46:14 -05:00
{
KeyValues * dat = FindKey ( keySymbol ) ;
return dat ? dat - > GetInt ( ( const char * ) NULL , defaultValue ) : defaultValue ;
}
2023-09-17 22:23:40 +08:00
inline uint64 KeyValues : : GetUint64 ( HKeySymbol keySymbol , uint64 defaultValue ) const
2010-07-22 01:46:14 -05:00
{
KeyValues * dat = FindKey ( keySymbol ) ;
return dat ? dat - > GetUint64 ( ( const char * ) NULL , defaultValue ) : defaultValue ;
}
2023-09-17 22:23:40 +08:00
inline float KeyValues : : GetFloat ( HKeySymbol keySymbol , float defaultValue ) const
2010-07-22 01:46:14 -05:00
{
KeyValues * dat = FindKey ( keySymbol ) ;
return dat ? dat - > GetFloat ( ( const char * ) NULL , defaultValue ) : defaultValue ;
}
2023-09-17 22:23:40 +08:00
inline const char * KeyValues : : GetString ( HKeySymbol keySymbol , const char * defaultValue , char * pszOut , size_t maxlen )
2010-07-22 01:46:14 -05:00
{
KeyValues * dat = FindKey ( keySymbol ) ;
2023-09-17 22:23:40 +08:00
return dat ? dat - > GetString ( ( const char * ) NULL , defaultValue , pszOut , maxlen ) : defaultValue ;
2010-07-22 01:46:14 -05:00
}
2023-09-17 22:23:40 +08:00
inline const wchar_t * KeyValues : : GetWString ( HKeySymbol keySymbol , const wchar_t * defaultValue , wchar_t * pszOut , size_t maxlen )
2010-07-22 01:46:14 -05:00
{
KeyValues * dat = FindKey ( keySymbol ) ;
2023-09-17 22:23:40 +08:00
return dat ? dat - > GetWString ( ( const char * ) NULL , defaultValue , pszOut , maxlen ) : defaultValue ;
2010-07-22 01:46:14 -05:00
}
2023-09-17 22:23:40 +08:00
inline void * KeyValues : : GetPtr ( HKeySymbol keySymbol , void * defaultValue ) const
2010-07-22 01:46:14 -05:00
{
KeyValues * dat = FindKey ( keySymbol ) ;
return dat ? dat - > GetPtr ( ( const char * ) NULL , defaultValue ) : defaultValue ;
}
2023-09-17 22:23:40 +08:00
inline Color KeyValues : : GetColor ( HKeySymbol keySymbol , const Color & defaultColor ) const
2010-07-22 01:46:14 -05:00
{
KeyValues * dat = FindKey ( keySymbol ) ;
2023-09-17 22:23:40 +08:00
return dat ? dat - > GetColor ( ( const char * ) NULL , defaultColor ) : defaultColor ;
2010-07-22 01:46:14 -05:00
}
2023-09-17 22:23:40 +08:00
inline bool KeyValues : : IsEmpty ( HKeySymbol keySymbol ) const
2010-07-22 01:46:14 -05:00
{
KeyValues * dat = FindKey ( keySymbol ) ;
2023-09-17 22:23:40 +08:00
return dat ? dat - > IsEmpty ( ) : true ;
2010-07-22 01:46:14 -05:00
}
//
// KeyValuesDumpContext and generic implementations
//
class IKeyValuesDumpContext
{
public :
virtual bool KvBeginKey ( KeyValues * pKey , int nIndentLevel ) = 0 ;
virtual bool KvWriteValue ( KeyValues * pValue , int nIndentLevel ) = 0 ;
virtual bool KvEndKey ( KeyValues * pKey , int nIndentLevel ) = 0 ;
} ;
class IKeyValuesDumpContextAsText : public IKeyValuesDumpContext
{
public :
virtual bool KvBeginKey ( KeyValues * pKey , int nIndentLevel ) ;
virtual bool KvWriteValue ( KeyValues * pValue , int nIndentLevel ) ;
virtual bool KvEndKey ( KeyValues * pKey , int nIndentLevel ) ;
public :
virtual bool KvWriteIndent ( int nIndentLevel ) ;
virtual bool KvWriteText ( char const * szText ) = 0 ;
} ;
class CKeyValuesDumpContextAsDevMsg : public IKeyValuesDumpContextAsText
{
public :
// Overrides developer level to dump in DevMsg, zero to dump as Msg
CKeyValuesDumpContextAsDevMsg ( int nDeveloperLevel = 1 ) : m_nDeveloperLevel ( nDeveloperLevel ) { }
public :
virtual bool KvBeginKey ( KeyValues * pKey , int nIndentLevel ) ;
virtual bool KvWriteText ( char const * szText ) ;
protected :
int m_nDeveloperLevel ;
} ;
inline bool KeyValuesDumpAsDevMsg ( KeyValues * pKeyValues , int nIndentLevel = 0 , int nDeveloperLevel = 1 )
{
CKeyValuesDumpContextAsDevMsg ctx ( nDeveloperLevel ) ;
return pKeyValues - > Dump ( & ctx , nIndentLevel ) ;
}
2023-09-17 17:29:31 +03:00
# endif // KEYVALUES_H