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

📄 vbf_compressedpersist.h

📁 数据压缩的实例
💻 H
字号:
// CompressedFile.h: interface for the CCompressedPersist class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_COMPRESSEDFILE_A_H__26902454_6259_4E74_9B07_1DB28162A11B__INCLUDED_)
#define AFX_COMPRESSEDFILE_A_H__26902454_6259_4E74_9B07_1DB28162A11B__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000


//#define BUFFERSIZE 32000
#define BUFFERSIZE 32768

// File format for compressed files is 8 bytes of signature/identifier.
// DWORD size of uncompressed file.
// DWORD size of compressed file.

#define NUMBER_OF_SIGNATURES   3
#define SIGNATURE_LENGTH       0

// 定义文件压缩方式
#define VBF_COMPRESS_NULL    0
#define VBF_COMPRESS_HUFF    1
#define VBF_COMPRESS_LZSS    2
#define VBF_COMPRESS_LZW     3

#define MODE_READ   1
#define MODE_CREATE 2
#define MODE_WRITE  3

#define SEEK_BEGIN 0
#define SEEK_CUR   1
#define SEEK_END   2


//#pragma pack()
template <class TYPE> 
class CCompressedPersist
{
public:
	CCompressedPersist( );
	~CCompressedPersist();

	virtual BOOL Open( TYPE* pPersist,unsigned int );
	virtual void Close( void );
	virtual unsigned int Read( void far *, unsigned int );
	virtual void Write( void far *, unsigned int );
    static	CCompressedPersist<TYPE>* MakeNewFile(   int Type = HUFF);
	unsigned int ReadBytes( void far *, unsigned int );
	void WriteBytes( void far *, unsigned int );
private:	
	TYPE* m_pPersist;
//	DWORD GetPosition( void );

	DWORD GetLength( void );
	BOOL FindFileInArchive( int );
	static int FileType( TYPE* pPersist);
	int ReadByte( void );
	void WriteByte( int );


	unsigned char *m_pBuffer;
	DWORD m_dwFilePointer;
	DWORD m_dwBytesInBuffer;
	DWORD m_dwBufferPointer;
	DWORD m_dwFileLength;
	BOOL m_bOpened;
	BOOL m_bCanRead;
	BOOL m_bCanWrite;

	int m_nRack, m_nPacifierCount, m_nMask;
	unsigned char m_ucBit;

	DWORD m_dwSeekTo;
//	char m_szFilename[130];

//	int GetFlagType(TYPE*,unsigned int nMode);
	void Write(TYPE* pPersist,const void* lpBuf, UINT nCount );
	UINT Read(TYPE* pPersist,void* lpBuf, UINT nCount );
	LONG Seek(TYPE* pPersist,LONG lOff, DWORD nFrom );
	DWORD GetLength( TYPE* pPersist ) ;
public:
	DWORD m_dwCompressedSize, m_dwUncompressedSize;
	int m_nCompressionType;
	int m_nMode;
	void OutputBits( DWORD, int );
	DWORD InputBits( int );
	void OutputBit( int );
	int InputBit( void );

	void SetSizeToFileLength( void );

};

#include "VBF_HuffmanPersist.h"
#include "VBF_LzssPersist.h"
#include "VBF_LzwPersist.h"
#include "VBF_UncompressedPersist.h"


template <class TYPE> 
CCompressedPersist<TYPE>::CCompressedPersist( )
{

	m_bOpened = m_bCanRead = m_bCanWrite = FALSE;
	m_nCompressionType = 0;
	m_pBuffer = NULL;
		
}

template <class TYPE> 
CCompressedPersist<TYPE>::~CCompressedPersist()
{

	if( m_bOpened ) Close();
	if( m_pBuffer != NULL ) delete [] m_pBuffer;

}



