CompressedFile.cpp
资源名称:compress.rar [点击查看]
上传用户:deer201011
上传日期:2022-06-24
资源大小:10k
文件大小:9k
源码类别:
压缩解压
开发平台:
Visual C++
- // CompressedFile.cpp
- #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;
- }