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