1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zFolderOutStream.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,161 @@ 1.4 +// 7zFolderOutStream.cpp 1.5 + 1.6 +#include "StdAfx.h" 1.7 + 1.8 +#include "7zFolderOutStream.h" 1.9 + 1.10 +namespace NArchive { 1.11 +namespace N7z { 1.12 + 1.13 +CFolderOutStream::CFolderOutStream() 1.14 +{ 1.15 + _outStreamWithHashSpec = new COutStreamWithCRC; 1.16 + _outStreamWithHash = _outStreamWithHashSpec; 1.17 +} 1.18 + 1.19 +HRESULT CFolderOutStream::Init( 1.20 + const CArchiveDatabaseEx *archiveDatabase, 1.21 + UInt32 ref2Offset, 1.22 + UInt32 startIndex, 1.23 + const CBoolVector *extractStatuses, 1.24 + IArchiveExtractCallback *extractCallback, 1.25 + bool testMode) 1.26 +{ 1.27 + _archiveDatabase = archiveDatabase; 1.28 + _ref2Offset = ref2Offset; 1.29 + _startIndex = startIndex; 1.30 + 1.31 + _extractStatuses = extractStatuses; 1.32 + _extractCallback = extractCallback; 1.33 + _testMode = testMode; 1.34 + 1.35 + _currentIndex = 0; 1.36 + _fileIsOpen = false; 1.37 + return WriteEmptyFiles(); 1.38 +} 1.39 + 1.40 +HRESULT CFolderOutStream::OpenFile() 1.41 +{ 1.42 + Int32 askMode; 1.43 + if((*_extractStatuses)[_currentIndex]) 1.44 + askMode = _testMode ? 1.45 + NArchive::NExtract::NAskMode::kTest : 1.46 + NArchive::NExtract::NAskMode::kExtract; 1.47 + else 1.48 + askMode = NArchive::NExtract::NAskMode::kSkip; 1.49 + CMyComPtr<ISequentialOutStream> realOutStream; 1.50 + 1.51 + UInt32 index = _startIndex + _currentIndex; 1.52 + RINOK(_extractCallback->GetStream(_ref2Offset + index, &realOutStream, askMode)); 1.53 + 1.54 + _outStreamWithHashSpec->Init(realOutStream); 1.55 + if (askMode == NArchive::NExtract::NAskMode::kExtract && 1.56 + (!realOutStream)) 1.57 + { 1.58 + const CFileItem &fileInfo = _archiveDatabase->Files[index]; 1.59 + if (!fileInfo.IsAnti && !fileInfo.IsDirectory) 1.60 + askMode = NArchive::NExtract::NAskMode::kSkip; 1.61 + } 1.62 + return _extractCallback->PrepareOperation(askMode); 1.63 +} 1.64 + 1.65 +HRESULT CFolderOutStream::WriteEmptyFiles() 1.66 +{ 1.67 + for(;_currentIndex < _extractStatuses->Size(); _currentIndex++) 1.68 + { 1.69 + UInt32 index = _startIndex + _currentIndex; 1.70 + const CFileItem &fileInfo = _archiveDatabase->Files[index]; 1.71 + if (!fileInfo.IsAnti && !fileInfo.IsDirectory && fileInfo.UnPackSize != 0) 1.72 + return S_OK; 1.73 + RINOK(OpenFile()); 1.74 + RINOK(_extractCallback->SetOperationResult( 1.75 + NArchive::NExtract::NOperationResult::kOK)); 1.76 + _outStreamWithHashSpec->ReleaseStream(); 1.77 + } 1.78 + return S_OK; 1.79 +} 1.80 + 1.81 +STDMETHODIMP CFolderOutStream::Write(const void *data, 1.82 + UInt32 size, UInt32 *processedSize) 1.83 +{ 1.84 + UInt32 realProcessedSize = 0; 1.85 + while(_currentIndex < _extractStatuses->Size()) 1.86 + { 1.87 + if (_fileIsOpen) 1.88 + { 1.89 + UInt32 index = _startIndex + _currentIndex; 1.90 + const CFileItem &fileInfo = _archiveDatabase->Files[index]; 1.91 + UInt64 fileSize = fileInfo.UnPackSize; 1.92 + 1.93 + UInt32 numBytesToWrite = (UInt32)MyMin(fileSize - _filePos, 1.94 + UInt64(size - realProcessedSize)); 1.95 + 1.96 + UInt32 processedSizeLocal; 1.97 + RINOK(_outStreamWithHash->Write((const Byte *)data + realProcessedSize, 1.98 + numBytesToWrite, &processedSizeLocal)); 1.99 + 1.100 + _filePos += processedSizeLocal; 1.101 + realProcessedSize += processedSizeLocal; 1.102 + if (_filePos == fileSize) 1.103 + { 1.104 + bool digestsAreEqual; 1.105 + if (fileInfo.IsFileCRCDefined) 1.106 + digestsAreEqual = fileInfo.FileCRC == _outStreamWithHashSpec->GetCRC(); 1.107 + else 1.108 + digestsAreEqual = true; 1.109 + 1.110 + RINOK(_extractCallback->SetOperationResult( 1.111 + digestsAreEqual ? 1.112 + NArchive::NExtract::NOperationResult::kOK : 1.113 + NArchive::NExtract::NOperationResult::kCRCError)); 1.114 + _outStreamWithHashSpec->ReleaseStream(); 1.115 + _fileIsOpen = false; 1.116 + _currentIndex++; 1.117 + } 1.118 + if (realProcessedSize == size) 1.119 + { 1.120 + if (processedSize != NULL) 1.121 + *processedSize = realProcessedSize; 1.122 + return WriteEmptyFiles(); 1.123 + } 1.124 + } 1.125 + else 1.126 + { 1.127 + RINOK(OpenFile()); 1.128 + _fileIsOpen = true; 1.129 + _filePos = 0; 1.130 + } 1.131 + } 1.132 + if (processedSize != NULL) 1.133 + *processedSize = size; 1.134 + return S_OK; 1.135 +} 1.136 + 1.137 +HRESULT CFolderOutStream::FlushCorrupted(Int32 resultEOperationResult) 1.138 +{ 1.139 + while(_currentIndex < _extractStatuses->Size()) 1.140 + { 1.141 + if (_fileIsOpen) 1.142 + { 1.143 + RINOK(_extractCallback->SetOperationResult(resultEOperationResult)); 1.144 + _outStreamWithHashSpec->ReleaseStream(); 1.145 + _fileIsOpen = false; 1.146 + _currentIndex++; 1.147 + } 1.148 + else 1.149 + { 1.150 + RINOK(OpenFile()); 1.151 + _fileIsOpen = true; 1.152 + } 1.153 + } 1.154 + return S_OK; 1.155 +} 1.156 + 1.157 +HRESULT CFolderOutStream::WasWritingFinished() 1.158 +{ 1.159 + if (_currentIndex == _extractStatuses->Size()) 1.160 + return S_OK; 1.161 + return E_FAIL; 1.162 +} 1.163 + 1.164 +}}