mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-07 17:29:36 +00:00
amd64: fix multithread, fix vgui, fix physmodels
This commit is contained in:
+458
-112
@@ -1,4 +1,4 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//====== Copyright (c) 1996-2005, Valve Corporation, All rights reserved. =======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
@@ -14,6 +14,8 @@
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "unitlib/unitlib.h" // just here for tests - remove before checking in!!!
|
||||
|
||||
#include "tier1/utlmemory.h"
|
||||
#include "tier1/byteswap.h"
|
||||
#include <stdarg.h>
|
||||
@@ -102,11 +104,48 @@ CUtlCharConversion *GetNoEscCharConversion();
|
||||
SetOverflowFuncs( static_cast <UtlBufferOverflowFunc_t>( _get ), static_cast <UtlBufferOverflowFunc_t>( _put ) )
|
||||
|
||||
|
||||
|
||||
typedef unsigned short ushort;
|
||||
|
||||
template < class A >
|
||||
static const char *GetFmtStr( int nRadix = 10, bool bPrint = true ) { Assert( 0 ); return ""; }
|
||||
#if defined( LINUX ) || defined( __clang__ ) || ( defined( _MSC_VER ) && _MSC_VER >= 1900 )
|
||||
template <> const char *GetFmtStr< short > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return "%hd"; }
|
||||
template <> const char *GetFmtStr< ushort > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return "%hu"; }
|
||||
template <> const char *GetFmtStr< int > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return "%d"; }
|
||||
template <> const char *GetFmtStr< uint > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 || nRadix == 16 ); return nRadix == 16 ? "%x" : "%u"; }
|
||||
template <> const char *GetFmtStr< int64 > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return "%lld"; }
|
||||
template <> const char *GetFmtStr< float > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return "%f"; }
|
||||
template <> const char *GetFmtStr< double > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return bPrint ? "%.15lf" : "%lf"; } // force Printf to print DBL_DIG=15 digits of precision for doubles - defaults to FLT_DIG=6
|
||||
#else
|
||||
template <> static const char *GetFmtStr< short > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return "%hd"; }
|
||||
template <> static const char *GetFmtStr< ushort > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return "%hu"; }
|
||||
template <> static const char *GetFmtStr< int > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return "%d"; }
|
||||
template <> static const char *GetFmtStr< uint > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 || nRadix == 16 ); return nRadix == 16 ? "%x" : "%u"; }
|
||||
template <> static const char *GetFmtStr< int64 > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return "%lld"; }
|
||||
template <> static const char *GetFmtStr< float > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return "%f"; }
|
||||
template <> static const char *GetFmtStr< double > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return bPrint ? "%.15lf" : "%lf"; } // force Printf to print DBL_DIG=15 digits of precision for doubles - defaults to FLT_DIG=6
|
||||
#endif
|
||||
//-----------------------------------------------------------------------------
|
||||
// Command parsing..
|
||||
//-----------------------------------------------------------------------------
|
||||
class CUtlBuffer
|
||||
{
|
||||
// Brian has on his todo list to revisit this as there are issues in some cases with CUtlVector using operator = instead of copy construtor in InsertMultiple, etc.
|
||||
// The unsafe case is something like this:
|
||||
// CUtlVector< CUtlBuffer > vecFoo;
|
||||
//
|
||||
// CUtlBuffer buf;
|
||||
// buf.Put( xxx );
|
||||
// vecFoo.Insert( buf );
|
||||
//
|
||||
// This will cause memory corruption when vecFoo is cleared
|
||||
//
|
||||
//private:
|
||||
// // Disallow copying
|
||||
// CUtlBuffer( const CUtlBuffer & );// { Assert( 0 ); }
|
||||
// CUtlBuffer &operator=( const CUtlBuffer & );// { Assert( 0 ); return *this; }
|
||||
|
||||
public:
|
||||
enum SeekType_t
|
||||
{
|
||||
@@ -132,7 +171,19 @@ public:
|
||||
CUtlBuffer( int growSize = 0, int initSize = 0, int nFlags = 0 );
|
||||
CUtlBuffer( const void* pBuffer, int size, int nFlags = 0 );
|
||||
// This one isn't actually defined so that we catch contructors that are trying to pass a bool in as the third param.
|
||||
CUtlBuffer( const void *pBuffer, int size, bool crap );
|
||||
CUtlBuffer( const void *pBuffer, int size, bool crap ) = delete;
|
||||
|
||||
// UtlBuffer objects should not be copyable; we do a slow copy if you use this but it asserts.
|
||||
// (REI: I'd like to delete these but we have some python bindings that currently rely on being able to copy these objects)
|
||||
CUtlBuffer( const CUtlBuffer& ); // = delete;
|
||||
CUtlBuffer& operator= ( const CUtlBuffer& ); // = delete;
|
||||
|
||||
#if VALVE_CPP11
|
||||
// UtlBuffer is non-copyable (same as CUtlMemory), but it is moveable. We would like to declare these with '= default'
|
||||
// but unfortunately VS2013 isn't fully C++11 compliant, so we have to manually declare these in the boilerplate way.
|
||||
CUtlBuffer( CUtlBuffer&& moveFrom ); // = default;
|
||||
CUtlBuffer& operator= ( CUtlBuffer&& moveFrom ); // = default;
|
||||
#endif
|
||||
|
||||
unsigned char GetFlags() const;
|
||||
|
||||
@@ -143,11 +194,15 @@ public:
|
||||
// Makes sure we've got at least this much memory
|
||||
void EnsureCapacity( int num );
|
||||
|
||||
// Access for direct read into buffer
|
||||
void * AccessForDirectRead( int nBytes );
|
||||
|
||||
// Attaches the buffer to external memory....
|
||||
void SetExternalBuffer( void* pMemory, int nSize, int nInitialPut, int nFlags = 0 );
|
||||
bool IsExternallyAllocated() const;
|
||||
// Takes ownership of the passed memory, including freeing it when this buffer is destroyed.
|
||||
void AssumeMemory( void *pMemory, int nSize, int nInitialPut, int nFlags = 0 );
|
||||
void *Detach();
|
||||
void* DetachMemory();
|
||||
|
||||
// copies data from another buffer
|
||||
void CopyBuffer( const CUtlBuffer &buffer );
|
||||
@@ -156,9 +211,10 @@ public:
|
||||
void Swap( CUtlBuffer &buf );
|
||||
void Swap( CUtlMemory<uint8> &mem );
|
||||
|
||||
|
||||
FORCEINLINE void ActivateByteSwappingIfBigEndian( void )
|
||||
{
|
||||
if ( IsX360() )
|
||||
if ( ( IsX360() || IsPS3() ) )
|
||||
ActivateByteSwapping( true );
|
||||
}
|
||||
|
||||
@@ -174,6 +230,9 @@ public:
|
||||
// Clears out the buffer; frees memory
|
||||
void Purge();
|
||||
|
||||
// Dump the buffer to stdout
|
||||
void Spew( );
|
||||
|
||||
// Read stuff out.
|
||||
// Binary mode: it'll just read the bits directly in, and characters will be
|
||||
// read for strings until a null character is reached.
|
||||
@@ -185,28 +244,25 @@ public:
|
||||
unsigned short GetUnsignedShort( );
|
||||
int GetInt( );
|
||||
int64 GetInt64( );
|
||||
int GetIntHex( );
|
||||
unsigned int GetIntHex( );
|
||||
unsigned int GetUnsignedInt( );
|
||||
uint64 GetUnsignedInt64( );
|
||||
float GetFloat( );
|
||||
double GetDouble( );
|
||||
void * GetPtr();
|
||||
template <size_t maxLenInChars> void GetString( char( &pString )[maxLenInChars] )
|
||||
{
|
||||
GetStringInternal( pString, maxLenInChars );
|
||||
}
|
||||
|
||||
void GetString( char *pString, size_t maxLenInChars )
|
||||
{
|
||||
GetStringInternal( pString, maxLenInChars );
|
||||
}
|
||||
void * GetPtr();
|
||||
void GetString( char* pString, int nMaxChars );
|
||||
bool Get( void* pMem, int size );
|
||||
void GetLine( char* pLine, int nMaxChars );
|
||||
|
||||
void GetStringManualCharCount( char *pString, size_t maxLenInChars )
|
||||
{
|
||||
GetStringInternal( pString, maxLenInChars );
|
||||
GetString( pString, maxLenInChars );
|
||||
}
|
||||
|
||||
void Get( void* pMem, int size );
|
||||
void GetLine( char* pLine, int nMaxChars = 0 );
|
||||
template <size_t maxLenInChars> void GetString( char( &pString )[maxLenInChars] )
|
||||
{
|
||||
GetString( pString, maxLenInChars );
|
||||
}
|
||||
|
||||
// Used for getting objects that have a byteswap datadesc defined
|
||||
template <typename T> void GetObjects( T *dest, int count = 1 );
|
||||
@@ -238,7 +294,7 @@ public:
|
||||
|
||||
// Just like scanf, but doesn't work in binary mode
|
||||
int Scanf( SCANF_FORMAT_STRING const char* pFmt, ... );
|
||||
int VaScanf( const char* pFmt, va_list list );
|
||||
int VaScanf( const char* pFmt, va_list list );
|
||||
|
||||
// Eats white space, advances Get index
|
||||
void EatWhiteSpace();
|
||||
@@ -270,16 +326,16 @@ public:
|
||||
// PutString will not write a terminating character
|
||||
void PutChar( char c );
|
||||
void PutUnsignedChar( unsigned char uc );
|
||||
void PutUint64( uint64 ub );
|
||||
void PutInt16( int16 s16 );
|
||||
void PutShort( short s );
|
||||
void PutUnsignedShort( unsigned short us );
|
||||
void PutInt( int i );
|
||||
void PutInt64( int64 i );
|
||||
void PutUnsignedInt( unsigned int u );
|
||||
void PutUnsignedInt64( uint64 u );
|
||||
void PutUint64( uint64 u );
|
||||
void PutFloat( float f );
|
||||
void PutDouble( double d );
|
||||
void PutPtr( void * ); // Writes the pointer, not the pointed to
|
||||
void PutPtr( void * ); // Writes the pointer, not the pointed to
|
||||
void PutString( const char* pString );
|
||||
void Put( const void* pMem, int size );
|
||||
|
||||
@@ -318,8 +374,8 @@ public:
|
||||
// Buffer base
|
||||
const void* Base() const;
|
||||
void* Base();
|
||||
// Returns the base as a const char*, only valid in text mode.
|
||||
const char *String() const;
|
||||
|
||||
const void* String() const;
|
||||
|
||||
// memory allocation size, does *not* reflect size written or read,
|
||||
// use TellPut or TellGet for that
|
||||
@@ -352,6 +408,12 @@ public:
|
||||
// Temporarily disables pretty print
|
||||
void EnableTabs( bool bEnable );
|
||||
|
||||
#if !defined( _GAMECONSOLE )
|
||||
// Swap my internal memory with another buffer,
|
||||
// and copy all of its other members
|
||||
void SwapCopy( CUtlBuffer &other ) ;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
// error flags
|
||||
enum
|
||||
@@ -371,7 +433,10 @@ protected:
|
||||
bool CheckPut( int size );
|
||||
bool CheckGet( int size );
|
||||
|
||||
// NOTE: Pass in nPut here even though it is just a copy of m_Put. This is almost always called immediately
|
||||
// after modifying m_Put and this lets it stay in a register
|
||||
void AddNullTermination( );
|
||||
void AddNullTermination( int nPut );
|
||||
|
||||
// Methods to help with pretty-printing
|
||||
bool WasLastCharacterCR();
|
||||
@@ -400,16 +465,18 @@ protected:
|
||||
// Call this to peek arbitrarily long into memory. It doesn't fail unless
|
||||
// it can't read *anything* new
|
||||
bool CheckArbitraryPeekGet( int nOffset, int &nIncrement );
|
||||
void GetStringInternal( char *pString, size_t maxLenInChars );
|
||||
|
||||
template <typename T> void GetType( T& dest, const char *pszFmt );
|
||||
template <typename T> void GetType( T& dest );
|
||||
template <typename T> void GetTypeBin( T& dest );
|
||||
template <typename T> bool GetTypeText( T &value, int nRadix = 10 );
|
||||
template <typename T> void GetObject( T *src );
|
||||
|
||||
template <typename T> void PutType( T src, const char *pszFmt );
|
||||
template <typename T> void PutType( T src );
|
||||
template <typename T> void PutTypeBin( T src );
|
||||
template <typename T> void PutObject( T *src );
|
||||
|
||||
// be sure to also update the copy constructor
|
||||
// and SwapCopy() when adding members.
|
||||
CUtlMemory<unsigned char> m_Memory;
|
||||
int m_Get;
|
||||
int m_Put;
|
||||
@@ -417,7 +484,7 @@ protected:
|
||||
unsigned char m_Error;
|
||||
unsigned char m_Flags;
|
||||
unsigned char m_Reserved;
|
||||
#if defined( _X360 )
|
||||
#if defined( _GAMECONSOLE )
|
||||
unsigned char pad;
|
||||
#endif
|
||||
|
||||
@@ -605,7 +672,7 @@ inline void CUtlBuffer::GetObject( T *dest )
|
||||
{
|
||||
if ( !m_Byteswap.IsSwappingBytes() || ( sizeof( T ) == 1 ) )
|
||||
{
|
||||
Q_memcpy( dest, PeekGet(), sizeof( T ) );
|
||||
*dest = *(T *)PeekGet();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -615,7 +682,7 @@ inline void CUtlBuffer::GetObject( T *dest )
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_memset( dest, 0, sizeof(T) );
|
||||
Q_memset( &dest, 0, sizeof(T) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -637,18 +704,18 @@ inline void CUtlBuffer::GetTypeBin( T &dest )
|
||||
{
|
||||
if ( !m_Byteswap.IsSwappingBytes() || ( sizeof( T ) == 1 ) )
|
||||
{
|
||||
Q_memcpy(&dest, PeekGet(), sizeof(T) );
|
||||
dest = *(T *)PeekGet();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Byteswap.SwapBufferToTargetEndian<T>( &dest, (T*)PeekGet() );
|
||||
}
|
||||
m_Get += sizeof(T);
|
||||
}
|
||||
m_Get += sizeof(T);
|
||||
}
|
||||
else
|
||||
{
|
||||
dest = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
@@ -656,8 +723,8 @@ inline void CUtlBuffer::GetTypeBin< float >( float &dest )
|
||||
{
|
||||
if ( CheckGet( sizeof( float ) ) )
|
||||
{
|
||||
uintptr_t pData = (uintptr_t)PeekGet();
|
||||
if ( IsX360() && ( pData & 0x03 ) )
|
||||
uintp pData = (uintp)PeekGet();
|
||||
if ( ( IsX360() || IsPS3() ) && ( pData & 0x03 ) )
|
||||
{
|
||||
// handle unaligned read
|
||||
((unsigned char*)&dest)[0] = ((unsigned char*)pData)[0];
|
||||
@@ -668,22 +735,148 @@ inline void CUtlBuffer::GetTypeBin< float >( float &dest )
|
||||
else
|
||||
{
|
||||
// aligned read
|
||||
Q_memcpy( &dest, (void*)pData, sizeof(float) );
|
||||
dest = *(float *)pData;
|
||||
}
|
||||
if ( m_Byteswap.IsSwappingBytes() )
|
||||
{
|
||||
m_Byteswap.SwapBufferToTargetEndian< float >( &dest, &dest );
|
||||
}
|
||||
m_Get += sizeof( float );
|
||||
}
|
||||
m_Get += sizeof( float );
|
||||
}
|
||||
else
|
||||
{
|
||||
dest = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void CUtlBuffer::GetTypeBin< double >( double &dest )
|
||||
{
|
||||
if ( CheckGet( sizeof( double ) ) )
|
||||
{
|
||||
uintp pData = (uintp)PeekGet();
|
||||
if ( ( IsX360() || IsPS3() ) && ( pData & 0x07 ) )
|
||||
{
|
||||
// handle unaligned read
|
||||
((unsigned char*)&dest)[0] = ((unsigned char*)pData)[0];
|
||||
((unsigned char*)&dest)[1] = ((unsigned char*)pData)[1];
|
||||
((unsigned char*)&dest)[2] = ((unsigned char*)pData)[2];
|
||||
((unsigned char*)&dest)[3] = ((unsigned char*)pData)[3];
|
||||
((unsigned char*)&dest)[4] = ((unsigned char*)pData)[4];
|
||||
((unsigned char*)&dest)[5] = ((unsigned char*)pData)[5];
|
||||
((unsigned char*)&dest)[6] = ((unsigned char*)pData)[6];
|
||||
((unsigned char*)&dest)[7] = ((unsigned char*)pData)[7];
|
||||
}
|
||||
else
|
||||
{
|
||||
// aligned read
|
||||
dest = *(double *)pData;
|
||||
}
|
||||
if ( m_Byteswap.IsSwappingBytes() )
|
||||
{
|
||||
m_Byteswap.SwapBufferToTargetEndian< double >( &dest, &dest );
|
||||
}
|
||||
m_Get += sizeof( double );
|
||||
}
|
||||
else
|
||||
{
|
||||
dest = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template < class T >
|
||||
inline T StringToNumber( char *pString, char **ppEnd, int nRadix )
|
||||
{
|
||||
Assert( 0 );
|
||||
*ppEnd = pString;
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline int8 StringToNumber( char *pString, char **ppEnd, int nRadix )
|
||||
{
|
||||
return ( int8 )strtol( pString, ppEnd, nRadix );
|
||||
}
|
||||
|
||||
template <>
|
||||
inline uint8 StringToNumber( char *pString, char **ppEnd, int nRadix )
|
||||
{
|
||||
return ( uint8 )strtoul( pString, ppEnd, nRadix );
|
||||
}
|
||||
|
||||
template <>
|
||||
inline int16 StringToNumber( char *pString, char **ppEnd, int nRadix )
|
||||
{
|
||||
return ( int16 )strtol( pString, ppEnd, nRadix );
|
||||
}
|
||||
|
||||
template <>
|
||||
inline uint16 StringToNumber( char *pString, char **ppEnd, int nRadix )
|
||||
{
|
||||
return ( uint16 )strtoul( pString, ppEnd, nRadix );
|
||||
}
|
||||
|
||||
template <>
|
||||
inline int32 StringToNumber( char *pString, char **ppEnd, int nRadix )
|
||||
{
|
||||
return ( int32 )strtol( pString, ppEnd, nRadix );
|
||||
}
|
||||
|
||||
template <>
|
||||
inline uint32 StringToNumber( char *pString, char **ppEnd, int nRadix )
|
||||
{
|
||||
return ( uint32 )strtoul( pString, ppEnd, nRadix );
|
||||
}
|
||||
|
||||
template <>
|
||||
inline int64 StringToNumber( char *pString, char **ppEnd, int nRadix )
|
||||
{
|
||||
#if defined(_PS3) || defined(POSIX)
|
||||
return ( int64 )strtoll( pString, ppEnd, nRadix );
|
||||
#else // !_PS3
|
||||
return ( int64 )_strtoi64( pString, ppEnd, nRadix );
|
||||
#endif // _PS3
|
||||
}
|
||||
|
||||
template <>
|
||||
inline float StringToNumber( char *pString, char **ppEnd, int nRadix )
|
||||
{
|
||||
NOTE_UNUSED( nRadix );
|
||||
return ( float )strtod( pString, ppEnd );
|
||||
}
|
||||
|
||||
template <>
|
||||
inline double StringToNumber( char *pString, char **ppEnd, int nRadix )
|
||||
{
|
||||
NOTE_UNUSED( nRadix );
|
||||
return ( double )strtod( pString, ppEnd );
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool CUtlBuffer::GetTypeText( T &value, int nRadix /*= 10*/ )
|
||||
{
|
||||
// NOTE: This is not bullet-proof; it assumes numbers are < 128 characters
|
||||
int nLength = 128;
|
||||
if ( !CheckArbitraryPeekGet( 0, nLength ) )
|
||||
{
|
||||
value = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
char *pStart = (char*)PeekGet();
|
||||
char* pEnd = pStart;
|
||||
value = StringToNumber< T >( pStart, &pEnd, nRadix );
|
||||
|
||||
int nBytesRead = (int)( pEnd - pStart );
|
||||
if ( nBytesRead == 0 )
|
||||
return false;
|
||||
|
||||
m_Get += nBytesRead;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void CUtlBuffer::GetType( T &dest, const char *pszFmt )
|
||||
inline void CUtlBuffer::GetType( T &dest )
|
||||
{
|
||||
if (!IsText())
|
||||
{
|
||||
@@ -691,93 +884,115 @@ inline void CUtlBuffer::GetType( T &dest, const char *pszFmt )
|
||||
}
|
||||
else
|
||||
{
|
||||
dest = 0;
|
||||
Scanf( pszFmt, &dest );
|
||||
GetTypeText( dest );
|
||||
}
|
||||
}
|
||||
|
||||
inline char CUtlBuffer::GetChar( )
|
||||
{
|
||||
// LEGACY WARNING: this behaves differently than GetUnsignedChar()
|
||||
char c;
|
||||
GetType( c, "%c" );
|
||||
GetTypeBin( c ); // always reads as binary
|
||||
return c;
|
||||
}
|
||||
|
||||
inline unsigned char CUtlBuffer::GetUnsignedChar( )
|
||||
{
|
||||
// LEGACY WARNING: this behaves differently than GetChar()
|
||||
unsigned char c;
|
||||
GetType( c, "%u" );
|
||||
if (!IsText())
|
||||
{
|
||||
GetTypeBin( c );
|
||||
}
|
||||
else
|
||||
{
|
||||
c = ( unsigned char )GetUnsignedShort();
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
inline short CUtlBuffer::GetShort( )
|
||||
{
|
||||
short s;
|
||||
GetType( s, "%d" );
|
||||
GetType( s );
|
||||
return s;
|
||||
}
|
||||
|
||||
inline unsigned short CUtlBuffer::GetUnsignedShort( )
|
||||
{
|
||||
unsigned short s;
|
||||
GetType( s, "%u" );
|
||||
GetType( s );
|
||||
return s;
|
||||
}
|
||||
|
||||
inline int CUtlBuffer::GetInt( )
|
||||
{
|
||||
int i;
|
||||
GetType( i, "%d" );
|
||||
GetType( i );
|
||||
return i;
|
||||
}
|
||||
|
||||
inline int64 CUtlBuffer::GetInt64( )
|
||||
{
|
||||
int64 i;
|
||||
GetType( i, "%lld" );
|
||||
GetType( i );
|
||||
return i;
|
||||
}
|
||||
|
||||
inline int CUtlBuffer::GetIntHex( )
|
||||
inline unsigned int CUtlBuffer::GetIntHex( )
|
||||
{
|
||||
int i;
|
||||
GetType( i, "%x" );
|
||||
uint i;
|
||||
if (!IsText())
|
||||
{
|
||||
GetTypeBin( i );
|
||||
}
|
||||
else
|
||||
{
|
||||
GetTypeText( i, 16 );
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
inline unsigned int CUtlBuffer::GetUnsignedInt( )
|
||||
{
|
||||
unsigned int u;
|
||||
GetType( u, "%u" );
|
||||
return u;
|
||||
unsigned int i;
|
||||
GetType( i );
|
||||
return i;
|
||||
}
|
||||
|
||||
inline uint64 CUtlBuffer::GetUnsignedInt64()
|
||||
{
|
||||
uint64 i;
|
||||
GetType( i );
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
inline float CUtlBuffer::GetFloat( )
|
||||
{
|
||||
float f;
|
||||
GetType( f, "%f" );
|
||||
GetType( f );
|
||||
return f;
|
||||
}
|
||||
|
||||
inline void *CUtlBuffer::GetPtr( )
|
||||
{
|
||||
void *p;
|
||||
// LEGACY WARNING: in text mode, PutPtr writes 32 bit pointers in hex, while GetPtr reads 32 or 64 bit pointers in decimal
|
||||
#ifndef PLATFORM_64BITS
|
||||
p = ( void* )GetUnsignedInt();
|
||||
#else
|
||||
p = ( void* )GetInt64();
|
||||
#endif
|
||||
return p;
|
||||
}
|
||||
|
||||
inline double CUtlBuffer::GetDouble( )
|
||||
{
|
||||
double d;
|
||||
GetType( d, "%f" );
|
||||
GetType( d );
|
||||
return d;
|
||||
}
|
||||
|
||||
inline void *CUtlBuffer::GetPtr( )
|
||||
{
|
||||
void *p;
|
||||
// LEGACY WARNING: in text mode, PutPtr writes 32 bit pointers in hex, while GetPtr reads 32 or 64 bit pointers in decimal
|
||||
#if !defined(X64BITS) && !defined(PLATFORM_64BITS)
|
||||
p = ( void* )GetUnsignedInt();
|
||||
#else
|
||||
p = ( void* )GetInt64();
|
||||
#endif
|
||||
return p;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Where am I writing?
|
||||
@@ -835,14 +1050,14 @@ inline void CUtlBuffer::PutObject( T *src )
|
||||
{
|
||||
if ( !m_Byteswap.IsSwappingBytes() || ( sizeof( T ) == 1 ) )
|
||||
{
|
||||
Q_memcpy( PeekPut(), src, sizeof( T ) );
|
||||
*(T *)PeekPut() = *src;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Byteswap.SwapFieldsToTargetEndian<T>( (T*)PeekPut(), src );
|
||||
}
|
||||
m_Put += sizeof(T);
|
||||
AddNullTermination();
|
||||
AddNullTermination( m_Put );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -864,19 +1079,93 @@ inline void CUtlBuffer::PutTypeBin( T src )
|
||||
{
|
||||
if ( !m_Byteswap.IsSwappingBytes() || ( sizeof( T ) == 1 ) )
|
||||
{
|
||||
Q_memcpy( PeekPut(), &src, sizeof( T ) );
|
||||
*(T *)PeekPut() = src;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Byteswap.SwapBufferToTargetEndian<T>( (T*)PeekPut(), &src );
|
||||
}
|
||||
m_Put += sizeof(T);
|
||||
AddNullTermination();
|
||||
AddNullTermination( m_Put );
|
||||
}
|
||||
}
|
||||
|
||||
#if defined( _GAMECONSOLE )
|
||||
template <>
|
||||
inline void CUtlBuffer::PutTypeBin< float >( float src )
|
||||
{
|
||||
if ( CheckPut( sizeof( src ) ) )
|
||||
{
|
||||
if ( m_Byteswap.IsSwappingBytes() )
|
||||
{
|
||||
m_Byteswap.SwapBufferToTargetEndian<float>( &src, &src );
|
||||
}
|
||||
|
||||
//
|
||||
// Write the data
|
||||
//
|
||||
unsigned pData = (unsigned)PeekPut();
|
||||
if ( pData & 0x03 )
|
||||
{
|
||||
// handle unaligned write
|
||||
byte* dst = (byte*)pData;
|
||||
byte* srcPtr = (byte*)&src;
|
||||
dst[0] = srcPtr[0];
|
||||
dst[1] = srcPtr[1];
|
||||
dst[2] = srcPtr[2];
|
||||
dst[3] = srcPtr[3];
|
||||
}
|
||||
else
|
||||
{
|
||||
*(float *)pData = src;
|
||||
}
|
||||
|
||||
m_Put += sizeof(float);
|
||||
AddNullTermination( m_Put );
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void CUtlBuffer::PutTypeBin< double >( double src )
|
||||
{
|
||||
if ( CheckPut( sizeof( src ) ) )
|
||||
{
|
||||
if ( m_Byteswap.IsSwappingBytes() )
|
||||
{
|
||||
m_Byteswap.SwapBufferToTargetEndian<double>( &src, &src );
|
||||
}
|
||||
|
||||
//
|
||||
// Write the data
|
||||
//
|
||||
unsigned pData = (unsigned)PeekPut();
|
||||
if ( pData & 0x07 )
|
||||
{
|
||||
// handle unaligned write
|
||||
byte* dst = (byte*)pData;
|
||||
byte* srcPtr = (byte*)&src;
|
||||
dst[0] = srcPtr[0];
|
||||
dst[1] = srcPtr[1];
|
||||
dst[2] = srcPtr[2];
|
||||
dst[3] = srcPtr[3];
|
||||
dst[4] = srcPtr[4];
|
||||
dst[5] = srcPtr[5];
|
||||
dst[6] = srcPtr[6];
|
||||
dst[7] = srcPtr[7];
|
||||
}
|
||||
else
|
||||
{
|
||||
*(double *)pData = src;
|
||||
}
|
||||
|
||||
m_Put += sizeof(double);
|
||||
AddNullTermination( m_Put );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
inline void CUtlBuffer::PutType( T src, const char *pszFmt )
|
||||
inline void CUtlBuffer::PutType( T src )
|
||||
{
|
||||
if (!IsText())
|
||||
{
|
||||
@@ -884,7 +1173,7 @@ inline void CUtlBuffer::PutType( T src, const char *pszFmt )
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf( pszFmt, src );
|
||||
Printf( GetFmtStr< T >(), src );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -952,68 +1241,74 @@ inline void CUtlBuffer::PutChar( char c )
|
||||
|
||||
inline void CUtlBuffer::PutUnsignedChar( unsigned char c )
|
||||
{
|
||||
PutType( c, "%u" );
|
||||
}
|
||||
|
||||
inline void CUtlBuffer::PutUint64( uint64 ub )
|
||||
{
|
||||
PutType( ub, "%llu" );
|
||||
}
|
||||
|
||||
inline void CUtlBuffer::PutInt16( int16 s16 )
|
||||
{
|
||||
PutType( s16, "%d" );
|
||||
if (!IsText())
|
||||
{
|
||||
PutTypeBin( c );
|
||||
}
|
||||
else
|
||||
{
|
||||
PutUnsignedShort( c );
|
||||
}
|
||||
}
|
||||
|
||||
inline void CUtlBuffer::PutShort( short s )
|
||||
{
|
||||
PutType( s, "%d" );
|
||||
PutType( s );
|
||||
}
|
||||
|
||||
inline void CUtlBuffer::PutUnsignedShort( unsigned short s )
|
||||
{
|
||||
PutType( s, "%u" );
|
||||
PutType( s );
|
||||
}
|
||||
|
||||
inline void CUtlBuffer::PutInt( int i )
|
||||
{
|
||||
PutType( i, "%d" );
|
||||
PutType( i );
|
||||
}
|
||||
|
||||
inline void CUtlBuffer::PutInt64( int64 i )
|
||||
{
|
||||
PutType( i, "%llu" );
|
||||
PutType( i );
|
||||
}
|
||||
|
||||
inline void CUtlBuffer::PutUnsignedInt( unsigned int u )
|
||||
{
|
||||
PutType( u, "%u" );
|
||||
PutType( u );
|
||||
}
|
||||
|
||||
inline void CUtlBuffer::PutUnsignedInt64( uint64 i )
|
||||
{
|
||||
PutType( i );
|
||||
}
|
||||
|
||||
inline void CUtlBuffer::PutUint64( uint64 i )
|
||||
{
|
||||
PutType( i );
|
||||
}
|
||||
|
||||
inline void CUtlBuffer::PutFloat( float f )
|
||||
{
|
||||
PutType( f, "%f" );
|
||||
PutType( f );
|
||||
}
|
||||
|
||||
inline void CUtlBuffer::PutDouble( double d )
|
||||
{
|
||||
PutType( d, "%f" );
|
||||
PutType( d );
|
||||
}
|
||||
|
||||
inline void CUtlBuffer::PutPtr( void *p )
|
||||
{
|
||||
// LEGACY WARNING: in text mode, PutPtr writes 32 bit pointers in hex, while GetPtr reads 32 or 64 bit pointers in decimal
|
||||
if (!IsText())
|
||||
{
|
||||
PutTypeBin( p );
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf( "0x%p", p );
|
||||
}
|
||||
// LEGACY WARNING: in text mode, PutPtr writes 32 bit pointers in hex, while GetPtr reads 32 or 64 bit pointers in decimal
|
||||
if (!IsText())
|
||||
{
|
||||
PutTypeBin( p );
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf( "0x%p", p );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Am I a text buffer?
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -1062,26 +1357,25 @@ inline bool CUtlBuffer::IsReadOnly() const
|
||||
//-----------------------------------------------------------------------------
|
||||
// Buffer base and size
|
||||
//-----------------------------------------------------------------------------
|
||||
inline const void* CUtlBuffer::Base() const
|
||||
{
|
||||
return m_Memory.Base();
|
||||
inline const void* CUtlBuffer::Base() const
|
||||
{
|
||||
return m_Memory.Base();
|
||||
}
|
||||
|
||||
inline void* CUtlBuffer::Base()
|
||||
{
|
||||
return m_Memory.Base();
|
||||
return m_Memory.Base();
|
||||
}
|
||||
|
||||
// Returns the base as a const char*, only valid in text mode.
|
||||
inline const char *CUtlBuffer::String() const
|
||||
inline const void* CUtlBuffer::String() const
|
||||
{
|
||||
Assert( IsText() );
|
||||
return reinterpret_cast<const char*>( m_Memory.Base() );
|
||||
}
|
||||
|
||||
inline int CUtlBuffer::Size() const
|
||||
{
|
||||
return m_Memory.NumAllocated();
|
||||
inline int CUtlBuffer::Size() const
|
||||
{
|
||||
return m_Memory.NumAllocated();
|
||||
}
|
||||
|
||||
|
||||
@@ -1095,7 +1389,7 @@ inline void CUtlBuffer::Clear()
|
||||
m_Error = 0;
|
||||
m_nOffset = 0;
|
||||
m_nMaxPut = -1;
|
||||
AddNullTermination();
|
||||
AddNullTermination( m_Put );
|
||||
}
|
||||
|
||||
inline void CUtlBuffer::Purge()
|
||||
@@ -1108,6 +1402,58 @@ inline void CUtlBuffer::Purge()
|
||||
m_Memory.Purge();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void *CUtlBuffer::AccessForDirectRead( int nBytes )
|
||||
{
|
||||
Assert( m_Get == 0 && m_Put == 0 && m_nMaxPut == 0 );
|
||||
EnsureCapacity( nBytes );
|
||||
m_nMaxPut = nBytes;
|
||||
return Base();
|
||||
}
|
||||
|
||||
inline void *CUtlBuffer::Detach()
|
||||
{
|
||||
void *p = m_Memory.Detach();
|
||||
Clear();
|
||||
return p;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
inline void CUtlBuffer::Spew( )
|
||||
{
|
||||
SeekGet( CUtlBuffer::SEEK_HEAD, 0 );
|
||||
|
||||
char pTmpLine[1024];
|
||||
while( IsValid() && GetBytesRemaining() )
|
||||
{
|
||||
V_memset( pTmpLine, 0, sizeof(pTmpLine) );
|
||||
Get( pTmpLine, MIN( ( size_t )GetBytesRemaining(), sizeof(pTmpLine)-1 ) );
|
||||
Msg( _T( "%s" ), pTmpLine );
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(_GAMECONSOLE)
|
||||
inline void CUtlBuffer::SwapCopy( CUtlBuffer &other )
|
||||
{
|
||||
m_Get = other.m_Get;
|
||||
m_Put = other.m_Put;
|
||||
m_Error = other.m_Error;
|
||||
m_Flags = other.m_Flags;
|
||||
m_Reserved = other.m_Reserved;
|
||||
m_nTab = other.m_nTab;
|
||||
m_nMaxPut = other.m_nMaxPut;
|
||||
m_nOffset = other.m_nOffset;
|
||||
m_GetOverflowFunc = other.m_GetOverflowFunc;
|
||||
m_PutOverflowFunc = other.m_PutOverflowFunc;
|
||||
m_Byteswap = other.m_Byteswap;
|
||||
|
||||
m_Memory.Swap( other.m_Memory );
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void CUtlBuffer::CopyBuffer( const CUtlBuffer &buffer )
|
||||
{
|
||||
CopyBuffer( buffer.Base(), buffer.TellPut() );
|
||||
|
||||
Reference in New Issue
Block a user