csgo-2018-source/mdllib/mdllib_utils.h

213 lines
5.5 KiB
C
Raw Normal View History

2021-07-25 12:11:47 +08:00
//====== Copyright <20> 1996-2007, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#ifndef MDLLIB_UTILS_H
#define MDLLIB_UTILS_H
#ifdef _WIN32
#pragma once
#endif
#include "utlmap.h"
#include "utlvector.h"
#include "bitvec.h"
//////////////////////////////////////////////////////////////////////////
//
// Helper macros
//
//////////////////////////////////////////////////////////////////////////
// Declare a pointer and automatically do the cast of initial value to the pointer type
#define DECLARE_PTR( type, name, initval ) type *name = ( type * ) ( initval )
#define DECLARE_UPDATE_PTR( type, name, initval ) name = ( type * ) ( initval )
// Compute a pointer that is offset given number of bytes from the base pointer
#define BYTE_OFF_PTR( initval, offval ) ( ( ( byte * ) ( initval ) ) + ( offval ) )
// Compute difference in bytes between two pointers
#define BYTE_DIFF_PTR( begin, end ) ( ( ( byte * ) ( end ) ) - ( ( byte * ) ( begin ) ) )
// "for {" to iterate children of a studio container
#define ITERATE_CHILDREN( type, name, parent, accessor, count ) \
for ( int name##_idx = 0; name##_idx < (parent)->count; ++ name##_idx ) { \
type *name = (parent)->accessor( name##_idx );
// "for {" to jointly iterate children of 2 studio containers of same size
#define ITERATE_CHILDREN2( type, type2, name, name2, parent, parent2, accessor, accessor2, count ) \
for ( int name##_idx = 0; name##_idx < (parent)->count; ++ name##_idx ) { \
type *name = (parent)->accessor( name##_idx ); \
type2 *name2 = (parent2)->accessor2( name##_idx );
// "}" to mark the end of iteration block
#define ITERATE_END }
// Get the child of a container by index
#define CHILD_AT( parent, accessor, idx ) ( (parent)->accessor( idx ) )
//
// CLessSimple< T >
// Comparison policy to use "t1 < t2" comparison rule.
//
template < typename T >
class CLessSimple
{
public:
bool Less( const T& src1, const T& src2, void *pCtx )
{
pCtx;
return ( src1 < src2 );
}
};
//
// CInsertionTracker
// Class that is tracking insertions that are scheduled to happen at given points.
// Use policy:
// InsertBytes / InsertElements [*] -- schedule insertions
// Finalize -- finalize insertion information
// ComputePointer / ComputeOffset [*] -- compute new pointers/offsets that will happen after insertions
// MemMove -- perform memory moves to apply insertions
//
class CInsertionTracker
{
public:
CInsertionTracker() : m_map( DefLessFunc( byte * ) ) {}
// Schedules a piece of memory for insertion
public:
void InsertBytes( void *pos, int length );
template< typename T >
void InsertElements( T *ptr, int count = 1 ) { InsertBytes( ( byte * ) ptr, count * sizeof( T ) ); }
int GetNumBytesInserted() const;
// Finalizes the insertion information
public:
void Finalize();
// Computes where the pointer would point after memory insertion occurs
public:
void * ComputePointer( void *ptrNothingInserted ) const;
int ComputeOffset( void *ptrBase, int off ) const;
// Perform memory moves, the buffer should be large enough to accommodate inserted bytes
public:
void MemMove( void *ptrBase, int &length ) const;
protected:
typedef CUtlMap< byte *, int, unsigned int > Map;
Map m_map; // pos -> length
};
//
// CMemoryMovingTracker
// Class that is tracking removals that are scheduled to happen at given points.
// Use policy:
// RegisterBytes / RegisterElements[*] -- schedule moving
// Finalize -- finalize moving information
// ComputePointer / ComputeOffset [*] -- compute new pointers/offsets that will happen after moving
// MemMove -- perform memory moves to apply
//
class CMemoryMovingTracker
{
public:
enum MemoryMovingPolicy_t
{
MEMORY_REMOVE,
MEMORY_INSERT,
MEMORY_MODIFY,
};
explicit CMemoryMovingTracker( MemoryMovingPolicy_t ePolicy ) : m_map( DefLessFunc( byte * ) ), m_ePolicy( ePolicy ) {}
// Schedules a piece of memory for removal
public:
void RegisterBytes( void *pos, int length );
template< typename T >
void RegisterElements( T *ptr, int count = 1 ) { RegisterBytes( ( byte * ) ptr, count * sizeof( T ) ); }
int GetNumBytesRegistered() const;
// Finalizes the removal information
public:
void RegisterBaseDelta( void *pOldBase, void *pNewBase );
void Finalize();
// Computes where the pointer would point after memory removal occurs
public:
void * ComputePointer( void *ptrNothingRemoved ) const;
int ComputeOffset( void *ptrBase, int off ) const;
public:
void MemMove( void *ptrBase, int &length ) const;
protected:
typedef CUtlMap< byte *, int, unsigned int > Map;
Map m_map; // pos -> length
struct Item
{
Map::IndexType_t idx;
byte *ptr;
int len;
};
Item m_hint;
MemoryMovingPolicy_t m_ePolicy;
};
//
// CGrowableBitVec
// Serves bit accumulation.
// Provides "GrowSetBit" method to automatically grow to the required size
// and set the given bit.
// Provides safe "IsBitSet" that would return false for missing bits.
//
class CGrowableBitVec : public CLargeVarBitVec
{
public:
void GrowSetBit( int iBit )
{
if ( iBit >= GetNumBits() )
Resize( iBit + 1, false );
Set( iBit );
}
bool IsBitSet( int bitNum ) const
{
return ( bitNum < GetNumBits() ) && CLargeVarBitVec::IsBitSet( bitNum );
}
};
//
// CGrowableVector
// Provides zero-initialization for new elements.
//
template < typename T >
class CGrowableVector : public CUtlVector < T >
{
public:
T & operator[] ( int idx )
{
while ( idx >= Count() )
AddToTail( T() );
return CUtlVector < T >::operator []( idx );
}
};
#endif // #ifndef MDLLIB_UTILS_H