template <class TYPE> 
BOOL CCompressedPersist<TYPE>::Open( TYPE* pPersist, unsigned int nMode)
{
	ASSERT(pPersist);
	m_pPersist = pPersist;
	if( m_pBuffer != NULL ) delete [] m_pBuffer;
	m_pBuffer = (unsigned char *) new unsigned char [BUFFERSIZE];

	m_nMode = nMode;
	if( m_pBuffer && (  m_nMode == MODE_READ ||  m_nMode == MODE_WRITE ||  m_nMode == MODE_CREATE))
	{
		if( m_nMode == MODE_READ ||  m_nMode == MODE_WRITE) 
			m_nCompressionType = FileType( m_pPersist );
	
		m_dwCompressedSize = m_dwUncompressedSize = 0L;
		m_dwSeekTo = SIGNATURE_LENGTH;
		m_dwBytesInBuffer = m_dwBufferPointer = m_dwFileLength = m_dwFilePointer = 0L;
	   
//		if( !TYPE::Open( pszFileName, nOpenFlags ) )return( FALSE );
		m_dwFileLength = GetLength(m_pPersist);
	  	
		if( m_nMode == MODE_WRITE )
		{
			m_dwSeekTo = m_dwFilePointer = Seek(m_pPersist,0,SEEK_END);
				//TYPE::SeekToEnd();
			Write(m_pPersist,&m_dwUncompressedSize, sizeof( DWORD ));
			Write(m_pPersist,&m_dwCompressedSize, sizeof( DWORD ) );
			m_dwFilePointer += 8L;
		}
		else if( m_nMode != MODE_CREATE )
		{
			Seek(m_pPersist, SIGNATURE_LENGTH, SEEK_BEGIN );
			Read(m_pPersist, &m_dwUncompressedSize, sizeof( DWORD ) );
			Read(m_pPersist, &m_dwCompressedSize, sizeof( DWORD ) );
		}
		else
		{

//			Write( m_pPersist,szSignatures[m_nCompressionType], SIGNATURE_LENGTH );
			Write( m_pPersist,&m_dwUncompressedSize, sizeof( DWORD ) );
			Write( m_pPersist,&m_dwCompressedSize, sizeof( DWORD ) );
		}
		m_bOpened = TRUE;
		if( m_nMode == MODE_READ ) 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 );
	
}


template <class TYPE> 
void CCompressedPersist<TYPE>::Close(  )
{
	
	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_nMode == MODE_WRITE ||	m_nMode == MODE_CREATE )) 
		{
			Write(m_pPersist, m_pBuffer, (unsigned int) m_dwBytesInBuffer );
		}
		delete [] m_pBuffer;
		m_pBuffer = NULL;	

	}
	if( m_nMode == ( MODE_CREATE) || m_nMode == MODE_WRITE )
	{
		Seek( m_pPersist,m_dwSeekTo, SEEK_BEGIN );
		Write(m_pPersist, &m_dwUncompressedSize, sizeof( DWORD ) );
		Write(m_pPersist, &m_dwCompressedSize, sizeof( DWORD ) );
	}

