initial
This commit is contained in:
421
tracker/common/msgbuffer.cpp
Normal file
421
tracker/common/msgbuffer.cpp
Normal file
@@ -0,0 +1,421 @@
|
||||
//========= Copyright © 1996-2001, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "msgbuffer.h"
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include <tier0/memdbgon.h>
|
||||
|
||||
#pragma warning(disable: 4244) // warning C4244: '=' : conversion from 'int' to 'unsigned char', possible loss of data
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Allocate message buffer
|
||||
// Input : *buffername -
|
||||
// *ef -
|
||||
//-----------------------------------------------------------------------------
|
||||
CMsgBuffer::CMsgBuffer( const char *buffername, void (*ef)( PRINTF_FORMAT_STRING const char *fmt, ... ) /*= NULL*/ )
|
||||
{
|
||||
m_pszBufferName = buffername;
|
||||
m_pfnErrorFunc = ef;
|
||||
m_bAllowOverflow = false; // if false, Error
|
||||
m_bOverFlowed = false; // set to true if the buffer size failed
|
||||
m_nMaxSize = NET_MAXMESSAGE;
|
||||
m_nPushedCount = 0;
|
||||
m_bPushed = false;
|
||||
m_nReadCount = 0;
|
||||
m_bBadRead = false;
|
||||
|
||||
Clear();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CMsgBuffer::~CMsgBuffer( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Temporarily remember the read position so we can reset it
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMsgBuffer::Push( void )
|
||||
{
|
||||
// ??? Allow multiple pushes without matching pops ???
|
||||
assert( !m_bPushed );
|
||||
|
||||
m_nPushedCount = m_nReadCount;
|
||||
m_bPushed = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMsgBuffer::Pop( void )
|
||||
{
|
||||
assert( m_bPushed );
|
||||
|
||||
m_nReadCount = m_nPushedCount;
|
||||
m_bPushed = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : allowed -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMsgBuffer::SetOverflow( bool allowed )
|
||||
{
|
||||
m_bAllowOverflow = allowed;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int CMsgBuffer::GetMaxSize( void )
|
||||
{
|
||||
return m_nMaxSize;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : void *
|
||||
//-----------------------------------------------------------------------------
|
||||
void * CMsgBuffer::GetData( void )
|
||||
{
|
||||
return m_rgData;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int CMsgBuffer::GetCurSize( void )
|
||||
{
|
||||
return m_nCurSize;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int CMsgBuffer::GetReadCount( void )
|
||||
{
|
||||
return m_nReadCount;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMsgBuffer::SetTime(float time)
|
||||
{
|
||||
m_fRecvTime = time;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
float CMsgBuffer::GetTime()
|
||||
{
|
||||
return m_fRecvTime;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMsgBuffer::SetNetAddress(netadr_t &adr)
|
||||
{
|
||||
m_NetAddr = adr;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
netadr_t &CMsgBuffer::GetNetAddress()
|
||||
{
|
||||
return m_NetAddr;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMsgBuffer::WriteByte( int c )
|
||||
{
|
||||
unsigned char *buf;
|
||||
buf = (unsigned char *)GetSpace( 1 );
|
||||
buf[0] = c;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : c -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMsgBuffer::WriteShort ( int c )
|
||||
{
|
||||
unsigned char *buf;
|
||||
buf = (unsigned char *)GetSpace( 2 );
|
||||
buf[0] = c&0xff;
|
||||
buf[1] = c>>8;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : c -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMsgBuffer::WriteLong (int c)
|
||||
{
|
||||
unsigned char *buf;
|
||||
|
||||
buf = (unsigned char *)GetSpace( 4 );
|
||||
buf[0] = c&0xff;
|
||||
buf[1] = (c>>8)&0xff;
|
||||
buf[2] = (c>>16)&0xff;
|
||||
buf[3] = c>>24;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : f -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMsgBuffer::WriteFloat (float f)
|
||||
{
|
||||
union
|
||||
{
|
||||
float f;
|
||||
int l;
|
||||
} dat;
|
||||
|
||||
dat.f = f;
|
||||
Write( &dat.l, 4 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *s -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMsgBuffer::WriteString (const char *s)
|
||||
{
|
||||
if ( !s )
|
||||
{
|
||||
Write ("", 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
Write ( s, strlen( s ) + 1 );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : iSize -
|
||||
// *buf -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMsgBuffer::WriteBuf( int iSize, void *buf )
|
||||
{
|
||||
if ( !buf )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Write( buf, iSize );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMsgBuffer::BeginReading (void)
|
||||
{
|
||||
m_nReadCount = 0;
|
||||
m_bBadRead = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : int CMsgBuffer::ReadByte
|
||||
//-----------------------------------------------------------------------------
|
||||
int CMsgBuffer::ReadByte (void)
|
||||
{
|
||||
int c;
|
||||
|
||||
if ( m_nReadCount + 1 > m_nCurSize )
|
||||
{
|
||||
m_bBadRead = true;
|
||||
return -1;
|
||||
}
|
||||
|
||||
c = ( unsigned char )m_rgData[ m_nReadCount ];
|
||||
m_nReadCount++;
|
||||
return c;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : int CMsgBuffer::ReadShort
|
||||
//-----------------------------------------------------------------------------
|
||||
int CMsgBuffer::ReadShort (void)
|
||||
{
|
||||
int c;
|
||||
|
||||
if ( m_nReadCount + 2 > m_nCurSize )
|
||||
{
|
||||
m_bBadRead = true;
|
||||
return -1;
|
||||
}
|
||||
|
||||
c = (short)(m_rgData[m_nReadCount] + (m_rgData[m_nReadCount+1]<<8));
|
||||
m_nReadCount += 2;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : int CMsgBuffer::ReadLong
|
||||
//-----------------------------------------------------------------------------
|
||||
int CMsgBuffer::ReadLong (void)
|
||||
{
|
||||
int c;
|
||||
|
||||
if (m_nReadCount+4 > m_nCurSize)
|
||||
{
|
||||
m_bBadRead = true;
|
||||
return -1;
|
||||
}
|
||||
|
||||
c = m_rgData[m_nReadCount]
|
||||
+ (m_rgData[m_nReadCount+1]<<8)
|
||||
+ (m_rgData[m_nReadCount+2]<<16)
|
||||
+ (m_rgData[m_nReadCount+3]<<24);
|
||||
|
||||
m_nReadCount += 4;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : float CMsgBuffer::ReadFloat
|
||||
//-----------------------------------------------------------------------------
|
||||
float CMsgBuffer::ReadFloat (void)
|
||||
{
|
||||
union
|
||||
{
|
||||
unsigned char b[4];
|
||||
float f;
|
||||
} dat;
|
||||
|
||||
dat.b[0] = m_rgData[m_nReadCount];
|
||||
dat.b[1] = m_rgData[m_nReadCount+1];
|
||||
dat.b[2] = m_rgData[m_nReadCount+2];
|
||||
dat.b[3] = m_rgData[m_nReadCount+3];
|
||||
m_nReadCount += 4;
|
||||
return dat.f;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : iSize -
|
||||
// *pbuf -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int CMsgBuffer::ReadBuf( int iSize, void *pbuf )
|
||||
{
|
||||
if (m_nReadCount + iSize > m_nCurSize)
|
||||
{
|
||||
m_bBadRead = true;
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy( pbuf, &m_rgData[m_nReadCount], iSize );
|
||||
m_nReadCount += iSize;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : char *
|
||||
//-----------------------------------------------------------------------------
|
||||
char *CMsgBuffer::ReadString (void)
|
||||
{
|
||||
static char string[ NET_MAXMESSAGE ];
|
||||
int l,c;
|
||||
|
||||
l = 0;
|
||||
do
|
||||
{
|
||||
c = (char)ReadByte();
|
||||
if ( c == -1 || c == 0 )
|
||||
break;
|
||||
string[l] = c;
|
||||
l++;
|
||||
} while ( l < sizeof(string)-1 );
|
||||
|
||||
string[ l ] = 0;
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMsgBuffer::Clear( void )
|
||||
{
|
||||
m_nCurSize = 0;
|
||||
m_bOverFlowed = false;
|
||||
m_nReadCount = 0;
|
||||
m_bBadRead = false;
|
||||
memset( m_rgData, 0, sizeof( m_rgData ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : length -
|
||||
//-----------------------------------------------------------------------------
|
||||
void *CMsgBuffer::GetSpace( int length )
|
||||
{
|
||||
void *d;
|
||||
|
||||
if (m_nCurSize + length > m_nMaxSize)
|
||||
{
|
||||
if ( !m_bAllowOverflow )
|
||||
{
|
||||
if ( m_pfnErrorFunc )
|
||||
{
|
||||
( *m_pfnErrorFunc )( "CMsgBuffer(%s), no room for %i bytes, %i / %i already in use\n",
|
||||
m_pszBufferName, length, m_nCurSize, m_nMaxSize );
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (length > m_nMaxSize)
|
||||
{
|
||||
if ( m_pfnErrorFunc )
|
||||
{
|
||||
( *m_pfnErrorFunc )( "CMsgBuffer(%s), no room for %i bytes, %i is max\n",
|
||||
m_pszBufferName, length, m_nMaxSize );
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
m_bOverFlowed = true;
|
||||
Clear();
|
||||
}
|
||||
|
||||
d = m_rgData + m_nCurSize;
|
||||
m_nCurSize += length;
|
||||
return d;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *m_rgData -
|
||||
// length -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMsgBuffer::Write(const void *m_rgData, int length)
|
||||
{
|
||||
memcpy( GetSpace(length), m_rgData, length );
|
||||
}
|
||||
108
tracker/common/msgbuffer.h
Normal file
108
tracker/common/msgbuffer.h
Normal file
@@ -0,0 +1,108 @@
|
||||
//========= Copyright © 1996-2001, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
#if !defined( MSGBUFFER_H )
|
||||
#define MSGBUFFER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "netadr.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Generic byte level message buffer with read/write support
|
||||
//-----------------------------------------------------------------------------
|
||||
class CMsgBuffer
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
NET_MAXMESSAGE = 8192
|
||||
};
|
||||
|
||||
// Buffers must be named
|
||||
CMsgBuffer( const char *buffername = "unnamed", void (*ef)( const char *fmt, ... ) = 0 );
|
||||
virtual ~CMsgBuffer( void );
|
||||
|
||||
// Reset the buffer for writing
|
||||
void Clear( void );
|
||||
// Get current # of bytes
|
||||
int GetCurSize( void );
|
||||
// Get max # of bytes
|
||||
int GetMaxSize( void );
|
||||
// Get pointer to raw data
|
||||
void *GetData( void );
|
||||
// Set/unset the allow overflow flag
|
||||
void SetOverflow( bool allowed );
|
||||
// Start reading from buffer
|
||||
void BeginReading( void );
|
||||
// Get current read byte
|
||||
int GetReadCount( void );
|
||||
|
||||
// Push read count ( to peek at data )
|
||||
void Push( void );
|
||||
void Pop( void );
|
||||
|
||||
// Writing functions
|
||||
void WriteByte(int c);
|
||||
void WriteShort(int c);
|
||||
void WriteLong(int c);
|
||||
void WriteFloat(float f);
|
||||
void WriteString(const char *s);
|
||||
void WriteBuf( int iSize, void *buf );
|
||||
|
||||
// Reading functions
|
||||
int ReadByte( void );
|
||||
int ReadShort( void );
|
||||
int ReadLong( void );
|
||||
float ReadFloat( void );
|
||||
char *ReadString( void );
|
||||
int ReadBuf( int iSize, void *pbuf );
|
||||
|
||||
// setting and storing time received
|
||||
void SetTime(float time);
|
||||
float GetTime();
|
||||
|
||||
// net address received from
|
||||
void SetNetAddress(netadr_t &adr);
|
||||
netadr_t &GetNetAddress();
|
||||
|
||||
private:
|
||||
// Ensures sufficient space to append an object of length
|
||||
void *GetSpace( int length );
|
||||
// Copy buffer in at current writing point
|
||||
void Write( const void *data, int length );
|
||||
|
||||
private:
|
||||
// Name of buffer in case of debugging/errors
|
||||
const char *m_pszBufferName;
|
||||
// Optional error callback
|
||||
void ( *m_pfnErrorFunc )( const char *fmt, ... );
|
||||
|
||||
// Current read pointer
|
||||
int m_nReadCount;
|
||||
// Push/pop read state
|
||||
int m_nPushedCount;
|
||||
bool m_bPushed;
|
||||
// Did we hit the end of the read buffer?
|
||||
bool m_bBadRead;
|
||||
// Max size of buffer
|
||||
int m_nMaxSize;
|
||||
// Current bytes written
|
||||
int m_nCurSize;
|
||||
// if false, call m_pfnErrorFunc
|
||||
bool m_bAllowOverflow;
|
||||
// set to true when buffer hits end
|
||||
bool m_bOverFlowed;
|
||||
// Internal storage
|
||||
unsigned char m_rgData[ NET_MAXMESSAGE ];
|
||||
// time received
|
||||
float m_fRecvTime;
|
||||
// address received from
|
||||
netadr_t m_NetAddr;
|
||||
};
|
||||
|
||||
#endif // !MSGBUFFER_H
|
||||
Reference in New Issue
Block a user