xref: /aosp_15_r20/external/lzma/CPP/7zip/Archive/Cab/CabBlockInStream.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // CabBlockInStream.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 "../../../../C/Alloc.h"
6*f6dc9357SAndroid Build Coastguard Worker #include "../../../../C/CpuArch.h"
7*f6dc9357SAndroid Build Coastguard Worker 
8*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/StreamUtils.h"
9*f6dc9357SAndroid Build Coastguard Worker 
10*f6dc9357SAndroid Build Coastguard Worker #include "CabBlockInStream.h"
11*f6dc9357SAndroid Build Coastguard Worker 
12*f6dc9357SAndroid Build Coastguard Worker namespace NArchive {
13*f6dc9357SAndroid Build Coastguard Worker namespace NCab {
14*f6dc9357SAndroid Build Coastguard Worker 
15*f6dc9357SAndroid Build Coastguard Worker static const UInt32 kBlockSize = 1 << 16;
16*f6dc9357SAndroid Build Coastguard Worker static const unsigned k_OverReadPadZone_Size = 32;
17*f6dc9357SAndroid Build Coastguard Worker static const unsigned kHeaderSize = 8;
18*f6dc9357SAndroid Build Coastguard Worker static const unsigned kReservedMax = 256;
19*f6dc9357SAndroid Build Coastguard Worker static const unsigned kHeaderOffset = kBlockSize + k_OverReadPadZone_Size;
20*f6dc9357SAndroid Build Coastguard Worker 
Create()21*f6dc9357SAndroid Build Coastguard Worker bool CBlockPackData::Create() throw()
22*f6dc9357SAndroid Build Coastguard Worker {
23*f6dc9357SAndroid Build Coastguard Worker   if (!_buf)
24*f6dc9357SAndroid Build Coastguard Worker     _buf = (Byte *)z7_AlignedAlloc(kBlockSize + k_OverReadPadZone_Size + kHeaderSize + kReservedMax);
25*f6dc9357SAndroid Build Coastguard Worker   return _buf != NULL;
26*f6dc9357SAndroid Build Coastguard Worker }
27*f6dc9357SAndroid Build Coastguard Worker 
~CBlockPackData()28*f6dc9357SAndroid Build Coastguard Worker CBlockPackData::~CBlockPackData() throw()
29*f6dc9357SAndroid Build Coastguard Worker {
30*f6dc9357SAndroid Build Coastguard Worker   z7_AlignedFree(_buf);
31*f6dc9357SAndroid Build Coastguard Worker }
32*f6dc9357SAndroid Build Coastguard Worker 
CheckSum(const Byte * p,UInt32 size)33*f6dc9357SAndroid Build Coastguard Worker static UInt32 CheckSum(const Byte *p, UInt32 size) throw()
34*f6dc9357SAndroid Build Coastguard Worker {
35*f6dc9357SAndroid Build Coastguard Worker #ifdef MY_CPU_64BIT
36*f6dc9357SAndroid Build Coastguard Worker 
37*f6dc9357SAndroid Build Coastguard Worker   UInt64 sum64 = 0;
38*f6dc9357SAndroid Build Coastguard Worker   if (size >= 16)
39*f6dc9357SAndroid Build Coastguard Worker   {
40*f6dc9357SAndroid Build Coastguard Worker     const Byte *lim = p + (size_t)size - 16;
41*f6dc9357SAndroid Build Coastguard Worker     do
42*f6dc9357SAndroid Build Coastguard Worker     {
43*f6dc9357SAndroid Build Coastguard Worker       sum64 ^= GetUi64(p) ^ GetUi64(p + 8);
44*f6dc9357SAndroid Build Coastguard Worker       p += 16;
45*f6dc9357SAndroid Build Coastguard Worker     }
46*f6dc9357SAndroid Build Coastguard Worker     while (p <= lim);
47*f6dc9357SAndroid Build Coastguard Worker     size = (UInt32)(lim + 16 - p);
48*f6dc9357SAndroid Build Coastguard Worker   }
49*f6dc9357SAndroid Build Coastguard Worker   if (size >= 8)
50*f6dc9357SAndroid Build Coastguard Worker   {
51*f6dc9357SAndroid Build Coastguard Worker     sum64 ^= GetUi64(p);
52*f6dc9357SAndroid Build Coastguard Worker     p += 8;
53*f6dc9357SAndroid Build Coastguard Worker     size -= 8;
54*f6dc9357SAndroid Build Coastguard Worker   }
55*f6dc9357SAndroid Build Coastguard Worker 
56*f6dc9357SAndroid Build Coastguard Worker   UInt32 sum = (UInt32)(sum64 >> 32) ^ (UInt32)sum64;
57*f6dc9357SAndroid Build Coastguard Worker 
58*f6dc9357SAndroid Build Coastguard Worker #else
59*f6dc9357SAndroid Build Coastguard Worker 
60*f6dc9357SAndroid Build Coastguard Worker   UInt32 sum = 0;
61*f6dc9357SAndroid Build Coastguard Worker   if (size >= 16)
62*f6dc9357SAndroid Build Coastguard Worker   {
63*f6dc9357SAndroid Build Coastguard Worker     const Byte *lim = p + (size_t)size - 16;
64*f6dc9357SAndroid Build Coastguard Worker     do
65*f6dc9357SAndroid Build Coastguard Worker     {
66*f6dc9357SAndroid Build Coastguard Worker       sum ^= GetUi32(p)
67*f6dc9357SAndroid Build Coastguard Worker            ^ GetUi32(p + 4)
68*f6dc9357SAndroid Build Coastguard Worker            ^ GetUi32(p + 8)
69*f6dc9357SAndroid Build Coastguard Worker            ^ GetUi32(p + 12);
70*f6dc9357SAndroid Build Coastguard Worker       p += 16;
71*f6dc9357SAndroid Build Coastguard Worker     }
72*f6dc9357SAndroid Build Coastguard Worker     while (p <= lim);
73*f6dc9357SAndroid Build Coastguard Worker     size = (UInt32)(lim + 16 - p);
74*f6dc9357SAndroid Build Coastguard Worker   }
75*f6dc9357SAndroid Build Coastguard Worker   if (size >= 8)
76*f6dc9357SAndroid Build Coastguard Worker   {
77*f6dc9357SAndroid Build Coastguard Worker     sum ^= GetUi32(p + 0) ^ GetUi32(p + 4);
78*f6dc9357SAndroid Build Coastguard Worker     p += 8;
79*f6dc9357SAndroid Build Coastguard Worker     size -= 8;
80*f6dc9357SAndroid Build Coastguard Worker   }
81*f6dc9357SAndroid Build Coastguard Worker 
82*f6dc9357SAndroid Build Coastguard Worker #endif
83*f6dc9357SAndroid Build Coastguard Worker 
84*f6dc9357SAndroid Build Coastguard Worker   if (size >= 4)
85*f6dc9357SAndroid Build Coastguard Worker   {
86*f6dc9357SAndroid Build Coastguard Worker     sum ^= GetUi32(p);
87*f6dc9357SAndroid Build Coastguard Worker     p += 4;
88*f6dc9357SAndroid Build Coastguard Worker   }
89*f6dc9357SAndroid Build Coastguard Worker   if (size &= 3)
90*f6dc9357SAndroid Build Coastguard Worker   {
91*f6dc9357SAndroid Build Coastguard Worker     if (size >= 2)
92*f6dc9357SAndroid Build Coastguard Worker     {
93*f6dc9357SAndroid Build Coastguard Worker       if (size > 2)
94*f6dc9357SAndroid Build Coastguard Worker         sum ^= (UInt32)(*p++) << 16;
95*f6dc9357SAndroid Build Coastguard Worker       sum ^= (UInt32)(*p++) << 8;
96*f6dc9357SAndroid Build Coastguard Worker     }
97*f6dc9357SAndroid Build Coastguard Worker     sum ^= (UInt32)(*p++);
98*f6dc9357SAndroid Build Coastguard Worker   }
99*f6dc9357SAndroid Build Coastguard Worker   return sum;
100*f6dc9357SAndroid Build Coastguard Worker }
101*f6dc9357SAndroid Build Coastguard Worker 
102*f6dc9357SAndroid Build Coastguard Worker 
Read(ISequentialInStream * stream,Byte ReservedSize,UInt32 & packSizeRes,UInt32 & unpackSize)103*f6dc9357SAndroid Build Coastguard Worker HRESULT CBlockPackData::Read(ISequentialInStream *stream, Byte ReservedSize, UInt32 &packSizeRes, UInt32 &unpackSize) throw()
104*f6dc9357SAndroid Build Coastguard Worker {
105*f6dc9357SAndroid Build Coastguard Worker   const UInt32 reserved8 = kHeaderSize + ReservedSize;
106*f6dc9357SAndroid Build Coastguard Worker   const Byte *header = _buf + kHeaderOffset;
107*f6dc9357SAndroid Build Coastguard Worker   RINOK(ReadStream_FALSE(stream, (void *)header, reserved8))
108*f6dc9357SAndroid Build Coastguard Worker   unpackSize = GetUi16a(header + 6);
109*f6dc9357SAndroid Build Coastguard Worker   const UInt32 packSize = GetUi16a(header + 4);
110*f6dc9357SAndroid Build Coastguard Worker   packSizeRes = packSize;
111*f6dc9357SAndroid Build Coastguard Worker   if (packSize > kBlockSize - _size)
112*f6dc9357SAndroid Build Coastguard Worker     return S_FALSE;
113*f6dc9357SAndroid Build Coastguard Worker   RINOK(ReadStream_FALSE(stream, _buf + _size, packSize))
114*f6dc9357SAndroid Build Coastguard Worker   memset(_buf + _size + packSize, 0xff, k_OverReadPadZone_Size);
115*f6dc9357SAndroid Build Coastguard Worker   if (*(const UInt32 *)(const void *)header != 0) // checkSum
116*f6dc9357SAndroid Build Coastguard Worker     if (CheckSum(header, reserved8) != CheckSum(_buf + _size, packSize))
117*f6dc9357SAndroid Build Coastguard Worker       return S_FALSE;
118*f6dc9357SAndroid Build Coastguard Worker   _size += packSize;
119*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
120*f6dc9357SAndroid Build Coastguard Worker }
121*f6dc9357SAndroid Build Coastguard Worker 
122*f6dc9357SAndroid Build Coastguard Worker }}
123