//??	m_pPersist->Close();
	
	m_bOpened = FALSE;

}
template <class TYPE> 
unsigned int CCompressedPersist<TYPE>::Read( void *lpBuf, unsigned int nCount )
{

	return( 0 );

}
template <class TYPE> 
void CCompressedPersist<TYPE>::Write( void *lpBuf, unsigned int nCount )
{

}
template <class TYPE> 
CCompressedPersist<TYPE>* CCompressedPersist<TYPE>::MakeNewFile(  int nTyp)
{

//	int nType = FileType( pPersist );
//	if( nType ==-1 ) 
	int nType = nTyp;

	switch( nType )
	{
		case VBF_COMPRESS_NULL:
			return( new CUncompressedPersist<TYPE> );
			break;
		case VBF_COMPRESS_HUFF:
			return( new CHuffmanPersist<TYPE> );
			break;
		case VBF_COMPRESS_LZSS:
			return( new CLzssPersist<TYPE> );
			break;
		case VBF_COMPRESS_LZW:
			return( new CLzwPersist<TYPE>);
			break;
		default:
			ASSERT(FALSE);
		}

	return( NULL );

}
template <class TYPE> 
int CCompressedPersist<TYPE>::FileType( TYPE* pPersist )
{
	/*
	char cbSignature[20];
	TYPE cf;
		
	if( Read( pPersist,cbSignature, SIGNATURE_LENGTH ) != SIGNATURE_LENGTH )
	{
		Seek(pPersist,0,SEEK_BEGIN);
		return( -1 );
	}
	Seek(pPersist,0,SEEK_BEGIN);

	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 );

}


template <class TYPE> 
unsigned int CCompressedPersist<TYPE>::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 = Read( m_pPersist,m_pBuffer, BUFFERSIZE );
					m_dwFilePointer += BUFFERSIZE;
					m_dwBufferPointer = 0;
				}
				else
				{
					m_dwBytesInBuffer = Read( m_pPersist,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( Read( m_pPersist,lpBuf, nCount ) );

}

template <class TYPE> 
int CCompressedPersist<TYPE>::ReadByte( void )
{
	int nReturnValue;
	unsigned char ucData;

	if( ReadBytes( &ucData, 1 ) != 1 ) return( -1 );
	nReturnValue = (int) ucData;
	nReturnValue &= 0x000000ff;

	return( nReturnValue );

}

template <class TYPE> 
void CCompressedPersist<TYPE>::WriteBytes( void *lpBuf, unsigned int nCount )
{
	if( !m_bOpened || !m_bCanWrite ) return;
	if( m_pBuffer )
	{
		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.
				Write( m_pPersist,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;
	}

	Write( m_pPersist,lpBuf, nCount );
}

template <class TYPE> 
void CCompressedPersist<TYPE>::WriteByte( int nByte )
{

	unsigned char ucData;
	ucData = (unsigned char) nByte;
	WriteBytes( &ucData, 1 );
	m_dwCompressedSize++;

}
/*
DWORD CCompressedPersist<TYPE>::GetPosition( void )
{

	return( m_dwFilePointer );

}
*/
template <class TYPE> 
DWORD CCompressedPersist<TYPE>::GetLength( void )
{

	return( m_dwUncompressedSize );

}





template <class TYPE> 
void CCompressedPersist<TYPE>::OutputBit( int nBit )
{

	if( nBit ) m_nRack |= m_nMask;
	m_nMask >>= 1;

	if( !m_nMask ){
		WriteByte( m_nRack );
		m_nRack = 0;
		m_nMask = 0x0080;		
		}

}

template <class TYPE> 
void CCompressedPersist<TYPE>::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;
		}

}

template <class TYPE> 
int CCompressedPersist<TYPE>::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 );

}

template <class TYPE> 
DWORD CCompressedPersist<TYPE>::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 );

}

template <class TYPE> 
BOOL CCompressedPersist<TYPE>::FindFileInArchive( int nIndex )
{

	if( !m_bOpened || m_nFlags != TYPE::modeRead ) return( FALSE );

	DWORD dwPosition = TYPE::GetPosition();
	DWORD dwLength = TYPE::GetLength();
	TYPE::Seek( SIGNATURE_LENGTH, TYPE::begin );
	BOOL bDone = FALSE;
	int nCounter = 0;

	while( !bDone )
	{
		DWORD dwUncompressed, dwCompressed;
		TYPE::Read( &dwUncompressed, sizeof( DWORD ) );
		TYPE::Read( &dwCompressed,   sizeof( DWORD ) );
		if( nCounter == nIndex )
		{
			m_dwUncompressedSize = dwUncompressed;
			m_dwCompressedSize = dwCompressed;
			m_dwFilePointer = m_dwSeekTo = TYPE::GetPosition();
			m_dwSeekTo -= 8L;
			m_nRack = m_nPacifierCount = 0;
			m_nMask = 0x0080;
			m_dwBytesInBuffer = m_dwBufferPointer = 0L;
			return( TRUE );
		}
		nCounter++;
		TYPE::Seek( dwCompressed, TYPE::current );
		if( TYPE::GetPosition () >= dwLength ) bDone = 1;
	}

	TYPE::Seek( dwPosition, TYPE::begin );

	return( FALSE );

}




template <class TYPE> 
void CCompressedPersist<TYPE>::SetSizeToFileLength( void )
{

	m_dwUncompressedSize = m_dwFileLength;

}





#endif // !defined(AFX_COMPRESSEDFILE_H__26902454_6259_4E74_9B07_1DB28162A11B__INCLUDED_)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -