1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
|
// FindSignature.cpp
#include "StdAfx.h"
#include <string.h>
#include "../../../Common/MyBuffer.h"
#include "../../Common/StreamUtils.h"
#include "FindSignature.h"
HRESULT FindSignatureInStream(ISequentialInStream *stream,
const Byte *signature, unsigned signatureSize,
const UInt64 *limit, UInt64 &resPos)
{
resPos = 0;
CByteBuffer byteBuffer2(signatureSize);
RINOK(ReadStream_FALSE(stream, byteBuffer2, signatureSize));
if (memcmp(byteBuffer2, signature, signatureSize) == 0)
return S_OK;
const UInt32 kBufferSize = (1 << 16);
CByteBuffer byteBuffer(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);
}
}
|