mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-05 03:24:56 +08:00
public: add Q_memfgets, replacement for COM_MemFgets rewritten using crtlib functions. Add a test
This commit is contained in:
@@ -776,7 +776,7 @@ void CL_InitClientMove( void )
|
||||
clgame.pmove->COM_FileSize = COM_FileSize;
|
||||
clgame.pmove->COM_LoadFile = COM_LoadFile;
|
||||
clgame.pmove->COM_FreeFile = COM_FreeFile;
|
||||
clgame.pmove->memfgets = COM_MemFgets;
|
||||
clgame.pmove->memfgets = Q_memfgets;
|
||||
clgame.pmove->PM_PlaySound = pfnPlaySound;
|
||||
clgame.pmove->PM_TraceTexture = PM_CL_TraceTexture;
|
||||
clgame.pmove->PM_PlaybackEventFull = pfnPlaybackEventFull;
|
||||
|
||||
@@ -227,7 +227,7 @@ client_textmessage_t *CL_TextMessageParse( poolhandle_t mempool, byte *pMemFile,
|
||||
lastLinePos = 0;
|
||||
messageCount = 0;
|
||||
|
||||
while( COM_MemFgets( pMemFile, fileSize, &filePos, buf, 512 ) != NULL )
|
||||
while( Q_memfgets( pMemFile, fileSize, &filePos, buf, 512 ) != NULL )
|
||||
{
|
||||
COM_TrimSpace( trim, buf, sizeof( trim ));
|
||||
|
||||
|
||||
@@ -597,7 +597,6 @@ void COM_HexConvert( const char *pszInput, int nInputLength, byte *pOutput )
|
||||
byte *p = pOutput;
|
||||
int i;
|
||||
|
||||
|
||||
for( i = 0; i < nInputLength; i += 2 )
|
||||
{
|
||||
pIn = &pszInput[i];
|
||||
@@ -606,59 +605,6 @@ void COM_HexConvert( const char *pszInput, int nInputLength, byte *pOutput )
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
COM_MemFgets
|
||||
|
||||
=============
|
||||
*/
|
||||
char *GAME_EXPORT COM_MemFgets( byte *pMemFile, int fileSize, int *filePos, char *pBuffer, int bufferSize )
|
||||
{
|
||||
int i, last, stop;
|
||||
|
||||
if( !pMemFile || !pBuffer || !filePos )
|
||||
return NULL;
|
||||
|
||||
if( *filePos >= fileSize )
|
||||
return NULL;
|
||||
|
||||
i = *filePos;
|
||||
last = fileSize;
|
||||
|
||||
// fgets always NULL terminates, so only read bufferSize-1 characters
|
||||
if( last - *filePos > ( bufferSize - 1 ))
|
||||
last = *filePos + ( bufferSize - 1);
|
||||
|
||||
stop = 0;
|
||||
|
||||
// stop at the next newline (inclusive) or end of buffer
|
||||
while( i < last && !stop )
|
||||
{
|
||||
if( pMemFile[i] == '\n' )
|
||||
stop = 1;
|
||||
i++;
|
||||
}
|
||||
|
||||
// if we actually advanced the pointer, copy it over
|
||||
if( i != *filePos )
|
||||
{
|
||||
// we read in size bytes
|
||||
int size = i - *filePos;
|
||||
|
||||
// copy it out
|
||||
memcpy( pBuffer, pMemFile + *filePos, size );
|
||||
|
||||
// If the buffer isn't full, terminate (this is always true)
|
||||
if( size < bufferSize ) pBuffer[size] = 0;
|
||||
|
||||
// update file pointer
|
||||
*filePos = i;
|
||||
return pBuffer;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
COM_LoadFileForMe
|
||||
|
||||
@@ -628,7 +628,6 @@ qboolean SV_Active( void );
|
||||
|
||||
==============================================================
|
||||
*/
|
||||
char *COM_MemFgets( byte *pMemFile, int fileSize, int *filePos, char *pBuffer, int bufferSize );
|
||||
void COM_HexConvert( const char *pszInput, int nInputLength, byte *pOutput );
|
||||
byte COM_Nibble( char c );
|
||||
int COM_SaveFile( const char *filename, const void *data, int len );
|
||||
|
||||
@@ -484,7 +484,7 @@ void SV_InitClientMove( void )
|
||||
svgame.pmove->COM_FileSize = COM_FileSize;
|
||||
svgame.pmove->COM_LoadFile = COM_LoadFile;
|
||||
svgame.pmove->COM_FreeFile = COM_FreeFile;
|
||||
svgame.pmove->memfgets = COM_MemFgets;
|
||||
svgame.pmove->memfgets = Q_memfgets;
|
||||
svgame.pmove->PM_PlaySound = pfnPlaySound;
|
||||
svgame.pmove->PM_TraceTexture = pfnTraceTexture;
|
||||
svgame.pmove->PM_PlaybackEventFull = pfnPlaybackEventFull;
|
||||
|
||||
@@ -22,6 +22,30 @@ GNU General Public License for more details.
|
||||
#include "xash3d_mathlib.h"
|
||||
#include "crtlib.h"
|
||||
|
||||
char *GAME_EXPORT Q_memfgets( byte *data, int data_len, int *data_offset, char *dst, int dst_size )
|
||||
{
|
||||
// sanity check
|
||||
if( !data || !data_offset || !dst || *data_offset >= data_len )
|
||||
return NULL;
|
||||
|
||||
const char *start = (const char *)data + *data_offset;
|
||||
int remaining = data_len - *data_offset;
|
||||
|
||||
// do not assume the data is null terminated, as we have data_len anyway :)
|
||||
const char *end = memchr( start, '\n', remaining );
|
||||
|
||||
if( end )
|
||||
remaining = end - start + 1;
|
||||
|
||||
// include null terminator
|
||||
Q_strncpy( dst, start, Q_min( remaining + 1, dst_size ));
|
||||
|
||||
*data_offset += remaining;
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
||||
void Q_strnlwr( const char *in, char *out, size_t size_out )
|
||||
{
|
||||
size_t len, i;
|
||||
|
||||
@@ -98,6 +98,7 @@ int Q_atoi_hex( int sign, const char *str );
|
||||
int Q_atoi( const char *str );
|
||||
float Q_atof( const char *str );
|
||||
void Q_atov( float *vec, const char *str, size_t siz );
|
||||
char *Q_memfgets( byte *data, int data_len, int *data_offset, char *dst, int dst_size );
|
||||
#define Q_strchr strchr
|
||||
#define Q_strrchr strrchr
|
||||
qboolean Q_stricmpext( const char *pattern, const char *text );
|
||||
|
||||
@@ -99,6 +99,47 @@ static int Test_TrimSpace( void )
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static int Test_memgets( qboolean include_null_terminator )
|
||||
{
|
||||
char data[] =
|
||||
"First line\n"
|
||||
"Second line\n"
|
||||
"Third line with long text\n"
|
||||
"Last line without newline";
|
||||
int data_len = sizeof( data ) - ( include_null_terminator ? 1 : 0 );
|
||||
string buffer;
|
||||
int data_offset = 0;
|
||||
int check_offset = sizeof( "First line\n" ) - 1;
|
||||
char *p;
|
||||
|
||||
p = Q_memfgets( data, data_len, &data_offset, buffer, sizeof( buffer ));
|
||||
if( !p || Q_strcmp( buffer, "First line\n" ) || data_offset != check_offset )
|
||||
return 1;
|
||||
|
||||
check_offset += sizeof( "Second line\n" ) - 1;
|
||||
p = Q_memfgets( data, data_len, &data_offset, buffer, sizeof( buffer ));
|
||||
if( !p || Q_strcmp( buffer, "Second line\n" ) || data_offset != check_offset )
|
||||
return 2;
|
||||
|
||||
check_offset += sizeof( "Third line with long text\n" ) - 1;
|
||||
p = Q_memfgets( data, data_len, &data_offset, buffer, sizeof( buffer ));
|
||||
if( !p || Q_strcmp( buffer, "Third line with long text\n" ) || data_offset != check_offset )
|
||||
return 3;
|
||||
|
||||
check_offset += sizeof( "Last line without newline" ) - ( include_null_terminator ? 1 : 0 );
|
||||
p = Q_memfgets( data, data_len, &data_offset, buffer, sizeof( buffer ));
|
||||
if( !p || Q_strcmp( buffer, "Last line without newline" ) || data_offset != check_offset )
|
||||
return 4;
|
||||
|
||||
p = Q_memfgets( data, data_len, &data_offset, buffer, sizeof( buffer ));
|
||||
if( p )
|
||||
return 5;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main( void )
|
||||
{
|
||||
int ret = Test_Strcpycatcmp();
|
||||
@@ -121,5 +162,15 @@ int main( void )
|
||||
if( ret > 0 )
|
||||
return ret + 48;
|
||||
|
||||
ret = Test_memgets( true );
|
||||
|
||||
if( ret > 0 )
|
||||
return ret + 64;
|
||||
|
||||
ret = Test_memgets( false );
|
||||
|
||||
if( ret > 0 )
|
||||
return ret + 64;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user