// FindSignature.cpp #include "StdAfx.h" #include "Common/Buffer.h" #include "FindSignature.h" #include "../../Common/StreamUtils.h" HRESULT FindSignatureInStream(ISequentialInStream *stream, const Byte *signature, unsigned signatureSize, const UInt64 *limit, UInt64 &resPos) { resPos = 0; CByteBuffer byteBuffer2; byteBuffer2.SetCapacity(signatureSize); RINOK(ReadStream_FALSE(stream, byteBuffer2, signatureSize)); if (memcmp(byteBuffer2, signature, signatureSize) == 0) return S_OK; const UInt32 kBufferSize = (1 << 16); CByteBuffer byteBuffer; byteBuffer.SetCapacity(kBufferSize); Byte *buffer = byteBuffer; UInt32 numPrevBytes = signatureSize - 1; memcpy(buffer, (const Byte *)byteBuffer2 + 1, numPrevBytes); resPos = 1; for (;;) { if (limit != NULL) if (resPos > *limit) return S_FALSE; do { UInt32 numReadBytes = kBufferSize - numPrevBytes; UInt32 processedSize; RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize)); numPrevBytes += processedSize; if (processedSize == 0) return S_FALSE; } while (numPrevBytes < signatureSize); UInt32 numTests = numPrevBytes - signatureSize + 1; for (UInt32 pos = 0; pos < numTests; pos++) { Byte b = signature[0]; for (; buffer[pos] != b && pos < numTests; pos++) {} if (pos == numTests) break; if (memcmp(buffer + pos, signature, signatureSize) == 0) { resPos += pos; return S_OK; } } resPos += numTests; numPrevBytes -= numTests; memmove(buffer, buffer + numTests, numPrevBytes); } }