Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

205 lines
4.9 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "mdllib_utils.h"
  7. //////////////////////////////////////////////////////////////////////////
  8. //
  9. // CInsertionTracker implementation
  10. //
  11. //////////////////////////////////////////////////////////////////////////
  12. void CInsertionTracker::InsertBytes( void *pos, int length )
  13. {
  14. if ( length <= 0 )
  15. return;
  16. Assert( m_map.InvalidIndex() == m_map.Find( ( byte * ) pos ) );
  17. m_map.InsertOrReplace( ( byte * ) pos, length );
  18. }
  19. int CInsertionTracker::GetNumBytesInserted() const
  20. {
  21. int iInserted = 0;
  22. for ( Map::IndexType_t idx = m_map.FirstInorder();
  23. idx != m_map.InvalidIndex(); idx = m_map.NextInorder( idx ) )
  24. {
  25. int numBytes = m_map.Element( idx );
  26. iInserted += numBytes;
  27. }
  28. return iInserted;
  29. }
  30. void CInsertionTracker::Finalize()
  31. {
  32. // Iterate the map and find all the adjacent removal data blocks
  33. // TODO:
  34. }
  35. void CInsertionTracker::MemMove( void *ptrBase, int &length ) const
  36. {
  37. int numBytesInsertReq = GetNumBytesInserted();
  38. byte *pbBlockEnd = BYTE_OFF_PTR( ptrBase, length );
  39. length += numBytesInsertReq;
  40. for ( Map::IndexType_t idx = m_map.LastInorder();
  41. idx != m_map.InvalidIndex(); idx = m_map.PrevInorder( idx ) )
  42. {
  43. byte *ptr = m_map.Key( idx );
  44. int numBytes = m_map.Element( idx );
  45. // Move [ptr, pbBlockEnd) ->> + numBytesInsertReq
  46. memmove( BYTE_OFF_PTR( ptr, numBytesInsertReq ), ptr, BYTE_DIFF_PTR( ptr, pbBlockEnd ) );
  47. // Inserted data
  48. memset( BYTE_OFF_PTR( ptr, numBytesInsertReq - numBytes ), 0, numBytes );
  49. numBytesInsertReq -= numBytes;
  50. pbBlockEnd = ptr;
  51. }
  52. }
  53. int CInsertionTracker::ComputeOffset( void *ptrBase, int off ) const
  54. {
  55. void *ptrNewBase = ComputePointer( ptrBase );
  56. void *ptrNewData = ComputePointer( BYTE_OFF_PTR( ptrBase, off ) );
  57. return BYTE_DIFF_PTR( ptrNewBase, ptrNewData );
  58. }
  59. void * CInsertionTracker::ComputePointer( void *ptrNothingInserted ) const
  60. {
  61. int iInserted = 0;
  62. // Iterate the map and find all the data that would be inserted before the given pointer
  63. for ( Map::IndexType_t idx = m_map.FirstInorder();
  64. idx != m_map.InvalidIndex(); idx = m_map.NextInorder( idx ) )
  65. {
  66. if ( m_map.Key( idx ) < ptrNothingInserted )
  67. iInserted += m_map.Element( idx );
  68. else
  69. break;
  70. }
  71. return BYTE_OFF_PTR( ptrNothingInserted, iInserted );
  72. }
  73. //////////////////////////////////////////////////////////////////////////
  74. //
  75. // CRemoveTracker implementation
  76. //
  77. //////////////////////////////////////////////////////////////////////////
  78. void CRemoveTracker::RemoveBytes( void *pos, int length )
  79. {
  80. if ( length <= 0 )
  81. return;
  82. // -- hint
  83. if ( m_map.Count() )
  84. {
  85. if ( m_hint.ptr < pos )
  86. {
  87. if ( BYTE_OFF_PTR( m_hint.ptr, m_hint.len ) == pos )
  88. {
  89. m_hint.len += length;
  90. m_map.Element( m_hint.idx ) = m_hint.len;
  91. return;
  92. }
  93. }
  94. else if ( m_hint.ptr > pos )
  95. {
  96. if ( BYTE_OFF_PTR( pos, length ) == m_hint.ptr )
  97. {
  98. m_hint.len += length;
  99. m_hint.ptr = BYTE_OFF_PTR( m_hint.ptr, - length );
  100. m_map.Key( m_hint.idx ) = m_hint.ptr;
  101. m_map.Element( m_hint.idx ) = m_hint.len;
  102. return;
  103. }
  104. }
  105. }
  106. // -- end hint
  107. // Insert new
  108. Assert( m_map.InvalidIndex() == m_map.Find( ( byte * ) pos ) );
  109. Map::IndexType_t idx = m_map.InsertOrReplace( ( byte * ) pos, length );
  110. // New hint
  111. m_hint.idx = idx;
  112. m_hint.ptr = ( byte * ) pos;
  113. m_hint.len = length;
  114. }
  115. int CRemoveTracker::GetNumBytesRemoved() const
  116. {
  117. int iRemoved = 0;
  118. for ( Map::IndexType_t idx = m_map.FirstInorder();
  119. idx != m_map.InvalidIndex(); idx = m_map.NextInorder( idx ) )
  120. {
  121. int numBytes = m_map.Element( idx );
  122. iRemoved += numBytes;
  123. }
  124. return iRemoved;
  125. }
  126. void CRemoveTracker::Finalize()
  127. {
  128. // Iterate the map and find all the adjacent removal data blocks
  129. // TODO:
  130. }
  131. void CRemoveTracker::MemMove( void *ptrBase, int &length ) const
  132. {
  133. int iRemoved = 0;
  134. for ( Map::IndexType_t idx = m_map.FirstInorder();
  135. idx != m_map.InvalidIndex(); idx = m_map.NextInorder( idx ) )
  136. {
  137. byte *ptr = m_map.Key( idx );
  138. byte *ptrDest = BYTE_OFF_PTR( ptr, - iRemoved );
  139. int numBytes = m_map.Element( idx );
  140. memmove( ptrDest, BYTE_OFF_PTR( ptrDest, numBytes ), BYTE_DIFF_PTR( BYTE_OFF_PTR( ptr, numBytes ), BYTE_OFF_PTR( ptrBase, length ) ) );
  141. iRemoved += numBytes;
  142. }
  143. length -= iRemoved;
  144. }
  145. int CRemoveTracker::ComputeOffset( void *ptrBase, int off ) const
  146. {
  147. void *ptrNewBase = ComputePointer( ptrBase );
  148. void *ptrNewData = ComputePointer( BYTE_OFF_PTR( ptrBase, off ) );
  149. return BYTE_DIFF_PTR( ptrNewBase, ptrNewData );
  150. }
  151. void * CRemoveTracker::ComputePointer( void *ptrNothingRemoved ) const
  152. {
  153. int iRemoved = 0;
  154. // Iterate the map and find all the data that would be removed before the given pointer
  155. for ( Map::IndexType_t idx = m_map.FirstInorder();
  156. idx != m_map.InvalidIndex(); idx = m_map.NextInorder( idx ) )
  157. {
  158. if ( m_map.Key( idx ) < ptrNothingRemoved )
  159. iRemoved += m_map.Element( idx );
  160. else
  161. break;
  162. }
  163. return BYTE_OFF_PTR( ptrNothingRemoved, - iRemoved );
  164. }