text: //====== Copyright (c) 1996-2005, Valve Corporation, All rights reserved. =======
  //
  // Purpose: 
  //
  //=============================================================================
  
  #ifndef KEYVALUESCOMPILER_H
  #define KEYVALUESCOMPILER_H
  #ifdef _WIN32
  #pragma once
  #endif
  
  #include "tier0/platform.h"
  #include "tier1/utlbuffer.h"
  #include "tier1/utlsymbol.h"
  #include "tier1/utldict.h"
  
  class KeyValues;
  
  #define COMPILED_KEYVALUES_ID	MAKEID( 'V', 'K', 'V', 'F' )
  
  #define COMPILED_KEYVALUES_VERSION	1
  
  struct KVHeader_t
  {
  	int			fileid;
  	int			version;
  	int			numStrings;
  };
  
  #pragma pack(1)
  struct KVFile_t
  {
  	KVFile_t() :
  		filename( 0 ),
  		firstElement( 0 ),
  		numElements( 0 )
  	{
  	}
  	short			filename;
  	short			firstElement;
  	short			numElements;
  };
  
  struct KVInfo_t
  {
  	KVInfo_t() :
  		key( 0 ),
  		value( 0 ),
  		parentIndex( -1 ),
  		issubtree( false )
  	{
  	}
  
  	inline void SetParent( int index )
  	{
  		Assert( index <= 32768 );
  		parentIndex = index;
  	}
  
  	inline short GetParent() const
  	{
  		return parentIndex;
  	}
  
  	inline void SetSubTree( bool state )
  	{
  		issubtree = state;
  	}
  
  	inline bool IsSubTree() const
  	{
  		return issubtree;
  	}
  
  	short		key;
  	short		value;
  
  private:
  
  	short		parentIndex;
  	bool		issubtree;
  };
  #pragma pack()
  
  //-----------------------------------------------------------------------------
  // Purpose: stringtable is a session global string table.
  //-----------------------------------------------------------------------------
  class CCompiledKeyValuesWriter
  {
  public:
  
  	CCompiledKeyValuesWriter()
  	{
  		m_StringTable.AddString( "" );
  	}
  
  	void AppendKeyValuesFile( char const *filename );
  	void WriteFile( char const *outfile );
  
  private:
  
  	void Describe( const KVFile_t& file );
  
  	void BuildKVData_R( KeyValues *kv, int parent );
  
  	void WriteStringTable( CUtlBuffer& buf );
  	void WriteData( CUtlBuffer& buf );
  	void WriteFiles( CUtlBuffer &buf );
  
  	CUtlVector< KVFile_t >		m_Files;
  	CUtlVector< KVInfo_t >		m_Data;
  
  	CUtlSymbolTable				m_StringTable;
  };
  
  
  class CRunTimeKeyValuesStringTable
  {
  public:
  
  	bool ReadStringTable( int numStrings, CUtlBuffer& buf );
  	
  	inline int Count() const
  	{
  		return m_Strings.Count();
  	}
  
  	inline char const *Lookup( short index )
  	{
  		return m_Strings[ index ];
  	}
  
  private:
  	CUtlVector< const char * >	m_Strings; 
  };
  
  class CCompiledKeyValuesReader
  {
  public:
  
  	CCompiledKeyValuesReader();
  	
  	bool		LoadFile( char const *filename );
  
  	KeyValues	*Instance( char const *kvfilename );
  	bool		InstanceInPlace( KeyValues& head, char const *kvfilename );
  	bool		LookupKeyValuesRootKeyName( char const *kvfilename, char *outbuf, size_t bufsize );
  
  	int			First() const;
  	int			Next( int i ) const;
  	int			InvalidIndex() const;
  
  	void		GetFileName( int index, char *buf, size_t bufsize );
  
  private:
  
  	struct FileInfo_t
  	{
  		FileInfo_t() : 
  			hFile( 0 ),
  			nFirstIndex( 0 ), 
  			nCount( 0 ) 
  		{
  		}
  		FileNameHandle_t	hFile;
  		short				nFirstIndex;
  		short				nCount;
  
  		static bool Less( const FileInfo_t& lhs, const FileInfo_t& rhs )
  		{
  			return lhs.hFile < rhs.hFile;
  		}
  	};
  
  	KeyValues *CreateFromData( const FileInfo_t& info );
  	bool CreateInPlaceFromData( KeyValues& head, const FileInfo_t& info );
  
  	// Now get the actual files
  	CUtlRBTree< FileInfo_t, unsigned short >	m_Dict;
  	CUtlVector< KVInfo_t >		m_Data;
  
  	CRunTimeKeyValuesStringTable		m_StringTable;
  
  	CUtlBuffer							m_LoadBuffer;
  };
  
  #endif // KEYVALUESCOMPILER_H
  