Mercurial > vba-linux
diff src/win32/7zip/7z/CPP/7zip/Archive/7z/7zExtract.cpp @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/win32/7zip/7z/CPP/7zip/Archive/7z/7zExtract.cpp Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,273 @@ 1.4 +// 7zExtract.cpp 1.5 + 1.6 +#include "StdAfx.h" 1.7 + 1.8 +#include "7zHandler.h" 1.9 +#include "7zFolderOutStream.h" 1.10 +#include "7zDecode.h" 1.11 +// #include "7z1Decode.h" 1.12 + 1.13 +#include "../../../Common/ComTry.h" 1.14 +#include "../../Common/StreamObjects.h" 1.15 +#include "../../Common/ProgressUtils.h" 1.16 +#include "../../Common/LimitedStreams.h" 1.17 + 1.18 +namespace NArchive { 1.19 +namespace N7z { 1.20 + 1.21 +struct CExtractFolderInfo 1.22 +{ 1.23 + #ifdef _7Z_VOL 1.24 + int VolumeIndex; 1.25 + #endif 1.26 + CNum FileIndex; 1.27 + CNum FolderIndex; 1.28 + CBoolVector ExtractStatuses; 1.29 + UInt64 UnpackSize; 1.30 + CExtractFolderInfo( 1.31 + #ifdef _7Z_VOL 1.32 + int volumeIndex, 1.33 + #endif 1.34 + CNum fileIndex, CNum folderIndex): 1.35 + #ifdef _7Z_VOL 1.36 + VolumeIndex(volumeIndex), 1.37 + #endif 1.38 + FileIndex(fileIndex), 1.39 + FolderIndex(folderIndex), 1.40 + UnpackSize(0) 1.41 + { 1.42 + if (fileIndex != kNumNoIndex) 1.43 + { 1.44 + ExtractStatuses.Reserve(1); 1.45 + ExtractStatuses.Add(true); 1.46 + } 1.47 + }; 1.48 +}; 1.49 + 1.50 +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, 1.51 + Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec) 1.52 +{ 1.53 + COM_TRY_BEGIN 1.54 + bool testMode = (testModeSpec != 0); 1.55 + CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec; 1.56 + UInt64 importantTotalUnpacked = 0; 1.57 + 1.58 + bool allFilesMode = (numItems == UInt32(-1)); 1.59 + if (allFilesMode) 1.60 + numItems = 1.61 + #ifdef _7Z_VOL 1.62 + _refs.Size(); 1.63 + #else 1.64 + _db.Files.Size(); 1.65 + #endif 1.66 + 1.67 + if(numItems == 0) 1.68 + return S_OK; 1.69 + 1.70 + /* 1.71 + if(_volumes.Size() != 1) 1.72 + return E_FAIL; 1.73 + const CVolume &volume = _volumes.Front(); 1.74 + const CArchiveDatabaseEx &_db = volume.Database; 1.75 + IInStream *_inStream = volume.Stream; 1.76 + */ 1.77 + 1.78 + CObjectVector<CExtractFolderInfo> extractFolderInfoVector; 1.79 + for(UInt32 ii = 0; ii < numItems; ii++) 1.80 + { 1.81 + // UInt32 fileIndex = allFilesMode ? indexIndex : indices[indexIndex]; 1.82 + UInt32 ref2Index = allFilesMode ? ii : indices[ii]; 1.83 + // const CRef2 &ref2 = _refs[ref2Index]; 1.84 + 1.85 + // for(UInt32 ri = 0; ri < ref2.Refs.Size(); ri++) 1.86 + { 1.87 + #ifdef _7Z_VOL 1.88 + // const CRef &ref = ref2.Refs[ri]; 1.89 + const CRef &ref = _refs[ref2Index]; 1.90 + 1.91 + int volumeIndex = ref.VolumeIndex; 1.92 + const CVolume &volume = _volumes[volumeIndex]; 1.93 + const CArchiveDatabaseEx &db = volume.Database; 1.94 + UInt32 fileIndex = ref.ItemIndex; 1.95 + #else 1.96 + const CArchiveDatabaseEx &db = _db; 1.97 + UInt32 fileIndex = ref2Index; 1.98 + #endif 1.99 + 1.100 + CNum folderIndex = db.FileIndexToFolderIndexMap[fileIndex]; 1.101 + if (folderIndex == kNumNoIndex) 1.102 + { 1.103 + extractFolderInfoVector.Add(CExtractFolderInfo( 1.104 + #ifdef _7Z_VOL 1.105 + volumeIndex, 1.106 + #endif 1.107 + fileIndex, kNumNoIndex)); 1.108 + continue; 1.109 + } 1.110 + if (extractFolderInfoVector.IsEmpty() || 1.111 + folderIndex != extractFolderInfoVector.Back().FolderIndex 1.112 + #ifdef _7Z_VOL 1.113 + || volumeIndex != extractFolderInfoVector.Back().VolumeIndex 1.114 + #endif 1.115 + ) 1.116 + { 1.117 + extractFolderInfoVector.Add(CExtractFolderInfo( 1.118 + #ifdef _7Z_VOL 1.119 + volumeIndex, 1.120 + #endif 1.121 + kNumNoIndex, folderIndex)); 1.122 + const CFolder &folderInfo = db.Folders[folderIndex]; 1.123 + UInt64 unpackSize = folderInfo.GetUnpackSize(); 1.124 + importantTotalUnpacked += unpackSize; 1.125 + extractFolderInfoVector.Back().UnpackSize = unpackSize; 1.126 + } 1.127 + 1.128 + CExtractFolderInfo &efi = extractFolderInfoVector.Back(); 1.129 + 1.130 + // const CFolderInfo &folderInfo = m_dam_Folders[folderIndex]; 1.131 + CNum startIndex = db.FolderStartFileIndex[folderIndex]; 1.132 + for (CNum index = efi.ExtractStatuses.Size(); 1.133 + index <= fileIndex - startIndex; index++) 1.134 + { 1.135 + // UInt64 unpackSize = _db.Files[startIndex + index].UnpackSize; 1.136 + // Count partial_folder_size 1.137 + // efi.UnpackSize += unpackSize; 1.138 + // importantTotalUnpacked += unpackSize; 1.139 + efi.ExtractStatuses.Add(index == fileIndex - startIndex); 1.140 + } 1.141 + } 1.142 + } 1.143 + 1.144 + extractCallback->SetTotal(importantTotalUnpacked); 1.145 + 1.146 + CDecoder decoder( 1.147 + #ifdef _ST_MODE 1.148 + false 1.149 + #else 1.150 + true 1.151 + #endif 1.152 + ); 1.153 + // CDecoder1 decoder; 1.154 + 1.155 + UInt64 currentTotalPacked = 0; 1.156 + UInt64 currentTotalUnpacked = 0; 1.157 + UInt64 totalFolderUnpacked; 1.158 + UInt64 totalFolderPacked; 1.159 + 1.160 + CLocalProgress *lps = new CLocalProgress; 1.161 + CMyComPtr<ICompressProgressInfo> progress = lps; 1.162 + lps->Init(extractCallback, false); 1.163 + 1.164 + for(int i = 0; i < extractFolderInfoVector.Size(); i++, 1.165 + currentTotalUnpacked += totalFolderUnpacked, 1.166 + currentTotalPacked += totalFolderPacked) 1.167 + { 1.168 + lps->OutSize = currentTotalUnpacked; 1.169 + lps->InSize = currentTotalPacked; 1.170 + RINOK(lps->SetCur()); 1.171 + 1.172 + const CExtractFolderInfo &efi = extractFolderInfoVector[i]; 1.173 + totalFolderUnpacked = efi.UnpackSize; 1.174 + 1.175 + totalFolderPacked = 0; 1.176 + 1.177 + CFolderOutStream *folderOutStream = new CFolderOutStream; 1.178 + CMyComPtr<ISequentialOutStream> outStream(folderOutStream); 1.179 + 1.180 + #ifdef _7Z_VOL 1.181 + const CVolume &volume = _volumes[efi.VolumeIndex]; 1.182 + const CArchiveDatabaseEx &db = volume.Database; 1.183 + #else 1.184 + const CArchiveDatabaseEx &db = _db; 1.185 + #endif 1.186 + 1.187 + CNum startIndex; 1.188 + if (efi.FileIndex != kNumNoIndex) 1.189 + startIndex = efi.FileIndex; 1.190 + else 1.191 + startIndex = db.FolderStartFileIndex[efi.FolderIndex]; 1.192 + 1.193 + 1.194 + HRESULT result = folderOutStream->Init(&db, 1.195 + #ifdef _7Z_VOL 1.196 + volume.StartRef2Index, 1.197 + #else 1.198 + 0, 1.199 + #endif 1.200 + startIndex, 1.201 + &efi.ExtractStatuses, extractCallback, testMode, _crcSize != 0); 1.202 + 1.203 + RINOK(result); 1.204 + 1.205 + if (efi.FileIndex != kNumNoIndex) 1.206 + continue; 1.207 + 1.208 + CNum folderIndex = efi.FolderIndex; 1.209 + const CFolder &folderInfo = db.Folders[folderIndex]; 1.210 + 1.211 + totalFolderPacked = _db.GetFolderFullPackSize(folderIndex); 1.212 + 1.213 + CNum packStreamIndex = db.FolderStartPackStreamIndex[folderIndex]; 1.214 + UInt64 folderStartPackPos = db.GetFolderStreamPos(folderIndex, 0); 1.215 + 1.216 + #ifndef _NO_CRYPTO 1.217 + CMyComPtr<ICryptoGetTextPassword> getTextPassword; 1.218 + if (extractCallback) 1.219 + extractCallback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword); 1.220 + #endif 1.221 + 1.222 + try 1.223 + { 1.224 + #ifndef _NO_CRYPTO 1.225 + bool passwordIsDefined; 1.226 + #endif 1.227 + 1.228 + HRESULT result = decoder.Decode( 1.229 + EXTERNAL_CODECS_VARS 1.230 + #ifdef _7Z_VOL 1.231 + volume.Stream, 1.232 + #else 1.233 + _inStream, 1.234 + #endif 1.235 + folderStartPackPos, 1.236 + &db.PackSizes[packStreamIndex], 1.237 + folderInfo, 1.238 + outStream, 1.239 + progress 1.240 + #ifndef _NO_CRYPTO 1.241 + , getTextPassword, passwordIsDefined 1.242 + #endif 1.243 + #ifdef COMPRESS_MT 1.244 + , true, _numThreads 1.245 + #endif 1.246 + ); 1.247 + 1.248 + if (result == S_FALSE) 1.249 + { 1.250 + RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError)); 1.251 + continue; 1.252 + } 1.253 + if (result == E_NOTIMPL) 1.254 + { 1.255 + RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); 1.256 + continue; 1.257 + } 1.258 + if (result != S_OK) 1.259 + return result; 1.260 + if (folderOutStream->WasWritingFinished() != S_OK) 1.261 + { 1.262 + RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError)); 1.263 + continue; 1.264 + } 1.265 + } 1.266 + catch(...) 1.267 + { 1.268 + RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError)); 1.269 + continue; 1.270 + } 1.271 + } 1.272 + return S_OK; 1.273 + COM_TRY_END 1.274 +} 1.275 + 1.276 +}}