⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compressedfile.cpp

📁 < VC++编程宝典> 编程必备,适合初学者!
💻 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 + -