// ========================================================================== // Class Specification : COXCheckBase, COXCheckSum8, // COXCheckSum16, COXCheckSum32, COXCRC16, COXCRC32 // ========================================================================== // Header file : OCCRCChk.h // Version: 9.3 // This software along with its related components, documentation and files ("The Libraries") // is © 1994-2007 The Code Project (1612916 Ontario Limited) and use of The Libraries is // governed by a software license agreement ("Agreement"). Copies of the Agreement are // available at The Code Project (www.codeproject.com), as part of the package you downloaded // to obtain this file, or directly from our office. For a copy of the license governing // this software, you may contact us at legalaffairs@codeproject.com, or by calling 416-849-8900. // ////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "OXCRCChk.h" #ifdef _DEBUG #undef THIS_FILE static char BASED_CODE THIS_FILE[] = __FILE__; #endif #define new DEBUG_NEW COXCheckBase::COXCheckBase(ESize eSize /* = szNone */) : m_nCheck32(0xFFFFFFFF), m_eSize(eSize) { } COXCheckBase::~COXCheckBase() { } DWORD COXCheckBase::CalculateBlock( const LPVOID pData, DWORD nCount) { return CalculateBlock(pData, nCount, m_nCheck32); } DWORD COXCheckBase::CalculateFile(CFile* pFile, DWORD nCount /*= 0xFFFFFFFF*/, DWORD nBufferLength /*= 2048*/) { LPBYTE pBuffer; DWORD nLengthRead; DWORD nOldCheck32 = m_nCheck32; if (nCount < nBufferLength) nBufferLength = nCount; pBuffer = new BYTE[nBufferLength]; do { TRY { nLengthRead = pFile->Read(pBuffer, nBufferLength); } CATCH(CFileException, e) { m_nCheck32 = nOldCheck32; delete[] pBuffer; THROW_LAST(); } END_CATCH m_nCheck32 = CalculateBlock(pBuffer, nLengthRead, m_nCheck32); nCount -= nLengthRead; if (nCount < nBufferLength) nBufferLength = nCount; } while ((nBufferLength!=0) && (nLengthRead == nBufferLength)); // So while not EOF delete[] pBuffer; return m_nCheck32; } DWORD COXCheckBase::CalculateFile(CString sFileName) { CFile file; CFileException exception; DWORD dwKey; if (file.Open(sFileName, CFile::modeRead | CFile::shareDenyWrite, &exception) == FALSE) AfxThrowFileException(exception.m_cause, exception.m_lOsError, sFileName); TRY { dwKey = CalculateFile(&file); } CATCH(CFileException, e) { file.Close(); THROW_LAST(); } END_CATCH file.Close(); return dwKey; } COXCheckSum8::COXCheckSum8() : COXCheckBase(sz8bit) { } DWORD COXCheckSum8::CalculateBlock( const LPVOID pData, DWORD nCount, DWORD nSeed) { m_nCheck8 = (BYTE) nSeed; for( DWORD i=0 ; i* COXCRC16::CTableList::CreateTable(WORD nPolynomial) { COXCRCTable* pTable = new COXCRCTable(nPolynomial); int i, j, k; WORD nCRC; // Calculate the CRC value for index position n. for( i=0 ; i<256 ; i++ ) { k = i << 8; nCRC = 0; for( j=0 ; j<8 ; j++ ) { if ((nCRC^k) & 0x8000) nCRC = (WORD) ((nCRC << 1) ^ nPolynomial); else nCRC <<= 1; k <<= 1; } pTable->values[i] = nCRC; } return pTable; } COXCRC16::COXCRC16(WORD nPolynomial /* = CRC16_POLYNOMIAL*/) : COXCheckBase(sz16bit), m_pTable(NULL) { m_pTable = m_tableList.GetTable(nPolynomial); } DWORD COXCRC16::CalculateBlock( const LPVOID pData, DWORD nCount, DWORD nSeed) { LPBYTE p = (LPBYTE) pData; m_nCheck16 = (WORD) nSeed; // Calculate the 16 bit CRC using the table lookup method. while( nCount-- ) m_nCheck16 = (WORD) ((m_nCheck16 << 8) ^ m_pTable->values[(BYTE)((m_nCheck16 >> 8) ^ *p++)]); return (DWORD) m_nCheck16; } ///////////////////////////////////////////////////////////////////////////// // Definition of static members // COXCRC32::CTableList::CTableList() { } COXCRCTable* COXCRC32::CTableList::CreateTable(DWORD nPolynomial) { COXCRCTable* pTable = new COXCRCTable(nPolynomial); int i, j; DWORD nCRC; // Calculate the CRC value for index position n. for(i=0 ; i<256 ; i++) { nCRC = i; for (j=8 ; j>0 ; j--) { if( nCRC & 1 ) nCRC = ( nCRC >> 1 ) ^ nPolynomial; else nCRC >>= 1; } pTable->values[i] = nCRC; } return pTable; } COXCRC32::COXCRC32(DWORD nPolynomial /*= CRC32_POLYNOMIAL*/) : COXCheckBase(sz32bit), m_pTable(NULL) { m_pTable = m_tableList.GetTable(nPolynomial); } DWORD COXCRC32::CalculateBlock( const LPVOID pData, DWORD nCount, DWORD nSeed) { DWORD dwTemp1; DWORD dwTemp2; LPBYTE p = (LPBYTE) pData; m_nCheck32 = nSeed; // Calculate the 32 bit CRC using the table lookup method. while( nCount-- ) { dwTemp1 = (m_nCheck32 >> 8) & 0x00FFFFFFL; dwTemp2 = m_pTable->values[(m_nCheck32 ^ *p++) & 0xff]; m_nCheck32 = dwTemp1 ^ dwTemp2; } return m_nCheck32; }