CompressedFile.cpp
上传用户:deer201011
上传日期:2022-06-24
资源大小:10k
文件大小:9k
源码类别:

压缩解压

开发平台:

Visual C++

  1. // CompressedFile.cpp
  2. #include "CompressedFile.h"
  3. CCompressedFile::CCompressedFile( int nType )
  4. {
  5. m_bOpened = m_bCanRead = m_bCanWrite = FALSE;
  6. m_nCompressionType = nType;
  7. m_pBuffer = NULL;
  8. }
  9. CCompressedFile::~CCompressedFile()
  10. {
  11. if( m_bOpened ) Close();
  12. if( m_pBuffer != NULL ) delete [] m_pBuffer;
  13. }
  14. BOOL CCompressedFile::Open( const char *pszFileName, unsigned int nOpenFlags, CFileException *pError )
  15. {
  16. if( m_pBuffer != NULL ) delete [] m_pBuffer;
  17. m_pBuffer = (unsigned char *) new unsigned char [BUFFERSIZE];
  18. if( m_pBuffer && ( nOpenFlags == CFile::modeRead || nOpenFlags == ( CFile::modeWrite | CFile::modeCreate ) || nOpenFlags == CFile::modeWrite ) ){
  19. if( nOpenFlags == CFile::modeRead || nOpenFlags == CFile::modeWrite) m_nCompressionType = FileType( (char *) pszFileName );
  20. strcpy( m_szFilename, pszFileName );
  21. m_dwCompressedSize = m_dwUncompressedSize = 0L;
  22. m_dwSeekTo = SIGNATURE_LENGTH;
  23. m_nFlags = nOpenFlags;
  24. m_dwBytesInBuffer = m_dwBufferPointer = m_dwFileLength = m_dwFilePointer = 0L;
  25. if( !CFile::Open( pszFileName, nOpenFlags, pError ) ) return( FALSE );
  26. m_dwFileLength = CFile::GetLength();
  27. if( nOpenFlags == CFile::modeWrite ){
  28. m_dwSeekTo = m_dwFilePointer = CFile::SeekToEnd();
  29. CFile::Write( &m_dwUncompressedSize, sizeof( DWORD ) );
  30. CFile::Write( &m_dwCompressedSize, sizeof( DWORD ) );
  31. m_dwFilePointer += 8L;
  32. }
  33. else if( nOpenFlags != ( CFile::modeCreate | CFile::modeWrite ) ){
  34. if( m_nCompressionType >= 0 ){
  35. CFile::Seek( SIGNATURE_LENGTH, CFile::begin );
  36. CFile::Read( &m_dwUncompressedSize, sizeof( DWORD ) );
  37. CFile::Read( &m_dwCompressedSize, sizeof( DWORD ) );
  38. }
  39. else{
  40. m_dwUncompressedSize = m_dwCompressedSize = CFile::GetLength();
  41. }
  42. }
  43. else{
  44. if( m_nCompressionType >= 0 ){
  45. CFile::Write( szSignatures[m_nCompressionType], SIGNATURE_LENGTH );
  46. CFile::Write( &m_dwUncompressedSize, sizeof( DWORD ) );
  47. CFile::Write( &m_dwCompressedSize, sizeof( DWORD ) );
  48. }
  49. }
  50. m_bOpened = TRUE;
  51. if( nOpenFlags == CFile::modeRead ) m_bCanRead = TRUE;
  52. else m_bCanWrite = TRUE;
  53. m_nRack = m_nPacifierCount = 0;
  54. m_nMask = 0x0080;
  55. return( TRUE );
  56. }
  57. if( m_pBuffer != NULL ) delete [] m_pBuffer;
  58. m_pBuffer = NULL;
  59. return( FALSE );
  60. }
  61. void CCompressedFile::Close( void )
  62. {
  63. if( !m_bOpened ) return;
  64. // If a buffer has been allocated, we may have some
  65. // bytes we need to write to disk.
  66. if( m_pBuffer != NULL ){
  67. if( m_dwBytesInBuffer && ( m_nFlags == CFile::modeWrite || m_nFlags == ( CFile::modeWrite | CFile::modeCreate ) )) CFile::Write( m_pBuffer, (unsigned int) m_dwBytesInBuffer );
  68. delete [] m_pBuffer;
  69. m_pBuffer = NULL;
  70. }
  71. CFile::Close();
  72. m_bOpened = FALSE;
  73. }
  74. unsigned int CCompressedFile::ReadBytes( void *lpBuf, unsigned int nCount )
  75. {
  76. if( !m_bOpened || !m_bCanRead ) return( 0 );
  77. if( m_pBuffer != NULL ){
  78. unsigned int nBytesRead = 0;
  79. // We got a void, so we need to point an unsigned
  80. // char pointer to the buffer in order to get the data.
  81. unsigned char *pTransfer = (unsigned char *) lpBuf;
  82. for( unsigned int i=0; i<nCount; i++ ){
  83. // If we have data in the buffer, go to buffer and get it.
  84. if( m_dwBytesInBuffer ){
  85. *pTransfer++ = m_pBuffer[m_dwBufferPointer++];
  86. m_dwBytesInBuffer--;
  87. nBytesRead++;
  88. }
  89. // If there's no data in the buffer, read up to
  90. // BUFFERSIZE bytes from disk and update m_dwBytesInBuffer
  91. else{
  92. DWORD dwBytesLeft = m_dwFileLength - m_dwFilePointer;
  93. if( dwBytesLeft >= BUFFERSIZE ){
  94. m_dwBytesInBuffer = CFile::Read( m_pBuffer, BUFFERSIZE );
  95. m_dwFilePointer += BUFFERSIZE;
  96. m_dwBufferPointer = 0;
  97. }
  98. else{
  99. m_dwBytesInBuffer = CFile::Read( m_pBuffer, (int) dwBytesLeft );
  100. m_dwFilePointer += (DWORD) m_dwBytesInBuffer;
  101. m_dwBufferPointer = 0;
  102. }
  103. // Now that we've read in the data, get the byte.
  104. *pTransfer++ = m_pBuffer[m_dwBufferPointer++];
  105. m_dwBytesInBuffer--;
  106. nBytesRead++;
  107. }
  108. }
  109. return( nBytesRead );
  110. }
  111. return( CFile::Read( lpBuf, nCount ) );
  112. }
  113. int CCompressedFile::ReadByte( void )
  114. {
  115. int nReturnValue;
  116. unsigned char ucData;
  117. if( ReadBytes( &ucData, 1 ) != 1 ) return( -1 );
  118. nReturnValue = (int) ucData;
  119. nReturnValue &= 0x000000ff;
  120. return( nReturnValue );
  121. }
  122. void CCompressedFile::WriteBytes( void *lpBuf, unsigned int nCount )
  123. {
  124. if( !m_bOpened || !m_bCanWrite ) return;
  125. if( m_pBuffer ){
  126. if( m_nCompressionType == -1 ){
  127. m_dwCompressedSize += (DWORD) nCount;
  128. m_dwUncompressedSize += (DWORD) nCount;
  129. }
  130. unsigned char *pTransfer = (unsigned char *) lpBuf;
  131. for( unsigned int i=0; i<nCount; i++ ){
  132. // If there are less than BUFFERSIZE bytes in
  133. // the buffer, just store the next byte in the buffer.
  134. if( m_dwBytesInBuffer < BUFFERSIZE ){
  135. m_pBuffer[m_dwBufferPointer++] = *pTransfer++;
  136. m_dwBytesInBuffer++;
  137. }
  138. // If there are BUFFERSIZE bytes in the buffer
  139. // it's time to write the data to disk before trying to
  140. // put another byte in the buffer.
  141. else{
  142. // Write the data.
  143. CFile::Write( m_pBuffer, BUFFERSIZE );
  144. m_dwFilePointer += BUFFERSIZE;
  145. m_dwFileLength += BUFFERSIZE;
  146. m_dwBytesInBuffer = 0;
  147. m_dwBufferPointer = 0;
  148. // Now store the byte in the buffer.
  149. m_pBuffer[m_dwBufferPointer++] = *pTransfer++;
  150. m_dwBytesInBuffer++;
  151. }
  152. }
  153. return;
  154. }
  155. CFile::Write( lpBuf, nCount );
  156. }
  157. void CCompressedFile::WriteByte( int nByte )
  158. {
  159. unsigned char ucData;
  160. ucData = (unsigned char) nByte;
  161. WriteBytes( &ucData, 1 );
  162. m_dwCompressedSize++;
  163. }
  164. DWORD CCompressedFile::GetPosition( void )
  165. {
  166. return( m_dwFilePointer );
  167. }
  168. DWORD CCompressedFile::GetLength( void )
  169. {
  170. return( m_dwUncompressedSize );
  171. }
  172. int CCompressedFile::FileType( char *pszFilename )
  173. {
  174. char cbSignature[20];
  175. CFile cf;
  176. if( !cf.Open( pszFilename, CFile::modeRead ) ) return( -1 );
  177. if( cf.Read( cbSignature, SIGNATURE_LENGTH ) != SIGNATURE_LENGTH ){
  178. cf.Close();
  179. return( -1 );
  180. }
  181. for( int i=0; i<NUMBER_OF_SIGNATURES; i++ ){
  182. int nMatched = 1;
  183. if( strncmp( cbSignature, szSignatures[i], strlen( szSignatures[i] ) ) )
  184. nMatched = 0;
  185. if( nMatched ) return( i );
  186. }
  187. return( -1 );
  188. }
  189. unsigned int CCompressedFile::Read( void *lpBuf, unsigned int nCount )
  190. {
  191. return( 0 );
  192. }
  193. void CCompressedFile::Write( void *lpBuf, unsigned int nCount )
  194. {
  195. }
  196. void CCompressedFile::OutputBit( int nBit )
  197. {
  198. if( nBit ) m_nRack |= m_nMask;
  199. m_nMask >>= 1;
  200. if( !m_nMask ){
  201. WriteByte( m_nRack );
  202. m_nRack = 0;
  203. m_nMask = 0x0080;
  204. }
  205. }
  206. void CCompressedFile::OutputBits( DWORD dwCode, int nCount )
  207. {
  208. DWORD dwMask;
  209. dwMask = 1L << ( nCount - 1 );
  210. while( dwMask ){
  211. if( dwMask & dwCode ) m_nRack |= m_nMask;
  212. m_nMask >>= 1;
  213. if( !m_nMask ){
  214. WriteByte( m_nRack );
  215. m_nRack = 0;
  216. m_nMask = 0x0080;
  217. }
  218. dwMask >>= 1;
  219. }
  220. }
  221. int CCompressedFile::InputBit( void )
  222. {
  223. int nValue;
  224. if( m_nMask == 0x0080 ) m_nRack = ReadByte();
  225. nValue = m_nRack & m_nMask;
  226. m_nMask >>= 1;
  227. if( !m_nMask ) m_nMask = 0x0080;
  228. return( nValue ? 1 : 0 );
  229. }
  230. DWORD CCompressedFile::InputBits( int nCount )
  231. {
  232. DWORD dwMask, dwReturnValue = 0;
  233. dwMask = 1L << ( nCount - 1 );
  234. while( dwMask ){
  235. if( m_nMask == 0x0080 ) m_nRack = ReadByte();
  236. if( m_nRack & m_nMask ) dwReturnValue |= dwMask;
  237. dwMask >>= 1;
  238. m_nMask >>= 1;
  239. if( !m_nMask ) m_nMask = 0x0080;
  240. }
  241. return( dwReturnValue );
  242. }
  243. BOOL CCompressedFile::FindFileInArchive( int nIndex )
  244. {
  245. if( !m_bOpened || m_nFlags != CFile::modeRead ) return( FALSE );
  246. DWORD dwPosition = CFile::GetPosition();
  247. DWORD dwLength = CFile::GetLength();
  248. CFile::Seek( SIGNATURE_LENGTH, CFile::begin );
  249. BOOL bDone = FALSE;
  250. int nCounter = 0;
  251. while( !bDone ){
  252. DWORD dwUncompressed, dwCompressed;
  253. CFile::Read( &dwUncompressed, sizeof( DWORD ) );
  254. CFile::Read( &dwCompressed, sizeof( DWORD ) );
  255. if( nCounter == nIndex ){
  256. m_dwUncompressedSize = dwUncompressed;
  257. m_dwCompressedSize = dwCompressed;
  258. m_dwFilePointer = m_dwSeekTo = CFile::GetPosition();
  259. m_dwSeekTo -= 8L;
  260. m_nRack = m_nPacifierCount = 0;
  261. m_nMask = 0x0080;
  262. m_dwBytesInBuffer = m_dwBufferPointer = 0L;
  263. return( TRUE );
  264. }
  265. nCounter++;
  266. CFile::Seek( dwCompressed, CFile::current );
  267. if( CFile::GetPosition () >= dwLength ) bDone = 1;
  268. }
  269. CFile::Seek( dwPosition, CFile::begin );
  270. return( FALSE );
  271. }
  272. CCompressedFile *CCompressedFile::MakeNewFile( char *pszFilename, int nTyp )
  273. {
  274. int nType;
  275. if( pszFilename && pszFilename[0] ) nType = FileType( pszFilename );
  276. else nType = nTyp;
  277. switch( nType ){
  278. case HUFF:
  279. return( new CHuffmanFile );
  280. break;
  281. case LZSS:
  282. return( new CLzssFile );
  283. break;
  284. case LZW:
  285. return( new CLzwFile );
  286. break;
  287. default:
  288. return( new CUncompressedFile );
  289. }
  290. return( NULL );
  291. }
  292. void CCompressedFile::SetSizeToFileLength( void )
  293. {
  294. m_dwUncompressedSize = m_dwFileLength;
  295. }