470 lines
9.3 KiB
C++
470 lines
9.3 KiB
C++
#include "global.h"
|
|
#include "RageLog.h"
|
|
#include "RageFile.h"
|
|
#include "RageUtil.h"
|
|
#include "RageUtil_FileDB.h"
|
|
#include "test_misc.h"
|
|
|
|
bool CreateTestFiles = false;
|
|
|
|
void CreateBinaryTestFile( RageFile &f, int size )
|
|
{
|
|
char c = 0;
|
|
while( size-- )
|
|
{
|
|
f.Write( ssprintf("%c", c) );
|
|
++c;
|
|
}
|
|
}
|
|
|
|
void CreateBinaryTestFile( RString fn, int size )
|
|
{
|
|
RageFile f;
|
|
f.Open( fn, RageFile::WRITE );
|
|
CreateBinaryTestFile( f, size );
|
|
f.Close();
|
|
|
|
if( !f.Open(fn) )
|
|
{
|
|
LOG->Warn("CreateBinaryTestFile: error reopening %s: %s", fn.c_str(), f.GetError().c_str() );
|
|
return;
|
|
}
|
|
|
|
int test = f.GetFileSize();
|
|
if( test != size )
|
|
LOG->Warn("CreateBinaryTestFile: f.GetFileSize ret %i, exp %i", test, size );
|
|
}
|
|
|
|
|
|
bool CheckData( const RString &buf, int offset )
|
|
{
|
|
char c = offset%256;
|
|
|
|
for( unsigned i = 0; i < buf.size(); ++i )
|
|
{
|
|
if( buf[i] != c )
|
|
return false;
|
|
++c;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
int TestBinaryRead( RageFile &test, int size, bool AllowEOF, int ExpectedFilePos, int TestDataPos )
|
|
{
|
|
char buf[4096];
|
|
ASSERT( size <= (int) sizeof(buf) );
|
|
int ret = test.Read( buf, size );
|
|
if( ret != size )
|
|
{
|
|
if( AllowEOF )
|
|
return 0;
|
|
LOG->Warn("FAIL");
|
|
return -1;
|
|
}
|
|
|
|
if( !CheckData( RString(buf, ret), TestDataPos ) )
|
|
{
|
|
LOG->Warn("TestBinaryRead: check failed (size %i, %i,%i)",
|
|
size, ExpectedFilePos, TestDataPos );
|
|
return -1;
|
|
}
|
|
|
|
if( test.Tell() != ExpectedFilePos+ret )
|
|
{
|
|
LOG->Warn( "Simple Tell() failed (got %i, expected %i)", test.Tell(), ret );
|
|
return -1;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
RString MakeTextTestLine( int line, int size )
|
|
{
|
|
RString ret = ssprintf( "%02i", line );
|
|
ret.append( RString( size-ret.size(), 'x' ) );
|
|
return ret;
|
|
}
|
|
|
|
bool CheckTextData( const RString &buf, int LineSize, int size )
|
|
{
|
|
return buf == MakeTextTestLine( LineSize, size );
|
|
}
|
|
|
|
void TestText( int LineSize, bool DOS )
|
|
{
|
|
const unsigned NumLines = 50;
|
|
|
|
RString filename = "test.text";
|
|
if( DOS )
|
|
filename += ".DOS";
|
|
filename += ssprintf( ".%i", LineSize );
|
|
if( CreateTestFiles )
|
|
{
|
|
RageFile f;
|
|
f.Open( filename, RageFile::WRITE );
|
|
|
|
for( unsigned line = 0; line < NumLines; ++line )
|
|
{
|
|
const RString TestLine = MakeTextTestLine( line, LineSize );
|
|
f.Write( TestLine );
|
|
if( DOS )
|
|
f.Write( "\r" );
|
|
f.Write( "\n" );
|
|
}
|
|
|
|
/* Write a binary test block at the end. */
|
|
CreateBinaryTestFile( f, 4096 );
|
|
|
|
/* Write a text line, with no NL. */
|
|
f.Write( "final" );
|
|
|
|
return;
|
|
}
|
|
|
|
RageFile test;
|
|
if( !test.Open(filename) )
|
|
{
|
|
LOG->Warn( "Open \"%s\" failed: %s", filename.c_str(), test.GetError().c_str() );
|
|
exit(1);
|
|
}
|
|
|
|
int ExpectedPos = 0;
|
|
for( unsigned line = 0; line < NumLines; ++line )
|
|
{
|
|
RString buf;
|
|
if( test.GetLine( buf ) <= 0 )
|
|
{
|
|
LOG->Warn("Text read failure, line %i, size %i, DOS %i",
|
|
line, LineSize, DOS );
|
|
return;
|
|
}
|
|
|
|
/* If we successfully got data, we should not be at EOF. */
|
|
if( test.AtEOF() )
|
|
{
|
|
LOG->Warn("Unexpected EOF in text read, line %i, size %i, DOS %i",
|
|
line, LineSize, DOS );
|
|
return;
|
|
}
|
|
|
|
if( !CheckTextData( buf, line, LineSize ) )
|
|
{
|
|
LOG->Warn("Text read check failure, line %i, size %i, DOS %i: '%s'",
|
|
line, LineSize, DOS, buf.c_str() );
|
|
return;
|
|
}
|
|
ExpectedPos += buf.size()+1;
|
|
if( DOS )
|
|
++ExpectedPos;
|
|
}
|
|
if( ExpectedPos != test.Tell() )
|
|
{
|
|
LOG->Warn("Text read pos failure, size %i, DOS %i: exp %i, got %i",
|
|
LineSize, DOS, ExpectedPos, test.Tell() );
|
|
return;
|
|
}
|
|
|
|
/* Test the binary block. Do it in a couple reads, to force it to read from
|
|
* the buffer and the file more than once. */
|
|
TestBinaryRead( test, 1024, true, test.Tell(), 1024*0 );
|
|
TestBinaryRead( test, 1024, true, test.Tell(), 1024*1 );
|
|
TestBinaryRead( test, 1024, true, test.Tell(), 1024*2 );
|
|
TestBinaryRead( test, 1024, true, test.Tell(), 1024*3 );
|
|
|
|
{
|
|
RString buf;
|
|
if( test.GetLine( buf ) <= 0 )
|
|
{
|
|
LOG->Warn( "Unexpected EOF in final line read, DOS %i", DOS );
|
|
return;
|
|
}
|
|
|
|
if( buf != "final" )
|
|
{
|
|
LOG->Warn( "Final text read check failure, DOS %i: '%s'",
|
|
DOS, buf.c_str() );
|
|
return;
|
|
}
|
|
if( test.AtEOF() )
|
|
{
|
|
LOG->Warn( "Unexpected EOF (2) in final text read, DOS %i", DOS );
|
|
return;
|
|
}
|
|
}
|
|
|
|
{
|
|
RString buf;
|
|
if( test.GetLine( buf ) != 0 )
|
|
{
|
|
LOG->Warn( "Expected EOF in final text read, but didn't get it" );
|
|
return;
|
|
}
|
|
|
|
if( !test.AtEOF() )
|
|
{
|
|
LOG->Warn( "Expected EOF (2) in final text read, but didn't get it" );
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void TestText()
|
|
{
|
|
/* Test with these line sizes. The internal buffer size is 256, so test line sizes
|
|
* around there carefully. */
|
|
int sizes[] = {
|
|
4,
|
|
7,
|
|
100,
|
|
200,
|
|
254,
|
|
255,
|
|
256,
|
|
257,
|
|
258,
|
|
500,
|
|
-1
|
|
};
|
|
|
|
for( int s = 0; sizes[s] != -1; ++s )
|
|
{
|
|
TestText( sizes[s], false );
|
|
TestText( sizes[s], true );
|
|
}
|
|
}
|
|
|
|
void TestSeek( bool relative )
|
|
{
|
|
const RString TestLine = "Hello World\n";
|
|
/* Print a couple kb of text. Make sure this is big enough that the binary
|
|
* test data after it won't start in the buffer; if that happens, the seek
|
|
* will be optimized out. */
|
|
RString junk;
|
|
for( int lines = 0; lines < 128; ++lines )
|
|
junk += "XXXXXXXXX\n";
|
|
|
|
if( CreateTestFiles )
|
|
{
|
|
/* Output a line of text, followed by some junk, followed by binary
|
|
* test data. */
|
|
RageFile f;
|
|
f.Open( "test.seek", RageFile::WRITE );
|
|
f.Write( TestLine );
|
|
f.Write( junk );
|
|
CreateBinaryTestFile( f, 1024 );
|
|
return;
|
|
}
|
|
|
|
/* Read the line of text. This will result in some of the junk being
|
|
* read into the buffer. */
|
|
RageFile test;
|
|
test.Open("test.seek");
|
|
RString line;
|
|
test.GetLine( line );
|
|
|
|
/* Run the absolute seek test twice. */
|
|
for( int pass = 0; pass < 2; ++pass )
|
|
{
|
|
/* Seek to the binary test data. */
|
|
if( relative && pass > 0 )
|
|
break;
|
|
|
|
int ret;
|
|
if( relative )
|
|
ret = test.Seek( test.Tell() + junk.size() );
|
|
else
|
|
ret = test.Seek( TestLine.size()+junk.size() );
|
|
|
|
if( ret != int(TestLine.size()+junk.size()) )
|
|
{
|
|
LOG->Warn( "Seek(%i) failed: got %i", TestLine.size()+junk.size(), ret );
|
|
return;
|
|
}
|
|
|
|
/* Check the binary test data (making sure we don't get any junk). */
|
|
TestBinaryRead( test, 256, false, test.Tell(), 256*0 );
|
|
TestBinaryRead( test, 256, false, test.Tell(), 256*1 );
|
|
TestBinaryRead( test, 256, false, test.Tell(), 256*2 );
|
|
TestBinaryRead( test, 256, false, test.Tell(), 256*3 );
|
|
|
|
/* Check EOF. */
|
|
char c;
|
|
ret = test.Read( &c, 1 );
|
|
if( ret != 0 )
|
|
{
|
|
LOG->Warn( "Read(1) failed: got %i, expected 0", ret );
|
|
return;
|
|
}
|
|
if( !test.AtEOF() )
|
|
{
|
|
LOG->Warn( "AtEOF returned false, expected true");
|
|
return;
|
|
}
|
|
}
|
|
|
|
test.Seek( 5 );
|
|
if( test.AtEOF() )
|
|
{
|
|
LOG->Warn( "AtEOF returned true, expected false");
|
|
return;
|
|
}
|
|
|
|
/* Make sure a read after seeking far past EOF returns 0. */
|
|
test.Seek( 9999999 );
|
|
char c;
|
|
int ret = test.Read( &c, 1 );
|
|
if( ret != 0 )
|
|
{
|
|
LOG->Warn( "Read(1) failed: got %i, expected 0", ret );
|
|
return;
|
|
}
|
|
if( !test.AtEOF() )
|
|
{
|
|
LOG->Warn( "AtEOF returned false, expected true");
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#include "RageFileDriverMemory.h"
|
|
#include "RageFileDriverDeflate.h"
|
|
void CheckDeflate( RageFileObjMem &data, int iSize, unsigned iInputCRC, int iBlockSize )
|
|
{
|
|
data.Seek(0);
|
|
|
|
RString foo2;
|
|
|
|
RageFileObjInflate infl( &data, iSize );
|
|
infl.EnableCRC32();
|
|
int iGot = 0;
|
|
while( iGot < iSize )
|
|
{
|
|
int iRet = infl.Read( foo2, iBlockSize );
|
|
if( iRet == 0 )
|
|
{
|
|
LOG->Warn( "Premature EOF (iSize %i, iBlockSize %i)", iSize, iBlockSize );
|
|
return;
|
|
}
|
|
|
|
iGot += iRet;
|
|
}
|
|
|
|
unsigned iOutputCRC;
|
|
if( !infl.GetCRC32(&iOutputCRC) )
|
|
{
|
|
LOG->Warn( "Inflate GetCRC32 failed" );
|
|
return;
|
|
}
|
|
if( iInputCRC != iOutputCRC )
|
|
{
|
|
LOG->Warn( "Expected CRC %08x, got %08x", iInputCRC, iOutputCRC );
|
|
return;
|
|
}
|
|
|
|
if( iSize != iGot )
|
|
{
|
|
LOG->Warn( "Expected %i, got %i", iSize, iGot );
|
|
return;
|
|
}
|
|
}
|
|
|
|
void TestDeflate()
|
|
{
|
|
RageFileObjMem data;
|
|
RageFileObjDeflate defl( &data );
|
|
defl.EnableCRC32();
|
|
|
|
int iSize = 0;
|
|
while( iSize < 1024*512 )
|
|
iSize += defl.Write("test foo bar fah");
|
|
defl.Flush();
|
|
|
|
unsigned iOutputCRC;
|
|
if( !defl.GetCRC32(&iOutputCRC) )
|
|
{
|
|
LOG->Warn( "Deflate GetCRC32 failed" );
|
|
return;
|
|
}
|
|
|
|
CheckDeflate( data, iSize, iOutputCRC, 1 );
|
|
CheckDeflate( data, iSize, iOutputCRC, 1024 );
|
|
CheckDeflate( data, iSize, iOutputCRC, 1024*4 );
|
|
CheckDeflate( data, iSize, iOutputCRC, iSize-1 );
|
|
CheckDeflate( data, iSize, iOutputCRC, iSize );
|
|
}
|
|
|
|
int main( int argc, char *argv[] )
|
|
{
|
|
test_handle_args( argc, argv );
|
|
|
|
optind = 0; // force getopt to reset
|
|
while( 1 )
|
|
{
|
|
opterr = 0;
|
|
int opt = getopt( argc, argv, "c" );
|
|
if( opt == -1 )
|
|
break;
|
|
switch( opt )
|
|
{
|
|
case 'c':
|
|
CreateTestFiles = true;
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
test_init();
|
|
|
|
if( GetCommandlineArgument("zlib") )
|
|
{
|
|
TestDeflate();
|
|
test_deinit();
|
|
return 0;
|
|
}
|
|
|
|
if( CreateTestFiles )
|
|
CreateBinaryTestFile( "test.binary", 4096 );
|
|
else
|
|
{
|
|
/* Test binary reading. */
|
|
RageFile test;
|
|
if( !test.Open("test.binary") )
|
|
{
|
|
LOG->Warn( "Open \"test.binary\" failed: %s", test.GetError().c_str() );
|
|
exit(1);
|
|
}
|
|
|
|
TestBinaryRead( test, 256, false, 0, 0 );
|
|
|
|
/* Test simple re-opening. */
|
|
test.Close();
|
|
test.Open("test.binary");
|
|
|
|
/* We should now be back at 0. */
|
|
if( test.Tell() != 0 )
|
|
{
|
|
LOG->Warn( "Simple Tell() after reopen failed (got %i, expected 0)", test.Tell() );
|
|
exit(1);
|
|
}
|
|
|
|
/* Test reading further, with various block sizes. */
|
|
while( 1 )
|
|
{
|
|
if( TestBinaryRead( test, 85, true, test.Tell(), test.Tell() ) == 0 )
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* Test text reading. */
|
|
TestText();
|
|
|
|
/* Test seeking. */
|
|
TestSeek( true );
|
|
TestSeek( false );
|
|
|
|
test_deinit();
|
|
|
|
exit(0);
|
|
}
|
|
|