• 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   Processed.ClearAndReserve(numFiles);
20   CRCs.ClearAndReserve(numFiles);
21   Sizes.ClearAndReserve(numFiles);
22 
23   if (Need_CTime) CTimes.ClearAndReserve(numFiles);
24   if (Need_ATime) ATimes.ClearAndReserve(numFiles);
25   if (Need_MTime) MTimes.ClearAndReserve(numFiles);
26   if (Need_Attrib) Attribs.ClearAndReserve(numFiles);
27   TimesDefined.ClearAndReserve(numFiles);
28 
29   _stream.Release();
30 }
31 
OpenStream()32 HRESULT CFolderInStream::OpenStream()
33 {
34   _pos = 0;
35   _crc = CRC_INIT_VAL;
36   _size_Defined = false;
37   _times_Defined = false;
38   _size = 0;
39   FILETIME_Clear(_cTime);
40   FILETIME_Clear(_aTime);
41   FILETIME_Clear(_mTime);
42   _attrib = 0;
43 
44   while (Processed.Size() < _numFiles)
45   {
46     CMyComPtr<ISequentialInStream> stream;
47     const HRESULT result = _updateCallback->GetStream(_indexes[Processed.Size()], &stream);
48     if (result != S_OK && result != S_FALSE)
49       return result;
50 
51     _stream = stream;
52 
53     if (stream)
54     {
55       {
56         CMyComPtr<IStreamGetProps> getProps;
57         stream.QueryInterface(IID_IStreamGetProps, (void **)&getProps);
58         if (getProps)
59         {
60           // access could be changed in first myx pass
61           if (getProps->GetProps(&_size,
62               Need_CTime ? &_cTime : NULL,
63               Need_ATime ? &_aTime : NULL,
64               Need_MTime ? &_mTime : NULL,
65               Need_Attrib ? &_attrib : NULL)
66               == S_OK)
67           {
68             _size_Defined = true;
69             _times_Defined = true;
70           }
71           return S_OK;
72         }
73       }
74       {
75         CMyComPtr<IStreamGetSize> streamGetSize;
76         stream.QueryInterface(IID_IStreamGetSize, &streamGetSize);
77         if (streamGetSize)
78         {
79           if (streamGetSize->GetSize(&_size) == S_OK)
80             _size_Defined = true;
81         }
82         return S_OK;
83       }
84     }
85 
86     RINOK(AddFileInfo(result == S_OK));
87   }
88   return S_OK;
89 }
90 
AddFt(CRecordVector<UInt64> & vec,const FILETIME & ft)91 static void AddFt(CRecordVector<UInt64> &vec, const FILETIME &ft)
92 {
93   vec.AddInReserved(FILETIME_To_UInt64(ft));
94 }
95 
96 /*
97 HRESULT ReportItemProps(IArchiveUpdateCallbackArcProp *reportArcProp,
98     UInt32 index, UInt64 size, const UInt32 *crc)
99 {
100   PROPVARIANT prop;
101   prop.vt = VT_EMPTY;
102   prop.wReserved1 = 0;
103 
104   NWindows::NCOM::PropVarEm_Set_UInt64(&prop, size);
105   RINOK(reportArcProp->ReportProp(NEventIndexType::kOutArcIndex, index, kpidSize, &prop));
106   if (crc)
107   {
108     NWindows::NCOM::PropVarEm_Set_UInt32(&prop, *crc);
109     RINOK(reportArcProp->ReportProp(NEventIndexType::kOutArcIndex, index, kpidCRC, &prop));
110   }
111   return reportArcProp->ReportFinished(NEventIndexType::kOutArcIndex, index, NUpdate::NOperationResult::kOK);
112 }
113 */
114 
AddFileInfo(bool isProcessed)115 HRESULT CFolderInStream::AddFileInfo(bool isProcessed)
116 {
117   // const UInt32 index = _indexes[Processed.Size()];
118   Processed.AddInReserved(isProcessed);
119   Sizes.AddInReserved(_pos);
120   const UInt32 crc = CRC_GET_DIGEST(_crc);
121   CRCs.AddInReserved(crc);
122   TimesDefined.AddInReserved(_times_Defined);
123   if (Need_CTime) AddFt(CTimes, _cTime);
124   if (Need_ATime) AddFt(ATimes, _aTime);
125   if (Need_MTime) AddFt(MTimes, _mTime);
126   if (Need_Attrib) Attribs.AddInReserved(_attrib);
127   /*
128   if (isProcessed && _reportArcProp)
129     RINOK(ReportItemProps(_reportArcProp, index, _pos, &crc))
130   */
131   return _updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
132 }
133 
Read(void * data,UInt32 size,UInt32 * processedSize)134 STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
135 {
136   if (processedSize)
137     *processedSize = 0;
138   while (size != 0)
139   {
140     if (_stream)
141     {
142       UInt32 cur = size;
143       const UInt32 kMax = (UInt32)1 << 20;
144       if (cur > kMax)
145         cur = kMax;
146       RINOK(_stream->Read(data, cur, &cur));
147       if (cur != 0)
148       {
149         _crc = CrcUpdate(_crc, data, cur);
150         _pos += cur;
151         if (processedSize)
152           *processedSize = cur;
153         return S_OK;
154       }
155 
156       _stream.Release();
157       RINOK(AddFileInfo(true));
158     }
159 
160     if (Processed.Size() >= _numFiles)
161       break;
162     RINOK(OpenStream());
163   }
164   return S_OK;
165 }
166 
GetSubStreamSize(UInt64 subStream,UInt64 * value)167 STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)
168 {
169   *value = 0;
170   if (subStream > Sizes.Size())
171     return S_FALSE; // E_FAIL;
172 
173   unsigned index = (unsigned)subStream;
174   if (index < Sizes.Size())
175   {
176     *value = Sizes[index];
177     return S_OK;
178   }
179 
180   if (!_size_Defined)
181   {
182     *value = _pos;
183     return S_FALSE;
184   }
185 
186   *value = (_pos > _size ? _pos : _size);
187   return S_OK;
188 }
189 
190 }}
191