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