1370b324cSopenharmony_ci// 7zFolderInStream.cpp
2370b324cSopenharmony_ci
3370b324cSopenharmony_ci#include "StdAfx.h"
4370b324cSopenharmony_ci
5370b324cSopenharmony_ci#include "../../../Windows/TimeUtils.h"
6370b324cSopenharmony_ci
7370b324cSopenharmony_ci#include "7zFolderInStream.h"
8370b324cSopenharmony_ci
9370b324cSopenharmony_cinamespace NArchive {
10370b324cSopenharmony_cinamespace N7z {
11370b324cSopenharmony_ci
12370b324cSopenharmony_civoid CFolderInStream::Init(IArchiveUpdateCallback *updateCallback,
13370b324cSopenharmony_ci    const UInt32 *indexes, unsigned numFiles)
14370b324cSopenharmony_ci{
15370b324cSopenharmony_ci  _updateCallback = updateCallback;
16370b324cSopenharmony_ci  _indexes = indexes;
17370b324cSopenharmony_ci  _numFiles = numFiles;
18370b324cSopenharmony_ci
19370b324cSopenharmony_ci  _totalSize_for_Coder = 0;
20370b324cSopenharmony_ci  ClearFileInfo();
21370b324cSopenharmony_ci
22370b324cSopenharmony_ci  Processed.ClearAndReserve(numFiles);
23370b324cSopenharmony_ci  Sizes.ClearAndReserve(numFiles);
24370b324cSopenharmony_ci  CRCs.ClearAndReserve(numFiles);
25370b324cSopenharmony_ci  TimesDefined.ClearAndReserve(numFiles);
26370b324cSopenharmony_ci  MTimes.ClearAndReserve(Need_MTime ? numFiles : (unsigned)0);
27370b324cSopenharmony_ci  CTimes.ClearAndReserve(Need_CTime ? numFiles : (unsigned)0);
28370b324cSopenharmony_ci  ATimes.ClearAndReserve(Need_ATime ? numFiles : (unsigned)0);
29370b324cSopenharmony_ci  Attribs.ClearAndReserve(Need_Attrib ? numFiles : (unsigned)0);
30370b324cSopenharmony_ci
31370b324cSopenharmony_ci  // FolderCrc = CRC_INIT_VAL;
32370b324cSopenharmony_ci  _stream.Release();
33370b324cSopenharmony_ci}
34370b324cSopenharmony_ci
35370b324cSopenharmony_civoid CFolderInStream::ClearFileInfo()
36370b324cSopenharmony_ci{
37370b324cSopenharmony_ci  _pos = 0;
38370b324cSopenharmony_ci  _crc = CRC_INIT_VAL;
39370b324cSopenharmony_ci  _size_Defined = false;
40370b324cSopenharmony_ci  _times_Defined = false;
41370b324cSopenharmony_ci  _size = 0;
42370b324cSopenharmony_ci  FILETIME_Clear(_mTime);
43370b324cSopenharmony_ci  FILETIME_Clear(_cTime);
44370b324cSopenharmony_ci  FILETIME_Clear(_aTime);
45370b324cSopenharmony_ci  _attrib = 0;
46370b324cSopenharmony_ci}
47370b324cSopenharmony_ci
48370b324cSopenharmony_ciHRESULT CFolderInStream::OpenStream()
49370b324cSopenharmony_ci{
50370b324cSopenharmony_ci  while (Processed.Size() < _numFiles)
51370b324cSopenharmony_ci  {
52370b324cSopenharmony_ci    CMyComPtr<ISequentialInStream> stream;
53370b324cSopenharmony_ci    const HRESULT result = _updateCallback->GetStream(_indexes[Processed.Size()], &stream);
54370b324cSopenharmony_ci    if (result != S_OK && result != S_FALSE)
55370b324cSopenharmony_ci      return result;
56370b324cSopenharmony_ci
57370b324cSopenharmony_ci    _stream = stream;
58370b324cSopenharmony_ci
59370b324cSopenharmony_ci    if (stream)
60370b324cSopenharmony_ci    {
61370b324cSopenharmony_ci      {
62370b324cSopenharmony_ci        CMyComPtr<IStreamGetProps> getProps;
63370b324cSopenharmony_ci        stream.QueryInterface(IID_IStreamGetProps, (void **)&getProps);
64370b324cSopenharmony_ci        if (getProps)
65370b324cSopenharmony_ci        {
66370b324cSopenharmony_ci          // access could be changed in first myx pass
67370b324cSopenharmony_ci          if (getProps->GetProps(&_size,
68370b324cSopenharmony_ci              Need_CTime ? &_cTime : NULL,
69370b324cSopenharmony_ci              Need_ATime ? &_aTime : NULL,
70370b324cSopenharmony_ci              Need_MTime ? &_mTime : NULL,
71370b324cSopenharmony_ci              Need_Attrib ? &_attrib : NULL)
72370b324cSopenharmony_ci              == S_OK)
73370b324cSopenharmony_ci          {
74370b324cSopenharmony_ci            _size_Defined = true;
75370b324cSopenharmony_ci            _times_Defined = true;
76370b324cSopenharmony_ci          }
77370b324cSopenharmony_ci          return S_OK;
78370b324cSopenharmony_ci        }
79370b324cSopenharmony_ci      }
80370b324cSopenharmony_ci      {
81370b324cSopenharmony_ci        CMyComPtr<IStreamGetSize> streamGetSize;
82370b324cSopenharmony_ci        stream.QueryInterface(IID_IStreamGetSize, &streamGetSize);
83370b324cSopenharmony_ci        if (streamGetSize)
84370b324cSopenharmony_ci        {
85370b324cSopenharmony_ci          if (streamGetSize->GetSize(&_size) == S_OK)
86370b324cSopenharmony_ci            _size_Defined = true;
87370b324cSopenharmony_ci        }
88370b324cSopenharmony_ci        return S_OK;
89370b324cSopenharmony_ci      }
90370b324cSopenharmony_ci    }
91370b324cSopenharmony_ci
92370b324cSopenharmony_ci    RINOK(AddFileInfo(result == S_OK))
93370b324cSopenharmony_ci  }
94370b324cSopenharmony_ci  return S_OK;
95370b324cSopenharmony_ci}
96370b324cSopenharmony_ci
97370b324cSopenharmony_cistatic void AddFt(CRecordVector<UInt64> &vec, const FILETIME &ft)
98370b324cSopenharmony_ci{
99370b324cSopenharmony_ci  vec.AddInReserved(FILETIME_To_UInt64(ft));
100370b324cSopenharmony_ci}
101370b324cSopenharmony_ci
102370b324cSopenharmony_ci/*
103370b324cSopenharmony_ciHRESULT ReportItemProps(IArchiveUpdateCallbackArcProp *reportArcProp,
104370b324cSopenharmony_ci    UInt32 index, UInt64 size, const UInt32 *crc)
105370b324cSopenharmony_ci{
106370b324cSopenharmony_ci  PROPVARIANT prop;
107370b324cSopenharmony_ci  prop.vt = VT_EMPTY;
108370b324cSopenharmony_ci  prop.wReserved1 = 0;
109370b324cSopenharmony_ci
110370b324cSopenharmony_ci  NWindows::NCOM::PropVarEm_Set_UInt64(&prop, size);
111370b324cSopenharmony_ci  RINOK(reportArcProp->ReportProp(NEventIndexType::kOutArcIndex, index, kpidSize, &prop));
112370b324cSopenharmony_ci  if (crc)
113370b324cSopenharmony_ci  {
114370b324cSopenharmony_ci    NWindows::NCOM::PropVarEm_Set_UInt32(&prop, *crc);
115370b324cSopenharmony_ci    RINOK(reportArcProp->ReportProp(NEventIndexType::kOutArcIndex, index, kpidCRC, &prop));
116370b324cSopenharmony_ci  }
117370b324cSopenharmony_ci  return reportArcProp->ReportFinished(NEventIndexType::kOutArcIndex, index, NUpdate::NOperationResult::kOK);
118370b324cSopenharmony_ci}
119370b324cSopenharmony_ci*/
120370b324cSopenharmony_ci
121370b324cSopenharmony_ciHRESULT CFolderInStream::AddFileInfo(bool isProcessed)
122370b324cSopenharmony_ci{
123370b324cSopenharmony_ci  // const UInt32 index = _indexes[Processed.Size()];
124370b324cSopenharmony_ci  Processed.AddInReserved(isProcessed);
125370b324cSopenharmony_ci  Sizes.AddInReserved(_pos);
126370b324cSopenharmony_ci  CRCs.AddInReserved(CRC_GET_DIGEST(_crc));
127370b324cSopenharmony_ci  if (Need_Attrib) Attribs.AddInReserved(_attrib);
128370b324cSopenharmony_ci  TimesDefined.AddInReserved(_times_Defined);
129370b324cSopenharmony_ci  if (Need_MTime) AddFt(MTimes, _mTime);
130370b324cSopenharmony_ci  if (Need_CTime) AddFt(CTimes, _cTime);
131370b324cSopenharmony_ci  if (Need_ATime) AddFt(ATimes, _aTime);
132370b324cSopenharmony_ci  ClearFileInfo();
133370b324cSopenharmony_ci  /*
134370b324cSopenharmony_ci  if (isProcessed && _reportArcProp)
135370b324cSopenharmony_ci    RINOK(ReportItemProps(_reportArcProp, index, _pos, &crc))
136370b324cSopenharmony_ci  */
137370b324cSopenharmony_ci  return _updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
138370b324cSopenharmony_ci}
139370b324cSopenharmony_ci
140370b324cSopenharmony_ciZ7_COM7F_IMF(CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize))
141370b324cSopenharmony_ci{
142370b324cSopenharmony_ci  if (processedSize)
143370b324cSopenharmony_ci    *processedSize = 0;
144370b324cSopenharmony_ci  while (size != 0)
145370b324cSopenharmony_ci  {
146370b324cSopenharmony_ci    if (_stream)
147370b324cSopenharmony_ci    {
148370b324cSopenharmony_ci      /*
149370b324cSopenharmony_ci      if (_pos == 0)
150370b324cSopenharmony_ci      {
151370b324cSopenharmony_ci        const UInt32 align = (UInt32)1 << AlignLog;
152370b324cSopenharmony_ci        const UInt32 offset = (UInt32)_totalSize_for_Coder & (align - 1);
153370b324cSopenharmony_ci        if (offset != 0)
154370b324cSopenharmony_ci        {
155370b324cSopenharmony_ci          UInt32 cur = align - offset;
156370b324cSopenharmony_ci          if (cur > size)
157370b324cSopenharmony_ci            cur = size;
158370b324cSopenharmony_ci          memset(data, 0, cur);
159370b324cSopenharmony_ci          data = (Byte *)data + cur;
160370b324cSopenharmony_ci          size -= cur;
161370b324cSopenharmony_ci          // _pos += cur; // for debug
162370b324cSopenharmony_ci          _totalSize_for_Coder += cur;
163370b324cSopenharmony_ci          if (processedSize)
164370b324cSopenharmony_ci            *processedSize += cur;
165370b324cSopenharmony_ci          continue;
166370b324cSopenharmony_ci        }
167370b324cSopenharmony_ci      }
168370b324cSopenharmony_ci      */
169370b324cSopenharmony_ci      UInt32 cur = size;
170370b324cSopenharmony_ci      const UInt32 kMax = (UInt32)1 << 20;
171370b324cSopenharmony_ci      if (cur > kMax)
172370b324cSopenharmony_ci        cur = kMax;
173370b324cSopenharmony_ci      RINOK(_stream->Read(data, cur, &cur))
174370b324cSopenharmony_ci      if (cur != 0)
175370b324cSopenharmony_ci      {
176370b324cSopenharmony_ci        // if (Need_Crc)
177370b324cSopenharmony_ci        _crc = CrcUpdate(_crc, data, cur);
178370b324cSopenharmony_ci        /*
179370b324cSopenharmony_ci        if (FolderCrc)
180370b324cSopenharmony_ci          FolderCrc = CrcUpdate(FolderCrc, data, cur);
181370b324cSopenharmony_ci        */
182370b324cSopenharmony_ci        _pos += cur;
183370b324cSopenharmony_ci        _totalSize_for_Coder += cur;
184370b324cSopenharmony_ci        if (processedSize)
185370b324cSopenharmony_ci          *processedSize = cur; // use +=cur, if continue is possible in loop
186370b324cSopenharmony_ci        return S_OK;
187370b324cSopenharmony_ci      }
188370b324cSopenharmony_ci
189370b324cSopenharmony_ci      _stream.Release();
190370b324cSopenharmony_ci      RINOK(AddFileInfo(true))
191370b324cSopenharmony_ci    }
192370b324cSopenharmony_ci
193370b324cSopenharmony_ci    if (Processed.Size() >= _numFiles)
194370b324cSopenharmony_ci      break;
195370b324cSopenharmony_ci    RINOK(OpenStream())
196370b324cSopenharmony_ci  }
197370b324cSopenharmony_ci  return S_OK;
198370b324cSopenharmony_ci}
199370b324cSopenharmony_ci
200370b324cSopenharmony_ciZ7_COM7F_IMF(CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value))
201370b324cSopenharmony_ci{
202370b324cSopenharmony_ci  *value = 0;
203370b324cSopenharmony_ci  if (subStream > Sizes.Size())
204370b324cSopenharmony_ci    return S_FALSE; // E_FAIL;
205370b324cSopenharmony_ci
206370b324cSopenharmony_ci  const unsigned index = (unsigned)subStream;
207370b324cSopenharmony_ci  if (index < Sizes.Size())
208370b324cSopenharmony_ci  {
209370b324cSopenharmony_ci    *value = Sizes[index];
210370b324cSopenharmony_ci    return S_OK;
211370b324cSopenharmony_ci  }
212370b324cSopenharmony_ci
213370b324cSopenharmony_ci  if (!_size_Defined)
214370b324cSopenharmony_ci  {
215370b324cSopenharmony_ci    *value = _pos;
216370b324cSopenharmony_ci    return S_FALSE;
217370b324cSopenharmony_ci  }
218370b324cSopenharmony_ci
219370b324cSopenharmony_ci  *value = (_pos > _size ? _pos : _size);
220370b324cSopenharmony_ci  return S_OK;
221370b324cSopenharmony_ci}
222370b324cSopenharmony_ci
223370b324cSopenharmony_ci
224370b324cSopenharmony_ci/*
225370b324cSopenharmony_ciHRESULT CFolderInStream::CloseCrcStream()
226370b324cSopenharmony_ci{
227370b324cSopenharmony_ci  if (!_crcStream)
228370b324cSopenharmony_ci    return S_OK;
229370b324cSopenharmony_ci  if (!_crcStream_Spec->WasFinished())
230370b324cSopenharmony_ci    return E_FAIL;
231370b324cSopenharmony_ci  _crc = _crcStream_Spec->GetCRC() ^ CRC_INIT_VAL; // change it
232370b324cSopenharmony_ci  const UInt64 size = _crcStream_Spec->GetSize();
233370b324cSopenharmony_ci  _pos = size;
234370b324cSopenharmony_ci  _totalSize_for_Coder += size;
235370b324cSopenharmony_ci  _crcStream.Release();
236370b324cSopenharmony_ci  // _crcStream->ReleaseStream();
237370b324cSopenharmony_ci  _stream.Release();
238370b324cSopenharmony_ci  return AddFileInfo(true);
239370b324cSopenharmony_ci}
240370b324cSopenharmony_ci
241370b324cSopenharmony_ciZ7_COM7F_IMF(CFolderInStream::GetNextInSubStream(UInt64 *streamIndexRes, ISequentialInStream **stream)
242370b324cSopenharmony_ci{
243370b324cSopenharmony_ci  RINOK(CloseCrcStream())
244370b324cSopenharmony_ci  *stream = NULL;
245370b324cSopenharmony_ci  *streamIndexRes = Processed.Size();
246370b324cSopenharmony_ci  if (Processed.Size() >= _numFiles)
247370b324cSopenharmony_ci    return S_OK;
248370b324cSopenharmony_ci  RINOK(OpenStream());
249370b324cSopenharmony_ci  if (!_stream)
250370b324cSopenharmony_ci    return S_OK;
251370b324cSopenharmony_ci  if (!_crcStream)
252370b324cSopenharmony_ci  {
253370b324cSopenharmony_ci    _crcStream_Spec = new CSequentialInStreamWithCRC;
254370b324cSopenharmony_ci    _crcStream = _crcStream_Spec;
255370b324cSopenharmony_ci  }
256370b324cSopenharmony_ci  _crcStream_Spec->Init();
257370b324cSopenharmony_ci  _crcStream_Spec->SetStream(_stream);
258370b324cSopenharmony_ci  *stream = _crcStream;
259370b324cSopenharmony_ci  _crcStream->AddRef();
260370b324cSopenharmony_ci  return S_OK;
261370b324cSopenharmony_ci}
262370b324cSopenharmony_ci*/
263370b324cSopenharmony_ci
264370b324cSopenharmony_ci}}
265