Mercurial > vba-linux
diff src/win32/7zip/7z/CPP/7zip/Archive/BZip2/BZip2Handler.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/BZip2/BZip2Handler.cpp Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,216 @@ 1.4 +// BZip2Handler.cpp 1.5 + 1.6 +#include "StdAfx.h" 1.7 + 1.8 +#include "Common/ComTry.h" 1.9 + 1.10 +#include "Windows/PropVariant.h" 1.11 + 1.12 +#include "../../Common/CreateCoder.h" 1.13 +#include "../../Common/ProgressUtils.h" 1.14 +#include "../../Common/StreamUtils.h" 1.15 + 1.16 +#include "../Common/DummyOutStream.h" 1.17 + 1.18 +#include "BZip2Handler.h" 1.19 + 1.20 +using namespace NWindows; 1.21 + 1.22 +namespace NArchive { 1.23 +namespace NBZip2 { 1.24 + 1.25 +static const CMethodId kMethodId_BZip2 = 0x040202; 1.26 + 1.27 +STATPROPSTG kProps[] = 1.28 +{ 1.29 + { NULL, kpidPackSize, VT_UI8} 1.30 +}; 1.31 + 1.32 +IMP_IInArchive_Props 1.33 +IMP_IInArchive_ArcProps_NO 1.34 + 1.35 +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) 1.36 +{ 1.37 + *numItems = 1; 1.38 + return S_OK; 1.39 +} 1.40 + 1.41 +STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) 1.42 +{ 1.43 + NWindows::NCOM::CPropVariant prop; 1.44 + switch(propID) 1.45 + { 1.46 + case kpidPackSize: prop = _item.PackSize; break; 1.47 + } 1.48 + prop.Detach(value); 1.49 + return S_OK; 1.50 +} 1.51 + 1.52 +STDMETHODIMP CHandler::Open(IInStream *stream, 1.53 + const UInt64 * /* maxCheckStartPosition */, 1.54 + IArchiveOpenCallback * /* openArchiveCallback */) 1.55 +{ 1.56 + COM_TRY_BEGIN 1.57 + try 1.58 + { 1.59 + RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_streamStartPosition)); 1.60 + const int kSignatureSize = 3; 1.61 + Byte buffer[kSignatureSize]; 1.62 + RINOK(ReadStream_FALSE(stream, buffer, kSignatureSize)); 1.63 + if (buffer[0] != 'B' || buffer[1] != 'Z' || buffer[2] != 'h') 1.64 + return S_FALSE; 1.65 + 1.66 + UInt64 endPosition; 1.67 + RINOK(stream->Seek(0, STREAM_SEEK_END, &endPosition)); 1.68 + _item.PackSize = endPosition - _streamStartPosition; 1.69 + 1.70 + _stream = stream; 1.71 + } 1.72 + catch(...) 1.73 + { 1.74 + return S_FALSE; 1.75 + } 1.76 + return S_OK; 1.77 + COM_TRY_END 1.78 +} 1.79 + 1.80 +STDMETHODIMP CHandler::Close() 1.81 +{ 1.82 + _stream.Release(); 1.83 + return S_OK; 1.84 +} 1.85 + 1.86 + 1.87 +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, 1.88 + Int32 testModeSpec, IArchiveExtractCallback *extractCallback) 1.89 +{ 1.90 + COM_TRY_BEGIN 1.91 + bool allFilesMode = (numItems == UInt32(-1)); 1.92 + if (!allFilesMode) 1.93 + { 1.94 + if (numItems == 0) 1.95 + return S_OK; 1.96 + if (numItems != 1) 1.97 + return E_INVALIDARG; 1.98 + if (indices[0] != 0) 1.99 + return E_INVALIDARG; 1.100 + } 1.101 + 1.102 + bool testMode = (testModeSpec != 0); 1.103 + 1.104 + extractCallback->SetTotal(_item.PackSize); 1.105 + 1.106 + UInt64 currentTotalPacked = 0; 1.107 + 1.108 + RINOK(extractCallback->SetCompleted(¤tTotalPacked)); 1.109 + 1.110 + CMyComPtr<ISequentialOutStream> realOutStream; 1.111 + Int32 askMode; 1.112 + askMode = testMode ? NExtract::NAskMode::kTest : 1.113 + NExtract::NAskMode::kExtract; 1.114 + 1.115 + RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); 1.116 + 1.117 + if(!testMode && !realOutStream) 1.118 + return S_OK; 1.119 + 1.120 + 1.121 + extractCallback->PrepareOperation(askMode); 1.122 + 1.123 + CMyComPtr<ICompressCoder> decoder; 1.124 + HRESULT loadResult = CreateCoder( 1.125 + EXTERNAL_CODECS_VARS 1.126 + kMethodId_BZip2, decoder, false); 1.127 + if (loadResult != S_OK || !decoder) 1.128 + { 1.129 + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod)); 1.130 + return S_OK; 1.131 + } 1.132 + 1.133 + #ifdef COMPRESS_MT 1.134 + { 1.135 + CMyComPtr<ICompressSetCoderMt> setCoderMt; 1.136 + decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt); 1.137 + if (setCoderMt) 1.138 + { 1.139 + RINOK(setCoderMt->SetNumberOfThreads(_numThreads)); 1.140 + } 1.141 + } 1.142 + #endif 1.143 + 1.144 + CDummyOutStream *outStreamSpec = new CDummyOutStream; 1.145 + CMyComPtr<ISequentialOutStream> outStream(outStreamSpec); 1.146 + outStreamSpec->SetStream(realOutStream); 1.147 + outStreamSpec->Init(); 1.148 + 1.149 + realOutStream.Release(); 1.150 + 1.151 + CLocalProgress *lps = new CLocalProgress; 1.152 + CMyComPtr<ICompressProgressInfo> progress = lps; 1.153 + lps->Init(extractCallback, true); 1.154 + 1.155 + RINOK(_stream->Seek(_streamStartPosition, STREAM_SEEK_SET, NULL)); 1.156 + 1.157 + HRESULT result = S_OK; 1.158 + 1.159 + bool firstItem = true; 1.160 + for (;;) 1.161 + { 1.162 + lps->InSize = currentTotalPacked; 1.163 + lps->OutSize = outStreamSpec->GetSize(); 1.164 + 1.165 + RINOK(lps->SetCur()); 1.166 + 1.167 + const int kSignatureSize = 3; 1.168 + Byte buffer[kSignatureSize]; 1.169 + size_t processedSize = kSignatureSize; 1.170 + RINOK(ReadStream(_stream, buffer, &processedSize)); 1.171 + if (processedSize != kSignatureSize) 1.172 + { 1.173 + if (firstItem) 1.174 + return E_FAIL; 1.175 + break; 1.176 + } 1.177 + if (buffer[0] != 'B' || buffer[1] != 'Z' || buffer[2] != 'h') 1.178 + { 1.179 + if (firstItem) 1.180 + return E_FAIL; 1.181 + break; 1.182 + } 1.183 + firstItem = false; 1.184 + 1.185 + UInt64 dataStartPos; 1.186 + RINOK(_stream->Seek((UInt64)(Int64)(-3), STREAM_SEEK_CUR, &dataStartPos)); 1.187 + 1.188 + result = decoder->Code(_stream, outStream, NULL, NULL, progress); 1.189 + 1.190 + if (result != S_OK) 1.191 + break; 1.192 + 1.193 + CMyComPtr<ICompressGetInStreamProcessedSize> getInStreamProcessedSize; 1.194 + decoder.QueryInterface(IID_ICompressGetInStreamProcessedSize, &getInStreamProcessedSize); 1.195 + if (!getInStreamProcessedSize) 1.196 + break; 1.197 + UInt64 packSize; 1.198 + RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&packSize)); 1.199 + UInt64 pos; 1.200 + RINOK(_stream->Seek(dataStartPos + packSize, STREAM_SEEK_SET, &pos)); 1.201 + currentTotalPacked = pos - _streamStartPosition; 1.202 + } 1.203 + outStream.Release(); 1.204 + 1.205 + Int32 retResult; 1.206 + if (result == S_OK) 1.207 + retResult = NExtract::NOperationResult::kOK; 1.208 + else if (result == S_FALSE) 1.209 + retResult = NExtract::NOperationResult::kDataError; 1.210 + else 1.211 + return result; 1.212 + return extractCallback->SetOperationResult(retResult); 1.213 + 1.214 + COM_TRY_END 1.215 +} 1.216 + 1.217 +IMPL_ISetCompressCodecsInfo 1.218 + 1.219 +}}