📄 compressedfile.cpp
字号:
// CompressedFile.cpp
#include "stdafx.h"
#include "CompressedFile.h"
CCompressedFile::CCompressedFile( int nType )
{
m_bOpened = m_bCanRead = m_bCanWrite = FALSE;
m_nCompressionType = nType;
m_pBuffer = NULL;
}
CCompressedFile::~CCompressedFile()
{
if( m_bOpened ) Close();
if( m_pBuffer != NULL ) delete [] m_pBuffer;
}
BOOL CCompressedFile::Open( const char *pszFileName, unsigned int nOpenFlags, CFileException *pError )
{
if( m_pBuffer != NULL ) delete [] m_pBuffer;
m_pBuffer = (unsigned char *) new unsigned char [BUFFERSIZE];
if( m_pBuffer && ( nOpenFlags == CFile::modeRead || nOpenFlags == ( CFile::modeWrite | CFile::modeCreate ) || nOpenFlags == CFile::modeWrite ) ){
if( nOpenFlags == CFile::modeRead || nOpenFlags == CFile::modeWrite) m_nCompressionType = FileType( (char *) pszFileName );
strcpy( m_szFilename, pszFileName );
m_dwCompressedSize = m_dwUncompressedSize = 0L;
m_dwSeekTo = SIGNATURE_LENGTH;
m_nFlags = nOpenFlags;
m_dwBytesInBuffer = m_dwBufferPointer = m_dwFileLength = m_dwFilePointer = 0L;
if( !CFile::Open( pszFileName, nOpenFlags, pError ) ) return( FALSE );
m_dwFileLength = CFile::GetLength();
if( nOpenFlags == CFile::modeWrite ){
m_dwSeekTo = m_dwFilePointer = CFile::SeekToEnd();
CFile::Write( &m_dwUncompressedSize, sizeof( DWORD ) );
CFile::Write( &m_dwCompressedSize, sizeof( DWORD ) );
m_dwFilePointer += 8L;
}
else if( nOpenFlags != ( CFile::modeCreate | CFile::modeWrite ) ){
if( m_nCompressionType >= 0 ){
CFile::Seek( SIGNATURE_LENGTH, CFile::begin );
CFile::Read( &m_dwUncompressedSize, sizeof( DWORD ) );
CFile::Read( &m_dwCompressedSize, sizeof( DWORD ) );
}
else{
m_dwUncompressedSize = m_dwCompressedSize = CFile::GetLength();
}
}
else{
if( m_nCompressionType >= 0 ){
CFile::Write( szSignatures[m_nCompressionType], SIGNATURE_LENGTH );
CFile::Write( &m_dwUncompressedSize, sizeof( DWORD ) );
CFile::Write( &m_dwCompressedSize, sizeof( DWORD ) );
}
}
m_bOpened = TRUE;
if( nOpenFlags == CFile::modeRead ) m_bCanRead = TRUE;
else m_bCanWrite = TRUE;
m_nRack = m_nPacifierCount = 0;
m_nMask = 0x0080;
return( TRUE );
}
if( m_pBuffer != NULL ) delete [] m_pBuffer;
m_pBuffer = NULL;
return( FALSE );
}
void CCompressedFile::Close( void )
{
if( !m_bOpened ) return;
// If a buffer has been allocated, we may have some
// bytes we need to write to disk.
if( m_pBuffer != NULL ){
if( m_dwBytesInBuffer && ( m_nFlags == CFile::modeWrite || m_nFlags == ( CFile::modeWrite | CFile::modeCreate ) )) CFile::Write( m_pBuffer, (unsigned int) m_dwBytesInBuffer );
delete [] m_pBuffer;
m_pBuffer = NULL;
}
CFile::Close();
m_bOpened = FALSE;
}
unsigned int CCompressedFile::ReadBytes( void *lpBuf, unsigned int nCount )
{
if( !m_bOpened || !m_bCanRead ) return( 0 );
if( m_pBuffer != NULL ){
unsigned int nBytesRead = 0;
// We got a void, so we need to point an unsigned
// char pointer to the buffer in order to get the data.
unsigned char *pTransfer = (unsigned char *) lpBuf;
for( unsigned int i=0; i<nCount; i++ ){
// If we have data in the buffer, go to buffer and get it.
if( m_dwBytesInBuffer ){
*pTransfer++ = m_pBuffer[m_dwBufferPointer++];
m_dwBytesInBuffer--;
nBytesRead++;
}
// If there's no data in the buffer, read up to
// BUFFERSIZE bytes from disk and update m_dwBytesInBuffer
else{
DWORD dwBytesLeft = m_dwFileLength - m_dwFilePointer;
if( dwBytesLeft >= BUFFERSIZE ){
m_dwBytesInBuffer = CFile::Read( m_pBuffer, BUFFERSIZE );
m_dwFilePointer += BUFFERSIZE;
m_dwBufferPointer = 0;
}
else{
m_dwBytesInBuffer = CFile::Read( m_pBuffer, (int) dwBytesLeft );
m_dwFilePointer += (DWORD) m_dwBytesInBuffer;
m_dwBufferPointer = 0;
}
// Now that we've read in the data, get the byte.
*pTransfer++ = m_pBuffer[m_dwBufferPointer++];
m_dwBytesInBuffer--;
nBytesRead++;
}
}
return( nBytesRead );
}
return( CFile::Read( lpBuf, nCount ) );
}
int CCompressedFile::ReadByte( void )
{
int nReturnValue;
unsigned char ucData;
if( ReadBytes( &ucData, 1 ) != 1 ) return( -1 );
nReturnValue = (int) ucData;
nReturnValue &= 0x000000ff;
return( nReturnValue );
}
void CCompressedFile::WriteBytes( void *lpBuf, unsigned int nCount )
{
if( !m_bOpened || !m_bCanWrite ) return;
if( m_pBuffer ){
if( m_nCompressionType == -1 ){
m_dwCompressedSize += (DWORD) nCount;
m_dwUncompressedSize += (DWORD) nCount;
}
unsigned char *pTransfer = (unsigned char *) lpBuf;
for( unsigned int i=0; i<nCount; i++ ){
// If there are less than BUFFERSIZE bytes in
// the buffer, just store the next byte in the buffer.
if( m_dwBytesInBuffer < BUFFERSIZE ){
m_pBuffer[m_dwBufferPointer++] = *pTransfer++;
m_dwBytesInBuffer++;
}
// If there are BUFFERSIZE bytes in the buffer
// it's time to write the data to disk before trying to
// put another byte in the buffer.
else{
// Write the data.
CFile::Write( m_pBuffer, BUFFERSIZE );
m_dwFilePointer += BUFFERSIZE;
m_dwFileLength += BUFFERSIZE;
m_dwBytesInBuffer = 0;
m_dwBufferPointer = 0;
// Now store the byte in the buffer.
m_pBuffer[m_dwBufferPointer++] = *pTransfer++;
m_dwBytesInBuffer++;
}
}
return;
}
CFile::Write( lpBuf, nCount );
}
void CCompressedFile::WriteByte( int nByte )
{
unsigned char ucData;
ucData = (unsigned char) nByte;
WriteBytes( &ucData, 1 );
m_dwCompressedSize++;
}
DWORD CCompressedFile::GetPosition( void )
{
return( m_dwFilePointer );
}
DWORD CCompressedFile::GetLength( void )
{
return( m_dwUncompressedSize );
}
int CCompressedFile::FileType( char *pszFilename )
{
char cbSignature[20];
CFile cf;
if( !cf.Open( pszFilename, CFile::modeRead ) ) return( -1 );
if( cf.Read( cbSignature, SIGNATURE_LENGTH ) != SIGNATURE_LENGTH ){
cf.Close();
return( -1 );
}
for( int i=0; i<NUMBER_OF_SIGNATURES; i++ ){
int nMatched = 1;
if( strncmp( cbSignature, szSignatures[i], strlen( szSignatures[i] ) ) )
nMatched = 0;
if( nMatched ) return( i );
}
return( -1 );
}
unsigned int CCompressedFile::Read( void *lpBuf, unsigned int nCount )
{
return( 0 );
}
void CCompressedFile::Write( void *lpBuf, unsigned int nCount )
{
}
void CCompressedFile::OutputBit( int nBit )
{
if( nBit ) m_nRack |= m_nMask;
m_nMask >>= 1;
if( !m_nMask ){
WriteByte( m_nRack );
m_nRack = 0;
m_nMask = 0x0080;
}
}
void CCompressedFile::OutputBits( DWORD dwCode, int nCount )
{
DWORD dwMask;
dwMask = 1L << ( nCount - 1 );
while( dwMask ){
if( dwMask & dwCode ) m_nRack |= m_nMask;
m_nMask >>= 1;
if( !m_nMask ){
WriteByte( m_nRack );
m_nRack = 0;
m_nMask = 0x0080;
}
dwMask >>= 1;
}
}
int CCompressedFile::InputBit( void )
{
int nValue;
if( m_nMask == 0x0080 ) m_nRack = ReadByte();
nValue = m_nRack & m_nMask;
m_nMask >>= 1;
if( !m_nMask ) m_nMask = 0x0080;
return( nValue ? 1 : 0 );
}
DWORD CCompressedFile::InputBits( int nCount )
{
DWORD dwMask, dwReturnValue = 0;
dwMask = 1L << ( nCount - 1 );
while( dwMask ){
if( m_nMask == 0x0080 ) m_nRack = ReadByte();
if( m_nRack & m_nMask ) dwReturnValue |= dwMask;
dwMask >>= 1;
m_nMask >>= 1;
if( !m_nMask ) m_nMask = 0x0080;
}
return( dwReturnValue );
}
BOOL CCompressedFile::FindFileInArchive( int nIndex )
{
if( !m_bOpened || m_nFlags != CFile::modeRead ) return( FALSE );
DWORD dwPosition = CFile::GetPosition();
DWORD dwLength = CFile::GetLength();
CFile::Seek( SIGNATURE_LENGTH, CFile::begin );
BOOL bDone = FALSE;
int nCounter = 0;
while( !bDone ){
DWORD dwUncompressed, dwCompressed;
CFile::Read( &dwUncompressed, sizeof( DWORD ) );
CFile::Read( &dwCompressed, sizeof( DWORD ) );
if( nCounter == nIndex ){
m_dwUncompressedSize = dwUncompressed;
m_dwCompressedSize = dwCompressed;
m_dwFilePointer = m_dwSeekTo = CFile::GetPosition();
m_dwSeekTo -= 8L;
m_nRack = m_nPacifierCount = 0;
m_nMask = 0x0080;
m_dwBytesInBuffer = m_dwBufferPointer = 0L;
return( TRUE );
}
nCounter++;
CFile::Seek( dwCompressed, CFile::current );
if( CFile::GetPosition () >= dwLength ) bDone = 1;
}
CFile::Seek( dwPosition, CFile::begin );
return( FALSE );
}
CCompressedFile *CCompressedFile::MakeNewFile( char *pszFilename, int nTyp )
{
int nType;
if( pszFilename && pszFilename[0] ) nType = FileType( pszFilename );
else nType = nTyp;
switch( nType ){
case HUFF:
return( new CHuffmanFile );
break;
case LZSS:
return( new CLzssFile );
break;
case LZW:
return( new CLzwFile );
break;
default:
return( new CUncompressedFile );
}
return( NULL );
}
void CCompressedFile::SetSizeToFileLength( void )
{
m_dwUncompressedSize = m_dwFileLength;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -