📄 vbf_compressedpersist.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 + -