rlm@1
|
1 // FindSignature.cpp
|
rlm@1
|
2
|
rlm@1
|
3 #include "StdAfx.h"
|
rlm@1
|
4
|
rlm@1
|
5 #include "Common/Buffer.h"
|
rlm@1
|
6
|
rlm@1
|
7 #include "FindSignature.h"
|
rlm@1
|
8
|
rlm@1
|
9 #include "../../Common/StreamUtils.h"
|
rlm@1
|
10
|
rlm@1
|
11 HRESULT FindSignatureInStream(ISequentialInStream *stream,
|
rlm@1
|
12 const Byte *signature, unsigned signatureSize,
|
rlm@1
|
13 const UInt64 *limit, UInt64 &resPos)
|
rlm@1
|
14 {
|
rlm@1
|
15 resPos = 0;
|
rlm@1
|
16 CByteBuffer byteBuffer2;
|
rlm@1
|
17 byteBuffer2.SetCapacity(signatureSize);
|
rlm@1
|
18 RINOK(ReadStream_FALSE(stream, byteBuffer2, signatureSize));
|
rlm@1
|
19
|
rlm@1
|
20 if (memcmp(byteBuffer2, signature, signatureSize) == 0)
|
rlm@1
|
21 return S_OK;
|
rlm@1
|
22
|
rlm@1
|
23 const UInt32 kBufferSize = (1 << 16);
|
rlm@1
|
24 CByteBuffer byteBuffer;
|
rlm@1
|
25 byteBuffer.SetCapacity(kBufferSize);
|
rlm@1
|
26 Byte *buffer = byteBuffer;
|
rlm@1
|
27 UInt32 numPrevBytes = signatureSize - 1;
|
rlm@1
|
28 memcpy(buffer, (const Byte *)byteBuffer2 + 1, numPrevBytes);
|
rlm@1
|
29 resPos = 1;
|
rlm@1
|
30 for (;;)
|
rlm@1
|
31 {
|
rlm@1
|
32 if (limit != NULL)
|
rlm@1
|
33 if (resPos > *limit)
|
rlm@1
|
34 return S_FALSE;
|
rlm@1
|
35 do
|
rlm@1
|
36 {
|
rlm@1
|
37 UInt32 numReadBytes = kBufferSize - numPrevBytes;
|
rlm@1
|
38 UInt32 processedSize;
|
rlm@1
|
39 RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize));
|
rlm@1
|
40 numPrevBytes += processedSize;
|
rlm@1
|
41 if (processedSize == 0)
|
rlm@1
|
42 return S_FALSE;
|
rlm@1
|
43 }
|
rlm@1
|
44 while (numPrevBytes < signatureSize);
|
rlm@1
|
45 UInt32 numTests = numPrevBytes - signatureSize + 1;
|
rlm@1
|
46 for (UInt32 pos = 0; pos < numTests; pos++)
|
rlm@1
|
47 {
|
rlm@1
|
48 Byte b = signature[0];
|
rlm@1
|
49 for (; buffer[pos] != b && pos < numTests; pos++);
|
rlm@1
|
50 if (pos == numTests)
|
rlm@1
|
51 break;
|
rlm@1
|
52 if (memcmp(buffer + pos, signature, signatureSize) == 0)
|
rlm@1
|
53 {
|
rlm@1
|
54 resPos += pos;
|
rlm@1
|
55 return S_OK;
|
rlm@1
|
56 }
|
rlm@1
|
57 }
|
rlm@1
|
58 resPos += numTests;
|
rlm@1
|
59 numPrevBytes -= numTests;
|
rlm@1
|
60 memmove(buffer, buffer + numTests, numPrevBytes);
|
rlm@1
|
61 }
|
rlm@1
|
62 }
|