//////////////////////////////////////////////////////////////////// // // Boyer-Moore implementation // version: 1.12 // (c)2006 Jeremy Collake / Bitsum Technologies // jeremy@bitsum.com // Use PECompact today! // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "bmbinbin.h" BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hModule); break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } CBoyerMooreHandle::CBoyerMooreHandle() { m_pTable=new unsigned long[256]; m_pPhrase=NULL; } CBoyerMooreHandle::~CBoyerMooreHandle() { delete m_pTable; if(m_pPhrase) { delete m_pPhrase; } } bool CBoyerMooreHandle::Init(unsigned char *pPhrase, unsigned long nPhraseLen) { if(!nPhraseLen || !pPhrase) { return false; } m_pPhrase=new unsigned char[nPhraseLen]; memcpy_s(m_pPhrase,nPhraseLen,pPhrase,nPhraseLen); for(int nI=0;nI<256;nI++) { m_pTable[nI]=nPhraseLen; } // duplicates over-written with smaller value using forward str direction for(unsigned int nI=0;nI<nPhraseLen;nI++) { m_pTable[pPhrase[nI]]=(nPhraseLen-nI)-1; } m_nPhraseLen=nPhraseLen; return true; } // // allocate and initialize table // COMMON_API CBoyerMooreHandle * __stdcall BoyerMooreBinBin_Init(unsigned char *pPhrase, unsigned long nPhraseLen) { CBoyerMooreHandle *pBMInfo=new CBoyerMooreHandle; if(!pBMInfo->Init(pPhrase,nPhraseLen)) { _ASSERT(0); delete pBMInfo; return NULL; } return pBMInfo; } COMMON_API int __stdcall BoyerMooreBinBin(CBoyerMooreHandle *pHandle, unsigned char *pBuffer, unsigned long nBufferSize, unsigned long nStart) { bool bMatch; nStart+=(pHandle->m_nPhraseLen-1); // advance up to phrase length if(nStart>=nBufferSize) { return -1; } for(unsigned long nPos=nStart;nPos<nBufferSize;) { int nDiff=pHandle->m_pTable[pBuffer[nPos]]; // get character shift value switch(nDiff) { case 0: // if shift of 0, then is last character so need to do a reverse comparison // .. starting at nPos-1 since we know last character is a match bMatch=true; for(int nI=pHandle->m_nPhraseLen-1;nI>0;nI--) { int nBufferIndex=nPos-(pHandle->m_nPhraseLen-nI); if(pHandle->m_pPhrase[nI-1]!=pBuffer[nBufferIndex]) { // reverse comparison failed.. // back up to last compared character and apply normal shift nBufferIndex+=pHandle->m_pTable[pBuffer[nBufferIndex]]; if(nBufferIndex>++nPos) { nPos=nBufferIndex; } bMatch=false; break; } } if(bMatch) { return nPos-(pHandle->m_nPhraseLen-1); } break; default: nPos+=nDiff; // shift break; } } return -1; } COMMON_API void __stdcall BoyerMooreBinBin_Deinit(CBoyerMooreHandle *pHandle) { delete pHandle; }