summaryrefslogtreecommitdiff
path: root/mdllib/mdllib_utils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mdllib/mdllib_utils.cpp')
-rw-r--r--mdllib/mdllib_utils.cpp205
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 );
+}
+
+