diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /mdllib/mdllib_utils.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'mdllib/mdllib_utils.cpp')
| -rw-r--r-- | mdllib/mdllib_utils.cpp | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/mdllib/mdllib_utils.cpp b/mdllib/mdllib_utils.cpp new file mode 100644 index 0000000..77ec4fa --- /dev/null +++ b/mdllib/mdllib_utils.cpp @@ -0,0 +1,205 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + + +#include "mdllib_utils.h" + + +////////////////////////////////////////////////////////////////////////// +// +// CInsertionTracker implementation +// +////////////////////////////////////////////////////////////////////////// + + +void CInsertionTracker::InsertBytes( void *pos, int length ) +{ + if ( length <= 0 ) + return; + + Assert( m_map.InvalidIndex() == m_map.Find( ( byte * ) pos ) ); + m_map.InsertOrReplace( ( byte * ) pos, length ); +} + +int CInsertionTracker::GetNumBytesInserted() const +{ + int iInserted = 0; + + for ( Map::IndexType_t idx = m_map.FirstInorder(); + idx != m_map.InvalidIndex(); idx = m_map.NextInorder( idx ) ) + { + int numBytes = m_map.Element( idx ); + iInserted += numBytes; + } + + return iInserted; +} + +void CInsertionTracker::Finalize() +{ + // Iterate the map and find all the adjacent removal data blocks + // TODO: +} + +void CInsertionTracker::MemMove( void *ptrBase, int &length ) const +{ + int numBytesInsertReq = GetNumBytesInserted(); + byte *pbBlockEnd = BYTE_OFF_PTR( ptrBase, length ); + length += numBytesInsertReq; + + for ( Map::IndexType_t idx = m_map.LastInorder(); + idx != m_map.InvalidIndex(); idx = m_map.PrevInorder( idx ) ) + { + byte *ptr = m_map.Key( idx ); + int numBytes = m_map.Element( idx ); + + // Move [ptr, pbBlockEnd) ->> + numBytesInsertReq + memmove( BYTE_OFF_PTR( ptr, numBytesInsertReq ), ptr, BYTE_DIFF_PTR( ptr, pbBlockEnd ) ); + + // Inserted data + memset( BYTE_OFF_PTR( ptr, numBytesInsertReq - numBytes ), 0, numBytes ); + + numBytesInsertReq -= numBytes; + pbBlockEnd = ptr; + } +} + +int CInsertionTracker::ComputeOffset( void *ptrBase, int off ) const +{ + void *ptrNewBase = ComputePointer( ptrBase ); + void *ptrNewData = ComputePointer( BYTE_OFF_PTR( ptrBase, off ) ); + return BYTE_DIFF_PTR( ptrNewBase, ptrNewData ); +} + +void * CInsertionTracker::ComputePointer( void *ptrNothingInserted ) const +{ + int iInserted = 0; + + // Iterate the map and find all the data that would be inserted before the given pointer + for ( Map::IndexType_t idx = m_map.FirstInorder(); + idx != m_map.InvalidIndex(); idx = m_map.NextInorder( idx ) ) + { + if ( m_map.Key( idx ) < ptrNothingInserted ) + iInserted += m_map.Element( idx ); + else + break; + } + + return BYTE_OFF_PTR( ptrNothingInserted, iInserted ); +} + + + +////////////////////////////////////////////////////////////////////////// +// +// CRemoveTracker implementation +// +////////////////////////////////////////////////////////////////////////// + + +void CRemoveTracker::RemoveBytes( void *pos, int length ) +{ + if ( length <= 0 ) + return; + + // -- hint + if ( m_map.Count() ) + { + if ( m_hint.ptr < pos ) + { + if ( BYTE_OFF_PTR( m_hint.ptr, m_hint.len ) == pos ) + { + m_hint.len += length; + m_map.Element( m_hint.idx ) = m_hint.len; + return; + } + } + else if ( m_hint.ptr > pos ) + { + if ( BYTE_OFF_PTR( pos, length ) == m_hint.ptr ) + { + m_hint.len += length; + m_hint.ptr = BYTE_OFF_PTR( m_hint.ptr, - length ); + m_map.Key( m_hint.idx ) = m_hint.ptr; + m_map.Element( m_hint.idx ) = m_hint.len; + return; + } + } + } + // -- end hint + + // Insert new + Assert( m_map.InvalidIndex() == m_map.Find( ( byte * ) pos ) ); + Map::IndexType_t idx = m_map.InsertOrReplace( ( byte * ) pos, length ); + + // New hint + m_hint.idx = idx; + m_hint.ptr = ( byte * ) pos; + m_hint.len = length; +} + +int CRemoveTracker::GetNumBytesRemoved() const +{ + int iRemoved = 0; + + for ( Map::IndexType_t idx = m_map.FirstInorder(); + idx != m_map.InvalidIndex(); idx = m_map.NextInorder( idx ) ) + { + int numBytes = m_map.Element( idx ); + iRemoved += numBytes; + } + + return iRemoved; +} + +void CRemoveTracker::Finalize() +{ + // Iterate the map and find all the adjacent removal data blocks + // TODO: +} + +void CRemoveTracker::MemMove( void *ptrBase, int &length ) const +{ + int iRemoved = 0; + + for ( Map::IndexType_t idx = m_map.FirstInorder(); + idx != m_map.InvalidIndex(); idx = m_map.NextInorder( idx ) ) + { + byte *ptr = m_map.Key( idx ); + byte *ptrDest = BYTE_OFF_PTR( ptr, - iRemoved ); + int numBytes = m_map.Element( idx ); + memmove( ptrDest, BYTE_OFF_PTR( ptrDest, numBytes ), BYTE_DIFF_PTR( BYTE_OFF_PTR( ptr, numBytes ), BYTE_OFF_PTR( ptrBase, length ) ) ); + iRemoved += numBytes; + } + + length -= iRemoved; +} + +int CRemoveTracker::ComputeOffset( void *ptrBase, int off ) const +{ + void *ptrNewBase = ComputePointer( ptrBase ); + void *ptrNewData = ComputePointer( BYTE_OFF_PTR( ptrBase, off ) ); + return BYTE_DIFF_PTR( ptrNewBase, ptrNewData ); +} + +void * CRemoveTracker::ComputePointer( void *ptrNothingRemoved ) const +{ + int iRemoved = 0; + + // Iterate the map and find all the data that would be removed before the given pointer + for ( Map::IndexType_t idx = m_map.FirstInorder(); + idx != m_map.InvalidIndex(); idx = m_map.NextInorder( idx ) ) + { + if ( m_map.Key( idx ) < ptrNothingRemoved ) + iRemoved += m_map.Element( idx ); + else + break; + } + + return BYTE_OFF_PTR( ptrNothingRemoved, - iRemoved ); +} + + |