From b03207d6f59125aa9c7517792b712bb9f3237a5e Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Sun, 12 Dec 2004 04:38:17 +0000 Subject: [PATCH] automatic crc32 calc; a couple extra helpers --- stepmania/src/RageFile.cpp | 36 +++++++++++++++++++++++++++++ stepmania/src/RageFile.h | 5 +++++ stepmania/src/RageFileBasic.cpp | 40 +++++++++++++++++++++++++++++++++ stepmania/src/RageFileBasic.h | 12 ++++++++++ 4 files changed, 93 insertions(+) diff --git a/stepmania/src/RageFile.cpp b/stepmania/src/RageFile.cpp index f6f759356e..f653b19751 100644 --- a/stepmania/src/RageFile.cpp +++ b/stepmania/src/RageFile.cpp @@ -97,6 +97,19 @@ int RageFile::PutLine( const CString &str ) return m_File->PutLine( str ); } +void RageFile::EnableCRC32( bool on ) +{ + ASSERT_OPEN; + m_File->EnableCRC32( on ); +} + +bool RageFile::GetCRC32( unsigned *iRet ) +{ + ASSERT_OPEN; + return m_File->GetCRC32( iRet ); +} + + bool RageFile::AtEOF() const { ASSERT_READ; @@ -203,6 +216,29 @@ void FileReading::ReadBytes( RageFileBasic &f, void *buf, int size, CString &sEr sError = "Unexpected end of file"; } +void FileReading::SkipBytes( RageFileBasic &f, int iBytes, CString &sError ) +{ + if( sError.size() != 0 ) + return; + + iBytes += f.Tell(); + FileReading::Seek( f, iBytes, sError ); +} + +void FileReading::Seek( RageFileBasic &f, int iOffset, CString &sError ) +{ + if( sError.size() != 0 ) + return; + + int iGot = f.Seek( iOffset ); + if( iGot == iOffset ) + return; + if( iGot == -1 ) + sError = f.GetError(); + else if( iGot < iOffset ) + sError = "Unexpected end of file"; +} + uint8_t FileReading::read_8( RageFileBasic &f, CString &sError ) { uint8_t val; diff --git a/stepmania/src/RageFile.h b/stepmania/src/RageFile.h index f19607c487..bb79a10836 100644 --- a/stepmania/src/RageFile.h +++ b/stepmania/src/RageFile.h @@ -68,6 +68,9 @@ public: int GetLine( CString &out ); int PutLine( const CString &str ); + void EnableCRC32( bool on=true ); + bool GetCRC32( unsigned *iRet ); + protected: void SetError( const CString &err ); @@ -84,6 +87,8 @@ namespace FileReading /* On error, these set sError to the error message. If sError is already * non-empty, nothing happens. */ void ReadBytes( RageFileBasic &f, void *buf, int size, CString &sError ); + void SkipBytes( RageFileBasic &f, int size, CString &sError ); + void Seek( RageFileBasic &f, int iOffset, CString &sError ); uint8_t read_8( RageFileBasic &f, CString &sError ); int16_t read_16_le( RageFileBasic &f, CString &sError ); uint16_t read_u16_le( RageFileBasic &f, CString &sError ); diff --git a/stepmania/src/RageFileBasic.cpp b/stepmania/src/RageFileBasic.cpp index 9e67010e1b..8a1a6c09e2 100644 --- a/stepmania/src/RageFileBasic.cpp +++ b/stepmania/src/RageFileBasic.cpp @@ -11,6 +11,8 @@ RageFileObj::RageFileObj() m_iBufAvail = 0; m_bEOF = false; m_iFilePos = 0; + m_bCRC32Enabled = false; + m_iCRC32 = 0; } RageFileObj::~RageFileObj() @@ -27,6 +29,9 @@ int RageFileObj::Seek( int iOffset ) m_bEOF = false; + /* If we're calculating a CRC32, disable it. */ + m_bCRC32Enabled = false; + ResetBuf(); int iPos = SeekInternal( iOffset ); @@ -58,6 +63,8 @@ int RageFileObj::Read( void *pBuffer, size_t iBytes ) /* Copy data out of the buffer first. */ int iFromBuffer = min( (int) iBytes, m_iBufAvail ); memcpy( pBuffer, m_pBuf, iFromBuffer ); + if( m_bCRC32Enabled ) + CRC32( m_iCRC32, pBuffer, iFromBuffer ); ret += iFromBuffer; m_iFilePos += iFromBuffer; @@ -85,6 +92,9 @@ int RageFileObj::Read( void *pBuffer, size_t iBytes ) if( iFromFile == 0 ) m_bEOF = true; + + if( m_bCRC32Enabled ) + CRC32( m_iCRC32, pBuffer, iFromFile ); ret += iFromFile; m_iFilePos += iFromFile; return ret; @@ -147,7 +157,11 @@ int RageFileObj::Write( const void *pBuffer, size_t iBytes ) { int iRet = WriteInternal( pBuffer, iBytes ); if( iRet != -1 ) + { m_iFilePos += iRet; + if( m_bCRC32Enabled ) + CRC32( m_iCRC32, pBuffer, iBytes ); + } return iRet; } @@ -172,6 +186,32 @@ void RageFileObj::EnableBuffering() m_pBuffer = new char[BSIZE]; } +void RageFileObj::EnableCRC32( bool on ) +{ + if( !on ) + { + m_bCRC32Enabled = false; + return; + } + + /* If we're not at the beginning of the file, it's meaningless to start + * calculating a CRC32 now. */ + if( m_iFilePos != 0 ) + return; + + m_bCRC32Enabled = true; + m_iCRC32 = 0; +} + +bool RageFileObj::GetCRC32( unsigned *iRet ) +{ + if( !m_bCRC32Enabled ) + return false; + + *iRet = m_iCRC32; + return true; +} + /* Read up to the next \n, and return it in out. Strip the \n. If the \n is * preceded by a \r (DOS newline), strip that, too. */ int RageFileObj::GetLine( CString &out ) diff --git a/stepmania/src/RageFileBasic.h b/stepmania/src/RageFileBasic.h index fb0abd767a..f038aeb507 100644 --- a/stepmania/src/RageFileBasic.h +++ b/stepmania/src/RageFileBasic.h @@ -49,6 +49,9 @@ public: virtual int GetLine( CString &out ) = 0; virtual int PutLine( const CString &str ) = 0; + virtual void EnableCRC32( bool on=true ) = 0; + virtual bool GetCRC32( unsigned *iRet ) = 0; + virtual int GetFileSize() const = 0; }; @@ -80,6 +83,9 @@ public: int GetLine( CString &out ); int PutLine( const CString &str ); + void EnableCRC32( bool on=true ); + bool GetCRC32( unsigned *iRet ); + virtual int GetFileSize() const = 0; virtual CString GetDisplayPath() const { return ""; } virtual RageFileBasic *Copy() const { FAIL_M( "Copying unimplemented" ); } @@ -123,6 +129,12 @@ private: char *m_pBuffer; char *m_pBuf; int m_iBufAvail; + + /* If EnableCRC32() is called, a CRC32 will be calculated as the file is read. + * This is only meaningful if EnableCRC32() is called at the very start of the + * file, and no seeking is performed. */ + bool m_bCRC32Enabled; + unsigned m_iCRC32; }; #endif