xref: /aosp_15_r20/external/lzma/CPP/7zip/Archive/Common/FindSignature.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // FindSignature.cpp
2*f6dc9357SAndroid Build Coastguard Worker 
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker 
5*f6dc9357SAndroid Build Coastguard Worker #include <string.h>
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/MyBuffer.h"
8*f6dc9357SAndroid Build Coastguard Worker 
9*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/StreamUtils.h"
10*f6dc9357SAndroid Build Coastguard Worker 
11*f6dc9357SAndroid Build Coastguard Worker #include "FindSignature.h"
12*f6dc9357SAndroid Build Coastguard Worker 
FindSignatureInStream(ISequentialInStream * stream,const Byte * signature,unsigned signatureSize,const UInt64 * limit,UInt64 & resPos)13*f6dc9357SAndroid Build Coastguard Worker HRESULT FindSignatureInStream(ISequentialInStream *stream,
14*f6dc9357SAndroid Build Coastguard Worker     const Byte *signature, unsigned signatureSize,
15*f6dc9357SAndroid Build Coastguard Worker     const UInt64 *limit, UInt64 &resPos)
16*f6dc9357SAndroid Build Coastguard Worker {
17*f6dc9357SAndroid Build Coastguard Worker   resPos = 0;
18*f6dc9357SAndroid Build Coastguard Worker   CByteBuffer byteBuffer2(signatureSize);
19*f6dc9357SAndroid Build Coastguard Worker   RINOK(ReadStream_FALSE(stream, byteBuffer2, signatureSize))
20*f6dc9357SAndroid Build Coastguard Worker 
21*f6dc9357SAndroid Build Coastguard Worker   if (memcmp(byteBuffer2, signature, signatureSize) == 0)
22*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
23*f6dc9357SAndroid Build Coastguard Worker 
24*f6dc9357SAndroid Build Coastguard Worker   const size_t kBufferSize = 1 << 16;
25*f6dc9357SAndroid Build Coastguard Worker   CByteBuffer byteBuffer(kBufferSize);
26*f6dc9357SAndroid Build Coastguard Worker   Byte *buffer = byteBuffer;
27*f6dc9357SAndroid Build Coastguard Worker   size_t numPrevBytes = signatureSize - 1;
28*f6dc9357SAndroid Build Coastguard Worker   memcpy(buffer, (const Byte *)byteBuffer2 + 1, numPrevBytes);
29*f6dc9357SAndroid Build Coastguard Worker   resPos = 1;
30*f6dc9357SAndroid Build Coastguard Worker   for (;;)
31*f6dc9357SAndroid Build Coastguard Worker   {
32*f6dc9357SAndroid Build Coastguard Worker     if (limit)
33*f6dc9357SAndroid Build Coastguard Worker       if (resPos > *limit)
34*f6dc9357SAndroid Build Coastguard Worker         return S_FALSE;
35*f6dc9357SAndroid Build Coastguard Worker     do
36*f6dc9357SAndroid Build Coastguard Worker     {
37*f6dc9357SAndroid Build Coastguard Worker       const size_t numReadBytes = kBufferSize - numPrevBytes;
38*f6dc9357SAndroid Build Coastguard Worker       UInt32 processedSize;
39*f6dc9357SAndroid Build Coastguard Worker       RINOK(stream->Read(buffer + numPrevBytes, (UInt32)numReadBytes, &processedSize))
40*f6dc9357SAndroid Build Coastguard Worker       numPrevBytes += (size_t)processedSize;
41*f6dc9357SAndroid Build Coastguard Worker       if (processedSize == 0)
42*f6dc9357SAndroid Build Coastguard Worker         return S_FALSE;
43*f6dc9357SAndroid Build Coastguard Worker     }
44*f6dc9357SAndroid Build Coastguard Worker     while (numPrevBytes < signatureSize);
45*f6dc9357SAndroid Build Coastguard Worker     const size_t numTests = numPrevBytes - signatureSize + 1;
46*f6dc9357SAndroid Build Coastguard Worker     for (size_t pos = 0; pos < numTests; pos++)
47*f6dc9357SAndroid Build Coastguard Worker     {
48*f6dc9357SAndroid Build Coastguard Worker       const Byte b = signature[0];
49*f6dc9357SAndroid Build Coastguard Worker       for (; buffer[pos] != b && pos < numTests; pos++);
50*f6dc9357SAndroid Build Coastguard Worker       if (pos == numTests)
51*f6dc9357SAndroid Build Coastguard Worker         break;
52*f6dc9357SAndroid Build Coastguard Worker       if (memcmp(buffer + pos, signature, signatureSize) == 0)
53*f6dc9357SAndroid Build Coastguard Worker       {
54*f6dc9357SAndroid Build Coastguard Worker         resPos += pos;
55*f6dc9357SAndroid Build Coastguard Worker         return S_OK;
56*f6dc9357SAndroid Build Coastguard Worker       }
57*f6dc9357SAndroid Build Coastguard Worker     }
58*f6dc9357SAndroid Build Coastguard Worker     resPos += numTests;
59*f6dc9357SAndroid Build Coastguard Worker     numPrevBytes -= numTests;
60*f6dc9357SAndroid Build Coastguard Worker     memmove(buffer, buffer + numTests, numPrevBytes);
61*f6dc9357SAndroid Build Coastguard Worker   }
62*f6dc9357SAndroid Build Coastguard Worker }
63*f6dc9357SAndroid Build Coastguard Worker 
64*f6dc9357SAndroid Build Coastguard Worker namespace NArchive {
65*f6dc9357SAndroid Build Coastguard Worker HRESULT ReadZeroTail(ISequentialInStream *stream, bool &areThereNonZeros, UInt64 &numZeros, UInt64 maxSize);
ReadZeroTail(ISequentialInStream * stream,bool & areThereNonZeros,UInt64 & numZeros,UInt64 maxSize)66*f6dc9357SAndroid Build Coastguard Worker HRESULT ReadZeroTail(ISequentialInStream *stream, bool &areThereNonZeros, UInt64 &numZeros, UInt64 maxSize)
67*f6dc9357SAndroid Build Coastguard Worker {
68*f6dc9357SAndroid Build Coastguard Worker   areThereNonZeros = false;
69*f6dc9357SAndroid Build Coastguard Worker   numZeros = 0;
70*f6dc9357SAndroid Build Coastguard Worker   const size_t kBufSize = 1 << 11;
71*f6dc9357SAndroid Build Coastguard Worker   Byte buf[kBufSize];
72*f6dc9357SAndroid Build Coastguard Worker   for (;;)
73*f6dc9357SAndroid Build Coastguard Worker   {
74*f6dc9357SAndroid Build Coastguard Worker     UInt32 size = 0;
75*f6dc9357SAndroid Build Coastguard Worker     RINOK(stream->Read(buf, kBufSize, &size))
76*f6dc9357SAndroid Build Coastguard Worker     if (size == 0)
77*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
78*f6dc9357SAndroid Build Coastguard Worker     for (UInt32 i = 0; i < size; i++)
79*f6dc9357SAndroid Build Coastguard Worker       if (buf[i] != 0)
80*f6dc9357SAndroid Build Coastguard Worker       {
81*f6dc9357SAndroid Build Coastguard Worker         areThereNonZeros = true;
82*f6dc9357SAndroid Build Coastguard Worker         numZeros += i;
83*f6dc9357SAndroid Build Coastguard Worker         return S_OK;
84*f6dc9357SAndroid Build Coastguard Worker       }
85*f6dc9357SAndroid Build Coastguard Worker     numZeros += size;
86*f6dc9357SAndroid Build Coastguard Worker     if (numZeros > maxSize)
87*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
88*f6dc9357SAndroid Build Coastguard Worker   }
89*f6dc9357SAndroid Build Coastguard Worker }
90*f6dc9357SAndroid Build Coastguard Worker }
91