summaryrefslogtreecommitdiffstats
path: root/src/libs/7zip/win/CPP/7zip/Archive/Common/FindSignature.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/7zip/win/CPP/7zip/Archive/Common/FindSignature.cpp')
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/Common/FindSignature.cpp62
1 files changed, 62 insertions, 0 deletions
diff --git a/src/libs/7zip/win/CPP/7zip/Archive/Common/FindSignature.cpp b/src/libs/7zip/win/CPP/7zip/Archive/Common/FindSignature.cpp
new file mode 100644
index 000000000..15aa6ceae
--- /dev/null
+++ b/src/libs/7zip/win/CPP/7zip/Archive/Common/FindSignature.cpp
@@ -0,0 +1,62 @@
+// 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);
+ }
+}