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