diff options
Diffstat (limited to 'CPP/7zip/Archive/Tar/TarHandler.cpp')
-rwxr-xr-x | CPP/7zip/Archive/Tar/TarHandler.cpp | 155 |
1 files changed, 53 insertions, 102 deletions
diff --git a/CPP/7zip/Archive/Tar/TarHandler.cpp b/CPP/7zip/Archive/Tar/TarHandler.cpp index f2c83caf..d16307ca 100755 --- a/CPP/7zip/Archive/Tar/TarHandler.cpp +++ b/CPP/7zip/Archive/Tar/TarHandler.cpp @@ -1,4 +1,4 @@ -// Tar/Handler.cpp +/ Tar/Handler.cpp #include "StdAfx.h" @@ -15,6 +15,7 @@ #include "../../Common/ProgressUtils.h" #include "../../Common/LimitedStreams.h" + #include "../../Compress/Copy/CopyCoder.h" #include "../Common/ItemNameUtils.h" @@ -25,7 +26,7 @@ using namespace NTime; namespace NArchive { namespace NTar { -STATPROPSTG kProperties[] = +STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, { NULL, kpidIsFolder, VT_BOOL}, @@ -36,41 +37,16 @@ STATPROPSTG kProperties[] = { NULL, kpidGroup, VT_BSTR}, }; -STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) -{ - value->vt = VT_EMPTY; - return S_OK; -} -STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) -{ - *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); - return S_OK; -} -STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType) -{ - if(index >= sizeof(kProperties) / sizeof(kProperties[0])) - return E_INVALIDARG; - const STATPROPSTG &srcItem = kProperties[index]; - *propID = srcItem.propid; - *varType = srcItem.vt; - *name = 0; - return S_OK; -} -STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) -{ - *numProperties = 0; - return S_OK; -} -STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, - BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) -{ - return E_INVALIDARG; -} + + + + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 * /* maxCheckStartPosition */, @@ -81,7 +57,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream, { CInArchive archive; - if(archive.Open(stream) != S_OK) + if (archive.Open(stream) != S_OK) return S_FALSE; _items.Clear(); @@ -120,11 +96,11 @@ STDMETHODIMP CHandler::Open(IInStream *stream, openArchiveCallback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback); if (!openVolumeCallback) return S_FALSE; - NCOM::CPropVariant propVariant; - RINOK(openVolumeCallback->GetProperty(kpidName, &propVariant)); - if (propVariant.vt != VT_BSTR) + NCOM::CPropVariant prop; + RINOK(openVolumeCallback->GetProperty(kpidName, &prop)); + if (prop.vt != VT_BSTR) return S_FALSE; - UString baseName = propVariant.bstrVal; + UString baseName = prop.bstrVal; baseName = baseName.Right(4); if (baseName.CompareNoCase(L".tar") != 0) return S_FALSE; @@ -157,45 +133,45 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN - NWindows::NCOM::CPropVariant propVariant; - const NArchive::NTar::CItemEx &item = _items[index]; + NWindows::NCOM::CPropVariant prop; + const CItemEx &item = _items[index]; switch(propID) { case kpidPath: - propVariant = (const wchar_t *)NItemName::GetOSName2( + prop = (const wchar_t *)NItemName::GetOSName2( MultiByteToUnicodeString(item.Name, CP_OEMCP)); break; case kpidIsFolder: - propVariant = item.IsDirectory(); + prop = item.IsDirectory(); break; case kpidSize: case kpidPackedSize: - propVariant = (UInt64)item.Size; + prop = (UInt64)item.Size; break; case kpidLastWriteTime: { FILETIME utcFileTime; if (item.ModificationTime != 0) - NTime::UnixTimeToFileTime((UInt32)item.ModificationTime, utcFileTime); + NTime::UnixTimeToFileTime(item.ModificationTime, utcFileTime); else { utcFileTime.dwLowDateTime = 0; utcFileTime.dwHighDateTime = 0; } - propVariant = utcFileTime; + prop = utcFileTime; break; } case kpidUser: - propVariant = (const wchar_t *) + prop = (const wchar_t *) MultiByteToUnicodeString(item.UserName, CP_OEMCP); break; case kpidGroup: - propVariant = (const wchar_t *) + prop = (const wchar_t *) MultiByteToUnicodeString(item.GroupName, CP_OEMCP); break; } - propVariant.Detach(value); + prop.Detach(value); return S_OK; COM_TRY_END } @@ -208,86 +184,61 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, bool allFilesMode = (numItems == UInt32(-1)); if (allFilesMode) numItems = _items.Size(); - UInt64 totalSize = 0; - if(numItems == 0) + if (numItems == 0) return S_OK; + UInt64 totalSize = 0; UInt32 i; - for(i = 0; i < numItems; i++) + for (i = 0; i < numItems; i++) totalSize += _items[allFilesMode ? i : indices[i]].Size; extractCallback->SetTotal(totalSize); UInt64 currentTotalSize = 0; UInt64 currentItemSize; - CMyComPtr<ICompressCoder> copyCoder; + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); + CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; - for(i = 0; i < numItems; i++, currentTotalSize += currentItemSize) + CLocalProgress *lps = new CLocalProgress; + CMyComPtr<ICompressProgressInfo> progress = lps; + lps->Init(extractCallback, false); + + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr<ISequentialInStream> inStream(streamSpec); + streamSpec->SetStream(_inStream); + + for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) { - RINOK(extractCallback->SetCompleted(¤tTotalSize)); + lps->InSize = lps->OutSize = currentTotalSize; + RINOK(lps->SetCur()); CMyComPtr<ISequentialOutStream> realOutStream; - Int32 askMode; - askMode = testMode ? NArchive::NExtract::NAskMode::kTest : + Int32 askMode = testMode ? + NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract; Int32 index = allFilesMode ? i : indices[i]; const CItemEx &item = _items[index]; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - currentItemSize = item.Size; - - if(item.IsDirectory()) + if (item.IsDirectory()) { RINOK(extractCallback->PrepareOperation(askMode)); RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); continue; } - if(!testMode && (!realOutStream)) - { + if (!testMode && (!realOutStream)) continue; - } RINOK(extractCallback->PrepareOperation(askMode)); + if (testMode) { - if (testMode) - { - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); - continue; - } - - RINOK(_inStream->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL)); - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr<ISequentialInStream> inStream(streamSpec); - streamSpec->SetStream(_inStream); - streamSpec->Init(item.Size); - - CLocalProgress *localProgressSpec = new CLocalProgress; - CMyComPtr<ICompressProgressInfo> progress = localProgressSpec; - localProgressSpec->Init(extractCallback, false); - - - CLocalCompressProgressInfo *localCompressProgressSpec = - new CLocalCompressProgressInfo; - CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec; - localCompressProgressSpec->Init(progress, - ¤tTotalSize, ¤tTotalSize); - - if(!copyCoder) - { - copyCoder = new NCompress::CCopyCoder; - } - try - { - RINOK(copyCoder->Code(inStream, realOutStream, - NULL, NULL, compressProgress)); - } - catch(...) - { - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError)); - continue; - } - realOutStream.Release(); RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + continue; } + RINOK(_inStream->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL)); + streamSpec->Init(item.Size); + RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ? + NArchive::NExtract::NOperationResult::kOK: + NArchive::NExtract::NOperationResult::kDataError)); } return S_OK; COM_TRY_END |