Mercurial > vba-linux
view src/win32/7zip/7z/CPP/7zip/Archive/Tar/TarHandler.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 source
1 // TarHandler.cpp3 #include "StdAfx.h"5 #include "Common/ComTry.h"6 #include "Common/Defs.h"7 #include "Common/NewHandler.h"8 #include "Common/StringConvert.h"10 #include "Windows/PropVariant.h"11 #include "Windows/Time.h"13 #include "../../Common/LimitedStreams.h"14 #include "../../Common/ProgressUtils.h"16 #include "../../Compress/CopyCoder.h"18 #include "../Common/DummyOutStream.h"19 #include "../Common/ItemNameUtils.h"21 #include "TarHandler.h"22 #include "TarIn.h"24 using namespace NWindows;26 namespace NArchive {27 namespace NTar {29 STATPROPSTG kProps[] =30 {31 { NULL, kpidPath, VT_BSTR},32 { NULL, kpidIsDir, VT_BOOL},33 { NULL, kpidSize, VT_UI8},34 { NULL, kpidPackSize, VT_UI8},35 { NULL, kpidMTime, VT_FILETIME},36 { NULL, kpidUser, VT_BSTR},37 { NULL, kpidGroup, VT_BSTR}38 };40 IMP_IInArchive_Props41 IMP_IInArchive_ArcProps_NO43 HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)44 {45 UInt64 endPos = 0;46 if (callback != NULL)47 {48 RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos));49 RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));50 }52 UInt64 pos = 0;53 for (;;)54 {55 CItemEx item;56 bool filled;57 item.HeaderPosition = pos;58 RINOK(ReadItem(stream, filled, item));59 if (!filled)60 break;61 _items.Add(item);63 RINOK(stream->Seek(item.GetPackSize(), STREAM_SEEK_CUR, &pos));64 if (pos >= endPos)65 return S_FALSE;66 if (callback != NULL)67 {68 if (_items.Size() == 1)69 {70 RINOK(callback->SetTotal(NULL, &endPos));71 }72 if (_items.Size() % 100 == 0)73 {74 UInt64 numFiles = _items.Size();75 RINOK(callback->SetCompleted(&numFiles, &pos));76 }77 }78 }80 if (_items.Size() == 0)81 {82 CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;83 if (!callback)84 return S_FALSE;85 callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback);86 if (!openVolumeCallback)87 return S_FALSE;88 NCOM::CPropVariant prop;89 if (openVolumeCallback->GetProperty(kpidName, &prop) != S_OK)90 return S_FALSE;91 if (prop.vt != VT_BSTR)92 return S_FALSE;93 UString baseName = prop.bstrVal;94 baseName = baseName.Right(4);95 if (baseName.CompareNoCase(L".tar") != 0)96 return S_FALSE;97 }98 return S_OK;99 }101 STDMETHODIMP CHandler::Open(IInStream *stream,102 const UInt64 * /* maxCheckStartPosition */,103 IArchiveOpenCallback *openArchiveCallback)104 {105 COM_TRY_BEGIN106 {107 Close();108 RINOK(Open2(stream, openArchiveCallback));109 _inStream = stream;110 }111 return S_OK;112 COM_TRY_END113 }115 STDMETHODIMP CHandler::Close()116 {117 _items.Clear();118 _inStream.Release();119 return S_OK;120 }122 STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)123 {124 *numItems = _items.Size();125 return S_OK;126 }128 STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)129 {130 COM_TRY_BEGIN131 NWindows::NCOM::CPropVariant prop;132 const CItemEx &item = _items[index];134 switch(propID)135 {136 case kpidPath: prop = NItemName::GetOSName2(MultiByteToUnicodeString(item.Name, CP_OEMCP)); break;137 case kpidIsDir: prop = item.IsDir(); break;138 case kpidSize: prop = item.Size; break;139 case kpidPackSize: prop = item.GetPackSize(); break;140 case kpidMTime:141 if (item.MTime != 0)142 {143 FILETIME ft;144 NTime::UnixTimeToFileTime(item.MTime, ft);145 prop = ft;146 }147 break;148 case kpidUser: prop = MultiByteToUnicodeString(item.UserName, CP_OEMCP); break;149 case kpidGroup: prop = MultiByteToUnicodeString(item.GroupName, CP_OEMCP); break;150 }151 prop.Detach(value);152 return S_OK;153 COM_TRY_END154 }156 STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,157 Int32 _aTestMode, IArchiveExtractCallback *extractCallback)158 {159 COM_TRY_BEGIN160 bool testMode = (_aTestMode != 0);161 bool allFilesMode = (numItems == UInt32(-1));162 if (allFilesMode)163 numItems = _items.Size();164 if (numItems == 0)165 return S_OK;166 UInt64 totalSize = 0;167 UInt32 i;168 for (i = 0; i < numItems; i++)169 totalSize += _items[allFilesMode ? i : indices[i]].Size;170 extractCallback->SetTotal(totalSize);172 UInt64 totalPackSize, curPackSize, curSize;173 totalSize = totalPackSize = 0;175 NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();176 CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;178 CLocalProgress *lps = new CLocalProgress;179 CMyComPtr<ICompressProgressInfo> progress = lps;180 lps->Init(extractCallback, false);182 CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;183 CMyComPtr<ISequentialInStream> inStream(streamSpec);184 streamSpec->SetStream(_inStream);186 CDummyOutStream *outStreamSpec = new CDummyOutStream;187 CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);189 for (i = 0; i < numItems; i++, totalSize += curSize, totalPackSize += curPackSize)190 {191 lps->InSize = totalPackSize;192 lps->OutSize = totalSize;193 RINOK(lps->SetCur());194 CMyComPtr<ISequentialOutStream> realOutStream;195 Int32 askMode = testMode ?196 NArchive::NExtract::NAskMode::kTest :197 NArchive::NExtract::NAskMode::kExtract;198 Int32 index = allFilesMode ? i : indices[i];199 const CItemEx &item = _items[index];200 RINOK(extractCallback->GetStream(index, &realOutStream, askMode));201 curSize = item.Size;202 curPackSize = item.GetPackSize();203 if (item.IsDir())204 {205 RINOK(extractCallback->PrepareOperation(askMode));206 RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));207 continue;208 }209 if (!testMode && (!realOutStream))210 continue;211 RINOK(extractCallback->PrepareOperation(askMode));213 outStreamSpec->SetStream(realOutStream);214 realOutStream.Release();215 outStreamSpec->Init();217 RINOK(_inStream->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL));218 streamSpec->Init(item.Size);219 RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));220 outStreamSpec->ReleaseStream();221 RINOK(extractCallback->SetOperationResult(copyCoderSpec->TotalSize == item.Size ?222 NArchive::NExtract::NOperationResult::kOK:223 NArchive::NExtract::NOperationResult::kDataError));224 }225 return S_OK;226 COM_TRY_END227 }229 }}