//========= Copyright c 1996-2008, Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //=============================================================================// #ifndef DATA_LINKER_H #define DATA_LINKER_H #include "datalinker_interface.h" #include #include #include #include "tier1/UtlStringMap.h" namespace DataLinker { enum LinkTargetEnum { kTargetResolved, kTargetUnresolved, kTargetNull }; struct LinkTargetDesc_t { LinkTargetEnum m_type; int m_resolvedOffset; LinkTargetDesc_t() { m_resolvedOffset = -1; m_type = kTargetUnresolved; } }; struct LinkSourceDesc_t { int m_targetId; // when this is 0, we use the embedded structure OffsetTypeEnum m_type; const char *m_pDescription; LinkTargetDesc_t m_defaultTarget; }; typedef std::map LinkSourceMap; typedef std::map LinkTargetMap; class Chunk { public: Chunk() {} Chunk( uint reserve, uint offset ); void Free(); uint GetAvailable()const { return m_capacity - m_size; } uint m_offset; uint m_size; uint m_capacity; uint m_recentSize; byte *m_data; }; ////////////////////////////////////////////////////////////////////////// // This writer uses malloc() to allocate memory for the binary data class Stream: public ILinkStream { public: Stream(); ~Stream(); void* WriteBytes( uint numBytes ); void EnsureAvailable( uint addCapacity ); void Link( LinkSource_t, LinkTarget_t, const char *szDescription ); void Align( uint nAlignment, int nOffset = 0 ); long Tell() { return m_size; } LinkSource_t WriteOffset( const char *szDescription ); LinkSource_t WriteOffset( LinkTarget_t linkTarget, const char *szDescription ); LinkSource_t WriteNullOffset( const char *szDescription ) { return WriteOffset( LinkTargetNull_t(), szDescription ); } LinkSource_t NewOffset( int *pOffset, const char *szDescription ); LinkSource_t LinkToHere( int *pOffset, const char *szDescription ); LinkSource_t Link( int32 *pOffset, LinkTarget_t linkTarget, const char *szDescription ); void Link( int32 *pOffset, const void *pTarget ); void Link( int16 *pOffset, const void *pTarget ); LinkTarget_t NewTarget(); // create new, unresolved target LinkTarget_t NewTarget( void *pWhere ); LinkTarget_t NewTargetHere(); // creates a target right here void SetTargetHere( LinkTarget_t ); // sets the given target to point to right here void SetTargetNull( LinkTarget_t ); // set this target to point to NULL // make the targets point to the same place //void Assign(LinkTarget_t assignee, LinkTarget_t assignor); bool Compile( void *pBuffer ); uint GetTotalSize()const { return m_size; } bool IsDeclared( LinkTarget_t linkTarget )const; bool IsSet( LinkTarget_t linkTarget )const; bool IsDefined( LinkSource_t linkSource )const; bool IsLinked( LinkSource_t linkSource )const; const char* WriteAndLinkString( Offset_t *pOffset, const char *pString ); long Tell()const { return m_size; } void Begin( const char *nName, uint flags = 0 ); void End(); void PrintStats(); void ClearStats(); protected: LinkSource_t NewLinkSource( int offsetOfOffset, OffsetTypeEnum type, int linkTargetId, const char *szDescription ); int GetOffsetTo( const void *ptr )const; void SetTarget( LinkTarget_t linkTarget, int offsetToTarget ); protected: std::vector m_data; struct StringTableElement_t { char *m_pString; int m_nOffset; StringTableElement_t(): m_pString( NULL ), m_nOffset( NULL ) {} }; CUtlStringMap m_stringTable; // each string offset uint m_size; // this is the currently used data int m_lastTarget; // the last id of LinkTarget uint m_alignBits; // the ( max alignment - 1 ) of the current block of data // LinkSource_t::m_offset -> ... LinkSourceMap m_mapSources; // LinkTargetMap m_mapTargets; struct BlockStats_t { BlockStats_t(): m_size( 0 ) {} long m_size; }; typedef std::mapBlockStatsMap; BlockStatsMap m_mapBlockStats; struct Block_t { std::string m_name; long m_tell; }; std::vector m_stackBlocks; }; } #endif