xref: /aosp_15_r20/external/lzma/CPP/7zip/Archive/7z/7zFolderInStream.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // 7zFolderInStream.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 "../../../Windows/TimeUtils.h"
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker #include "7zFolderInStream.h"
8*f6dc9357SAndroid Build Coastguard Worker 
9*f6dc9357SAndroid Build Coastguard Worker namespace NArchive {
10*f6dc9357SAndroid Build Coastguard Worker namespace N7z {
11*f6dc9357SAndroid Build Coastguard Worker 
Init(IArchiveUpdateCallback * updateCallback,const UInt32 * indexes,unsigned numFiles)12*f6dc9357SAndroid Build Coastguard Worker void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback,
13*f6dc9357SAndroid Build Coastguard Worker     const UInt32 *indexes, unsigned numFiles)
14*f6dc9357SAndroid Build Coastguard Worker {
15*f6dc9357SAndroid Build Coastguard Worker   _updateCallback = updateCallback;
16*f6dc9357SAndroid Build Coastguard Worker   _indexes = indexes;
17*f6dc9357SAndroid Build Coastguard Worker   _numFiles = numFiles;
18*f6dc9357SAndroid Build Coastguard Worker 
19*f6dc9357SAndroid Build Coastguard Worker   _totalSize_for_Coder = 0;
20*f6dc9357SAndroid Build Coastguard Worker   ClearFileInfo();
21*f6dc9357SAndroid Build Coastguard Worker 
22*f6dc9357SAndroid Build Coastguard Worker   Processed.ClearAndReserve(numFiles);
23*f6dc9357SAndroid Build Coastguard Worker   Sizes.ClearAndReserve(numFiles);
24*f6dc9357SAndroid Build Coastguard Worker   CRCs.ClearAndReserve(numFiles);
25*f6dc9357SAndroid Build Coastguard Worker   TimesDefined.ClearAndReserve(numFiles);
26*f6dc9357SAndroid Build Coastguard Worker   MTimes.ClearAndReserve(Need_MTime ? numFiles : (unsigned)0);
27*f6dc9357SAndroid Build Coastguard Worker   CTimes.ClearAndReserve(Need_CTime ? numFiles : (unsigned)0);
28*f6dc9357SAndroid Build Coastguard Worker   ATimes.ClearAndReserve(Need_ATime ? numFiles : (unsigned)0);
29*f6dc9357SAndroid Build Coastguard Worker   Attribs.ClearAndReserve(Need_Attrib ? numFiles : (unsigned)0);
30*f6dc9357SAndroid Build Coastguard Worker 
31*f6dc9357SAndroid Build Coastguard Worker   // FolderCrc = CRC_INIT_VAL;
32*f6dc9357SAndroid Build Coastguard Worker   _stream.Release();
33*f6dc9357SAndroid Build Coastguard Worker }
34*f6dc9357SAndroid Build Coastguard Worker 
ClearFileInfo()35*f6dc9357SAndroid Build Coastguard Worker void CFolderInStream::ClearFileInfo()
36*f6dc9357SAndroid Build Coastguard Worker {
37*f6dc9357SAndroid Build Coastguard Worker   _pos = 0;
38*f6dc9357SAndroid Build Coastguard Worker   _crc = CRC_INIT_VAL;
39*f6dc9357SAndroid Build Coastguard Worker   _size_Defined = false;
40*f6dc9357SAndroid Build Coastguard Worker   _times_Defined = false;
41*f6dc9357SAndroid Build Coastguard Worker   _size = 0;
42*f6dc9357SAndroid Build Coastguard Worker   FILETIME_Clear(_mTime);
43*f6dc9357SAndroid Build Coastguard Worker   FILETIME_Clear(_cTime);
44*f6dc9357SAndroid Build Coastguard Worker   FILETIME_Clear(_aTime);
45*f6dc9357SAndroid Build Coastguard Worker   _attrib = 0;
46*f6dc9357SAndroid Build Coastguard Worker }
47*f6dc9357SAndroid Build Coastguard Worker 
OpenStream()48*f6dc9357SAndroid Build Coastguard Worker HRESULT CFolderInStream::OpenStream()
49*f6dc9357SAndroid Build Coastguard Worker {
50*f6dc9357SAndroid Build Coastguard Worker   while (Processed.Size() < _numFiles)
51*f6dc9357SAndroid Build Coastguard Worker   {
52*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<ISequentialInStream> stream;
53*f6dc9357SAndroid Build Coastguard Worker     const HRESULT result = _updateCallback->GetStream(_indexes[Processed.Size()], &stream);
54*f6dc9357SAndroid Build Coastguard Worker     if (result != S_OK && result != S_FALSE)
55*f6dc9357SAndroid Build Coastguard Worker       return result;
56*f6dc9357SAndroid Build Coastguard Worker 
57*f6dc9357SAndroid Build Coastguard Worker     _stream = stream;
58*f6dc9357SAndroid Build Coastguard Worker 
59*f6dc9357SAndroid Build Coastguard Worker     if (stream)
60*f6dc9357SAndroid Build Coastguard Worker     {
61*f6dc9357SAndroid Build Coastguard Worker       {
62*f6dc9357SAndroid Build Coastguard Worker         CMyComPtr<IStreamGetProps> getProps;
63*f6dc9357SAndroid Build Coastguard Worker         stream.QueryInterface(IID_IStreamGetProps, (void **)&getProps);
64*f6dc9357SAndroid Build Coastguard Worker         if (getProps)
65*f6dc9357SAndroid Build Coastguard Worker         {
66*f6dc9357SAndroid Build Coastguard Worker           // access could be changed in first myx pass
67*f6dc9357SAndroid Build Coastguard Worker           if (getProps->GetProps(&_size,
68*f6dc9357SAndroid Build Coastguard Worker               Need_CTime ? &_cTime : NULL,
69*f6dc9357SAndroid Build Coastguard Worker               Need_ATime ? &_aTime : NULL,
70*f6dc9357SAndroid Build Coastguard Worker               Need_MTime ? &_mTime : NULL,
71*f6dc9357SAndroid Build Coastguard Worker               Need_Attrib ? &_attrib : NULL)
72*f6dc9357SAndroid Build Coastguard Worker               == S_OK)
73*f6dc9357SAndroid Build Coastguard Worker           {
74*f6dc9357SAndroid Build Coastguard Worker             _size_Defined = true;
75*f6dc9357SAndroid Build Coastguard Worker             _times_Defined = true;
76*f6dc9357SAndroid Build Coastguard Worker           }
77*f6dc9357SAndroid Build Coastguard Worker           return S_OK;
78*f6dc9357SAndroid Build Coastguard Worker         }
79*f6dc9357SAndroid Build Coastguard Worker       }
80*f6dc9357SAndroid Build Coastguard Worker       {
81*f6dc9357SAndroid Build Coastguard Worker         CMyComPtr<IStreamGetSize> streamGetSize;
82*f6dc9357SAndroid Build Coastguard Worker         stream.QueryInterface(IID_IStreamGetSize, &streamGetSize);
83*f6dc9357SAndroid Build Coastguard Worker         if (streamGetSize)
84*f6dc9357SAndroid Build Coastguard Worker         {
85*f6dc9357SAndroid Build Coastguard Worker           if (streamGetSize->GetSize(&_size) == S_OK)
86*f6dc9357SAndroid Build Coastguard Worker             _size_Defined = true;
87*f6dc9357SAndroid Build Coastguard Worker         }
88*f6dc9357SAndroid Build Coastguard Worker         return S_OK;
89*f6dc9357SAndroid Build Coastguard Worker       }
90*f6dc9357SAndroid Build Coastguard Worker     }
91*f6dc9357SAndroid Build Coastguard Worker 
92*f6dc9357SAndroid Build Coastguard Worker     RINOK(AddFileInfo(result == S_OK))
93*f6dc9357SAndroid Build Coastguard Worker   }
94*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
95*f6dc9357SAndroid Build Coastguard Worker }
96*f6dc9357SAndroid Build Coastguard Worker 
AddFt(CRecordVector<UInt64> & vec,const FILETIME & ft)97*f6dc9357SAndroid Build Coastguard Worker static void AddFt(CRecordVector<UInt64> &vec, const FILETIME &ft)
98*f6dc9357SAndroid Build Coastguard Worker {
99*f6dc9357SAndroid Build Coastguard Worker   vec.AddInReserved(FILETIME_To_UInt64(ft));
100*f6dc9357SAndroid Build Coastguard Worker }
101*f6dc9357SAndroid Build Coastguard Worker 
102*f6dc9357SAndroid Build Coastguard Worker /*
103*f6dc9357SAndroid Build Coastguard Worker HRESULT ReportItemProps(IArchiveUpdateCallbackArcProp *reportArcProp,
104*f6dc9357SAndroid Build Coastguard Worker     UInt32 index, UInt64 size, const UInt32 *crc)
105*f6dc9357SAndroid Build Coastguard Worker {
106*f6dc9357SAndroid Build Coastguard Worker   PROPVARIANT prop;
107*f6dc9357SAndroid Build Coastguard Worker   prop.vt = VT_EMPTY;
108*f6dc9357SAndroid Build Coastguard Worker   prop.wReserved1 = 0;
109*f6dc9357SAndroid Build Coastguard Worker 
110*f6dc9357SAndroid Build Coastguard Worker   NWindows::NCOM::PropVarEm_Set_UInt64(&prop, size);
111*f6dc9357SAndroid Build Coastguard Worker   RINOK(reportArcProp->ReportProp(NEventIndexType::kOutArcIndex, index, kpidSize, &prop));
112*f6dc9357SAndroid Build Coastguard Worker   if (crc)
113*f6dc9357SAndroid Build Coastguard Worker   {
114*f6dc9357SAndroid Build Coastguard Worker     NWindows::NCOM::PropVarEm_Set_UInt32(&prop, *crc);
115*f6dc9357SAndroid Build Coastguard Worker     RINOK(reportArcProp->ReportProp(NEventIndexType::kOutArcIndex, index, kpidCRC, &prop));
116*f6dc9357SAndroid Build Coastguard Worker   }
117*f6dc9357SAndroid Build Coastguard Worker   return reportArcProp->ReportFinished(NEventIndexType::kOutArcIndex, index, NUpdate::NOperationResult::kOK);
118*f6dc9357SAndroid Build Coastguard Worker }
119*f6dc9357SAndroid Build Coastguard Worker */
120*f6dc9357SAndroid Build Coastguard Worker 
AddFileInfo(bool isProcessed)121*f6dc9357SAndroid Build Coastguard Worker HRESULT CFolderInStream::AddFileInfo(bool isProcessed)
122*f6dc9357SAndroid Build Coastguard Worker {
123*f6dc9357SAndroid Build Coastguard Worker   // const UInt32 index = _indexes[Processed.Size()];
124*f6dc9357SAndroid Build Coastguard Worker   Processed.AddInReserved(isProcessed);
125*f6dc9357SAndroid Build Coastguard Worker   Sizes.AddInReserved(_pos);
126*f6dc9357SAndroid Build Coastguard Worker   CRCs.AddInReserved(CRC_GET_DIGEST(_crc));
127*f6dc9357SAndroid Build Coastguard Worker   if (Need_Attrib) Attribs.AddInReserved(_attrib);
128*f6dc9357SAndroid Build Coastguard Worker   TimesDefined.AddInReserved(_times_Defined);
129*f6dc9357SAndroid Build Coastguard Worker   if (Need_MTime) AddFt(MTimes, _mTime);
130*f6dc9357SAndroid Build Coastguard Worker   if (Need_CTime) AddFt(CTimes, _cTime);
131*f6dc9357SAndroid Build Coastguard Worker   if (Need_ATime) AddFt(ATimes, _aTime);
132*f6dc9357SAndroid Build Coastguard Worker   ClearFileInfo();
133*f6dc9357SAndroid Build Coastguard Worker   /*
134*f6dc9357SAndroid Build Coastguard Worker   if (isProcessed && _reportArcProp)
135*f6dc9357SAndroid Build Coastguard Worker     RINOK(ReportItemProps(_reportArcProp, index, _pos, &crc))
136*f6dc9357SAndroid Build Coastguard Worker   */
137*f6dc9357SAndroid Build Coastguard Worker   return _updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
138*f6dc9357SAndroid Build Coastguard Worker }
139*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFolderInStream::Read (void * data,UInt32 size,UInt32 * processedSize))140*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize))
141*f6dc9357SAndroid Build Coastguard Worker {
142*f6dc9357SAndroid Build Coastguard Worker   if (processedSize)
143*f6dc9357SAndroid Build Coastguard Worker     *processedSize = 0;
144*f6dc9357SAndroid Build Coastguard Worker   while (size != 0)
145*f6dc9357SAndroid Build Coastguard Worker   {
146*f6dc9357SAndroid Build Coastguard Worker     if (_stream)
147*f6dc9357SAndroid Build Coastguard Worker     {
148*f6dc9357SAndroid Build Coastguard Worker       /*
149*f6dc9357SAndroid Build Coastguard Worker       if (_pos == 0)
150*f6dc9357SAndroid Build Coastguard Worker       {
151*f6dc9357SAndroid Build Coastguard Worker         const UInt32 align = (UInt32)1 << AlignLog;
152*f6dc9357SAndroid Build Coastguard Worker         const UInt32 offset = (UInt32)_totalSize_for_Coder & (align - 1);
153*f6dc9357SAndroid Build Coastguard Worker         if (offset != 0)
154*f6dc9357SAndroid Build Coastguard Worker         {
155*f6dc9357SAndroid Build Coastguard Worker           UInt32 cur = align - offset;
156*f6dc9357SAndroid Build Coastguard Worker           if (cur > size)
157*f6dc9357SAndroid Build Coastguard Worker             cur = size;
158*f6dc9357SAndroid Build Coastguard Worker           memset(data, 0, cur);
159*f6dc9357SAndroid Build Coastguard Worker           data = (Byte *)data + cur;
160*f6dc9357SAndroid Build Coastguard Worker           size -= cur;
161*f6dc9357SAndroid Build Coastguard Worker           // _pos += cur; // for debug
162*f6dc9357SAndroid Build Coastguard Worker           _totalSize_for_Coder += cur;
163*f6dc9357SAndroid Build Coastguard Worker           if (processedSize)
164*f6dc9357SAndroid Build Coastguard Worker             *processedSize += cur;
165*f6dc9357SAndroid Build Coastguard Worker           continue;
166*f6dc9357SAndroid Build Coastguard Worker         }
167*f6dc9357SAndroid Build Coastguard Worker       }
168*f6dc9357SAndroid Build Coastguard Worker       */
169*f6dc9357SAndroid Build Coastguard Worker       UInt32 cur = size;
170*f6dc9357SAndroid Build Coastguard Worker       const UInt32 kMax = (UInt32)1 << 20;
171*f6dc9357SAndroid Build Coastguard Worker       if (cur > kMax)
172*f6dc9357SAndroid Build Coastguard Worker         cur = kMax;
173*f6dc9357SAndroid Build Coastguard Worker       RINOK(_stream->Read(data, cur, &cur))
174*f6dc9357SAndroid Build Coastguard Worker       if (cur != 0)
175*f6dc9357SAndroid Build Coastguard Worker       {
176*f6dc9357SAndroid Build Coastguard Worker         // if (Need_Crc)
177*f6dc9357SAndroid Build Coastguard Worker         _crc = CrcUpdate(_crc, data, cur);
178*f6dc9357SAndroid Build Coastguard Worker         /*
179*f6dc9357SAndroid Build Coastguard Worker         if (FolderCrc)
180*f6dc9357SAndroid Build Coastguard Worker           FolderCrc = CrcUpdate(FolderCrc, data, cur);
181*f6dc9357SAndroid Build Coastguard Worker         */
182*f6dc9357SAndroid Build Coastguard Worker         _pos += cur;
183*f6dc9357SAndroid Build Coastguard Worker         _totalSize_for_Coder += cur;
184*f6dc9357SAndroid Build Coastguard Worker         if (processedSize)
185*f6dc9357SAndroid Build Coastguard Worker           *processedSize = cur; // use +=cur, if continue is possible in loop
186*f6dc9357SAndroid Build Coastguard Worker         return S_OK;
187*f6dc9357SAndroid Build Coastguard Worker       }
188*f6dc9357SAndroid Build Coastguard Worker 
189*f6dc9357SAndroid Build Coastguard Worker       _stream.Release();
190*f6dc9357SAndroid Build Coastguard Worker       RINOK(AddFileInfo(true))
191*f6dc9357SAndroid Build Coastguard Worker     }
192*f6dc9357SAndroid Build Coastguard Worker 
193*f6dc9357SAndroid Build Coastguard Worker     if (Processed.Size() >= _numFiles)
194*f6dc9357SAndroid Build Coastguard Worker       break;
195*f6dc9357SAndroid Build Coastguard Worker     RINOK(OpenStream())
196*f6dc9357SAndroid Build Coastguard Worker   }
197*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
198*f6dc9357SAndroid Build Coastguard Worker }
199*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFolderInStream::GetSubStreamSize (UInt64 subStream,UInt64 * value))200*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value))
201*f6dc9357SAndroid Build Coastguard Worker {
202*f6dc9357SAndroid Build Coastguard Worker   *value = 0;
203*f6dc9357SAndroid Build Coastguard Worker   if (subStream > Sizes.Size())
204*f6dc9357SAndroid Build Coastguard Worker     return S_FALSE; // E_FAIL;
205*f6dc9357SAndroid Build Coastguard Worker 
206*f6dc9357SAndroid Build Coastguard Worker   const unsigned index = (unsigned)subStream;
207*f6dc9357SAndroid Build Coastguard Worker   if (index < Sizes.Size())
208*f6dc9357SAndroid Build Coastguard Worker   {
209*f6dc9357SAndroid Build Coastguard Worker     *value = Sizes[index];
210*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
211*f6dc9357SAndroid Build Coastguard Worker   }
212*f6dc9357SAndroid Build Coastguard Worker 
213*f6dc9357SAndroid Build Coastguard Worker   if (!_size_Defined)
214*f6dc9357SAndroid Build Coastguard Worker   {
215*f6dc9357SAndroid Build Coastguard Worker     *value = _pos;
216*f6dc9357SAndroid Build Coastguard Worker     return S_FALSE;
217*f6dc9357SAndroid Build Coastguard Worker   }
218*f6dc9357SAndroid Build Coastguard Worker 
219*f6dc9357SAndroid Build Coastguard Worker   *value = (_pos > _size ? _pos : _size);
220*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
221*f6dc9357SAndroid Build Coastguard Worker }
222*f6dc9357SAndroid Build Coastguard Worker 
223*f6dc9357SAndroid Build Coastguard Worker 
224*f6dc9357SAndroid Build Coastguard Worker /*
225*f6dc9357SAndroid Build Coastguard Worker HRESULT CFolderInStream::CloseCrcStream()
226*f6dc9357SAndroid Build Coastguard Worker {
227*f6dc9357SAndroid Build Coastguard Worker   if (!_crcStream)
228*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
229*f6dc9357SAndroid Build Coastguard Worker   if (!_crcStream_Spec->WasFinished())
230*f6dc9357SAndroid Build Coastguard Worker     return E_FAIL;
231*f6dc9357SAndroid Build Coastguard Worker   _crc = _crcStream_Spec->GetCRC() ^ CRC_INIT_VAL; // change it
232*f6dc9357SAndroid Build Coastguard Worker   const UInt64 size = _crcStream_Spec->GetSize();
233*f6dc9357SAndroid Build Coastguard Worker   _pos = size;
234*f6dc9357SAndroid Build Coastguard Worker   _totalSize_for_Coder += size;
235*f6dc9357SAndroid Build Coastguard Worker   _crcStream.Release();
236*f6dc9357SAndroid Build Coastguard Worker   // _crcStream->ReleaseStream();
237*f6dc9357SAndroid Build Coastguard Worker   _stream.Release();
238*f6dc9357SAndroid Build Coastguard Worker   return AddFileInfo(true);
239*f6dc9357SAndroid Build Coastguard Worker }
240*f6dc9357SAndroid Build Coastguard Worker 
241*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFolderInStream::GetNextInSubStream(UInt64 *streamIndexRes, ISequentialInStream **stream)
242*f6dc9357SAndroid Build Coastguard Worker {
243*f6dc9357SAndroid Build Coastguard Worker   RINOK(CloseCrcStream())
244*f6dc9357SAndroid Build Coastguard Worker   *stream = NULL;
245*f6dc9357SAndroid Build Coastguard Worker   *streamIndexRes = Processed.Size();
246*f6dc9357SAndroid Build Coastguard Worker   if (Processed.Size() >= _numFiles)
247*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
248*f6dc9357SAndroid Build Coastguard Worker   RINOK(OpenStream());
249*f6dc9357SAndroid Build Coastguard Worker   if (!_stream)
250*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
251*f6dc9357SAndroid Build Coastguard Worker   if (!_crcStream)
252*f6dc9357SAndroid Build Coastguard Worker   {
253*f6dc9357SAndroid Build Coastguard Worker     _crcStream_Spec = new CSequentialInStreamWithCRC;
254*f6dc9357SAndroid Build Coastguard Worker     _crcStream = _crcStream_Spec;
255*f6dc9357SAndroid Build Coastguard Worker   }
256*f6dc9357SAndroid Build Coastguard Worker   _crcStream_Spec->Init();
257*f6dc9357SAndroid Build Coastguard Worker   _crcStream_Spec->SetStream(_stream);
258*f6dc9357SAndroid Build Coastguard Worker   *stream = _crcStream;
259*f6dc9357SAndroid Build Coastguard Worker   _crcStream->AddRef();
260*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
261*f6dc9357SAndroid Build Coastguard Worker }
262*f6dc9357SAndroid Build Coastguard Worker */
263*f6dc9357SAndroid Build Coastguard Worker 
264*f6dc9357SAndroid Build Coastguard Worker }}
265