Mercurial > vba-linux
diff src/win32/7zip/7z/CPP/7zip/Archive/GZip/GZipHandler.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/GZip/GZipHandler.cpp Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,284 @@ 1.4 +// GZipHandler.cpp 1.5 + 1.6 +#include "StdAfx.h" 1.7 + 1.8 +#include "GZipHandler.h" 1.9 + 1.10 +#include "Common/Defs.h" 1.11 +#include "Common/StringConvert.h" 1.12 +#include "Common/ComTry.h" 1.13 +#include "Windows/PropVariant.h" 1.14 +#include "Windows/Time.h" 1.15 + 1.16 +#include "../../ICoder.h" 1.17 +#include "../../Common/ProgressUtils.h" 1.18 +#include "../../Common/CreateCoder.h" 1.19 +#include "../Common/OutStreamWithCRC.h" 1.20 + 1.21 +using namespace NWindows; 1.22 + 1.23 +namespace NArchive { 1.24 +namespace NGZip { 1.25 + 1.26 +static const CMethodId kMethodId_Deflate = 0x040108; 1.27 + 1.28 +const wchar_t *kHostOS[] = 1.29 +{ 1.30 + L"FAT", 1.31 + L"AMIGA", 1.32 + L"VMS", 1.33 + L"Unix", 1.34 + L"VM_CMS", 1.35 + L"Atari", // what if it's a minix filesystem? [cjh] 1.36 + L"HPFS", // filesystem used by OS/2 (and NT 3.x) 1.37 + L"Mac", 1.38 + L"Z_System", 1.39 + L"CPM", 1.40 + L"TOPS20", // pkzip 2.50 NTFS 1.41 + L"NTFS", // filesystem used by Windows NT 1.42 + L"QDOS ", // SMS/QDOS 1.43 + L"Acorn", // Archimedes Acorn RISC OS 1.44 + L"VFAT", // filesystem used by Windows 95, NT 1.45 + L"MVS", 1.46 + L"BeOS", // hybrid POSIX/database filesystem 1.47 + // BeBOX or PowerMac 1.48 + L"Tandem", 1.49 + L"THEOS" 1.50 +}; 1.51 + 1.52 +static const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]); 1.53 + 1.54 +static const wchar_t *kUnknownOS = L"Unknown"; 1.55 + 1.56 +/* 1.57 +enum // PropID 1.58 +{ 1.59 + kpidExtraIsPresent = kpidUserDefined, 1.60 + kpidExtraFlags, 1.61 + kpidIsText 1.62 +}; 1.63 +*/ 1.64 + 1.65 +STATPROPSTG kProps[] = 1.66 +{ 1.67 + { NULL, kpidPath, VT_BSTR}, 1.68 + { NULL, kpidSize, VT_UI8}, 1.69 + { NULL, kpidPackSize, VT_UI8}, 1.70 + { NULL, kpidMTime, VT_FILETIME}, 1.71 + // { NULL, kpidMethod, VT_UI1}, 1.72 + { NULL, kpidHostOS, VT_BSTR}, 1.73 + { NULL, kpidCRC, VT_UI4} 1.74 + // { L"Extra", kpidExtraIsPresent, VT_BOOL} 1.75 + // { L"Extra flags", kpidExtraFlags, VT_UI1}, 1.76 + // { L"Is Text", kpidIsText, VT_BOOL}, 1.77 +}; 1.78 + 1.79 +IMP_IInArchive_Props 1.80 +IMP_IInArchive_ArcProps_NO 1.81 + 1.82 +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) 1.83 +{ 1.84 + *numItems = 1; 1.85 + return S_OK; 1.86 +} 1.87 + 1.88 +STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) 1.89 +{ 1.90 + COM_TRY_BEGIN 1.91 + NWindows::NCOM::CPropVariant prop; 1.92 + switch(propID) 1.93 + { 1.94 + case kpidPath: 1.95 + if (m_Item.NameIsPresent()) 1.96 + prop = MultiByteToUnicodeString(m_Item.Name, CP_ACP); 1.97 + break; 1.98 + case kpidMTime: 1.99 + { 1.100 + FILETIME utcTime; 1.101 + if (m_Item.Time != 0) 1.102 + { 1.103 + NTime::UnixTimeToFileTime((UInt32)m_Item.Time, utcTime); 1.104 + prop = utcTime; 1.105 + } 1.106 + else 1.107 + { 1.108 + // utcTime.dwLowDateTime = utcTime.dwHighDateTime = 0; 1.109 + // prop = utcTime; 1.110 + } 1.111 + break; 1.112 + } 1.113 + case kpidSize: prop = UInt64(m_Item.UnPackSize32); break; 1.114 + case kpidPackSize: prop = m_PackSize; break; 1.115 + case kpidCommented: prop = m_Item.CommentIsPresent(); break; 1.116 + case kpidHostOS: 1.117 + prop = (m_Item.HostOS < kNumHostOSes) ? 1.118 + kHostOS[m_Item.HostOS] : kUnknownOS; 1.119 + break; 1.120 + case kpidMethod: prop = m_Item.CompressionMethod; break; 1.121 + case kpidCRC: prop = m_Item.FileCRC; break; 1.122 + /* 1.123 + case kpidExtraFlags: prop = m_Item.ExtraFlags; break; 1.124 + case kpidIsText: prop = m_Item.IsText(); break; 1.125 + case kpidExtraIsPresent: prop = m_Item.ExtraFieldIsPresent(); break; 1.126 + */ 1.127 + } 1.128 + prop.Detach(value); 1.129 + return S_OK; 1.130 + COM_TRY_END 1.131 +} 1.132 + 1.133 +STDMETHODIMP CHandler::Open(IInStream *inStream, 1.134 + const UInt64 * /* maxCheckStartPosition */, 1.135 + IArchiveOpenCallback * /* openArchiveCallback */) 1.136 +{ 1.137 + COM_TRY_BEGIN 1.138 + try 1.139 + { 1.140 + CInArchive archive; 1.141 + RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_StreamStartPosition)); 1.142 + RINOK(archive.ReadHeader(inStream, m_Item)); 1.143 + m_DataOffset = archive.GetOffset(); 1.144 + UInt64 newPosition; 1.145 + RINOK(inStream->Seek(-8, STREAM_SEEK_END, &newPosition)); 1.146 + m_PackSize = newPosition - (m_StreamStartPosition + m_DataOffset); 1.147 + if (archive.ReadPostHeader(inStream, m_Item) != S_OK) 1.148 + return S_FALSE; 1.149 + m_Stream = inStream; 1.150 + } 1.151 + catch(...) 1.152 + { 1.153 + return S_FALSE; 1.154 + } 1.155 + return S_OK; 1.156 + COM_TRY_END 1.157 +} 1.158 + 1.159 +STDMETHODIMP CHandler::Close() 1.160 +{ 1.161 + m_Stream.Release(); 1.162 + return S_OK; 1.163 +} 1.164 + 1.165 +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, 1.166 + Int32 _aTestMode, IArchiveExtractCallback *extractCallback) 1.167 +{ 1.168 + COM_TRY_BEGIN 1.169 + bool allFilesMode = (numItems == UInt32(-1)); 1.170 + if (!allFilesMode) 1.171 + { 1.172 + if (numItems == 0) 1.173 + return S_OK; 1.174 + if (numItems != 1) 1.175 + return E_INVALIDARG; 1.176 + if (indices[0] != 0) 1.177 + return E_INVALIDARG; 1.178 + } 1.179 + 1.180 + bool testMode = (_aTestMode != 0); 1.181 + 1.182 + extractCallback->SetTotal(m_PackSize); 1.183 + 1.184 + UInt64 currentTotalPacked = 0; 1.185 + 1.186 + RINOK(extractCallback->SetCompleted(¤tTotalPacked)); 1.187 + CMyComPtr<ISequentialOutStream> realOutStream; 1.188 + Int32 askMode; 1.189 + askMode = testMode ? NArchive::NExtract::NAskMode::kTest : 1.190 + NArchive::NExtract::NAskMode::kExtract; 1.191 + 1.192 + RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); 1.193 + 1.194 + if(!testMode && !realOutStream) 1.195 + return S_OK; 1.196 + 1.197 + extractCallback->PrepareOperation(askMode); 1.198 + 1.199 + COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC; 1.200 + CMyComPtr<ISequentialOutStream> outStream(outStreamSpec); 1.201 + outStreamSpec->SetStream(realOutStream); 1.202 + outStreamSpec->Init(); 1.203 + realOutStream.Release(); 1.204 + 1.205 + CLocalProgress *lps = new CLocalProgress; 1.206 + CMyComPtr<ICompressProgressInfo> progress = lps; 1.207 + lps->Init(extractCallback, true); 1.208 + 1.209 + CMyComPtr<ICompressCoder> deflateDecoder; 1.210 + bool firstItem = true; 1.211 + RINOK(m_Stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL)); 1.212 + Int32 opRes; 1.213 + for (;;) 1.214 + { 1.215 + lps->InSize = currentTotalPacked; 1.216 + lps->OutSize = outStreamSpec->GetSize(); 1.217 + 1.218 + CInArchive archive; 1.219 + CItem item; 1.220 + HRESULT result = archive.ReadHeader(m_Stream, item); 1.221 + if (result != S_OK) 1.222 + { 1.223 + if (firstItem) 1.224 + return E_FAIL; 1.225 + opRes = NArchive::NExtract::NOperationResult::kOK; 1.226 + break; 1.227 + } 1.228 + firstItem = false; 1.229 + 1.230 + UInt64 dataStartPos; 1.231 + RINOK(m_Stream->Seek(0, STREAM_SEEK_CUR, &dataStartPos)); 1.232 + 1.233 + outStreamSpec->InitCRC(); 1.234 + 1.235 + if (item.CompressionMethod != NFileHeader::NCompressionMethod::kDeflate) 1.236 + { 1.237 + opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod; 1.238 + break; 1.239 + } 1.240 + 1.241 + if (!deflateDecoder) 1.242 + { 1.243 + RINOK(CreateCoder( 1.244 + EXTERNAL_CODECS_VARS 1.245 + kMethodId_Deflate, deflateDecoder, false)); 1.246 + if (!deflateDecoder) 1.247 + { 1.248 + opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod; 1.249 + break; 1.250 + } 1.251 + } 1.252 + result = deflateDecoder->Code(m_Stream, outStream, NULL, NULL, progress); 1.253 + if (result != S_OK) 1.254 + { 1.255 + if (result != S_FALSE) 1.256 + return result; 1.257 + opRes = NArchive::NExtract::NOperationResult::kDataError; 1.258 + break; 1.259 + } 1.260 + 1.261 + CMyComPtr<ICompressGetInStreamProcessedSize> getInStreamProcessedSize; 1.262 + RINOK(deflateDecoder.QueryInterface(IID_ICompressGetInStreamProcessedSize, 1.263 + &getInStreamProcessedSize)); 1.264 + UInt64 packSize; 1.265 + RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&packSize)); 1.266 + UInt64 pos; 1.267 + RINOK(m_Stream->Seek(dataStartPos + packSize, STREAM_SEEK_SET, &pos)); 1.268 + 1.269 + currentTotalPacked = pos - m_StreamStartPosition; 1.270 + 1.271 + CItem postItem; 1.272 + if (archive.ReadPostHeader(m_Stream, postItem) != S_OK) 1.273 + return E_FAIL; 1.274 + if((outStreamSpec->GetCRC() != postItem.FileCRC)) 1.275 + { 1.276 + opRes = NArchive::NExtract::NOperationResult::kCRCError; 1.277 + break; 1.278 + } 1.279 + } 1.280 + outStream.Release(); 1.281 + return extractCallback->SetOperationResult(opRes); 1.282 + COM_TRY_END 1.283 +} 1.284 + 1.285 +IMPL_ISetCompressCodecsInfo 1.286 + 1.287 +}}