diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2008-08-13 04:00:00 +0400 |
---|---|---|
committer | Kornel LesiĆski <kornel@geekhood.net> | 2016-05-28 02:15:56 +0300 |
commit | 173c07e166fdf6fcd20f18ea73008f1b628945df (patch) | |
tree | 13ebea85cdc4c16ae93714ff0627ee9f91ad7e08 /CPP/7zip/Archive/Tar | |
parent | 3901bf0ab88106a5b031cba7bc18d60cdebf7eef (diff) |
4.59 beta
Diffstat (limited to 'CPP/7zip/Archive/Tar')
-rwxr-xr-x | CPP/7zip/Archive/Tar/StdAfx.cpp | 3 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Tar/TarHandler.cpp | 206 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Tar/TarHandler.h | 4 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Tar/TarHandlerOut.cpp | 61 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Tar/TarHeader.cpp | 2 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Tar/TarHeader.h | 16 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Tar/TarIn.cpp | 175 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Tar/TarIn.h | 16 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Tar/TarItem.h | 38 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Tar/TarOut.cpp | 2 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Tar/TarUpdate.cpp | 42 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Tar/TarUpdate.h | 6 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Tar/tar.ico | bin | 3638 -> 0 bytes |
13 files changed, 226 insertions, 345 deletions
diff --git a/CPP/7zip/Archive/Tar/StdAfx.cpp b/CPP/7zip/Archive/Tar/StdAfx.cpp deleted file mode 100755 index d0feea85..00000000 --- a/CPP/7zip/Archive/Tar/StdAfx.cpp +++ /dev/null @@ -1,3 +0,0 @@ -// StdAfx.cpp - -#include "StdAfx.h" diff --git a/CPP/7zip/Archive/Tar/TarHandler.cpp b/CPP/7zip/Archive/Tar/TarHandler.cpp index 33866d61..f70f7e4e 100755 --- a/CPP/7zip/Archive/Tar/TarHandler.cpp +++ b/CPP/7zip/Archive/Tar/TarHandler.cpp @@ -15,104 +15,99 @@ #include "../../Common/ProgressUtils.h" #include "../../Common/LimitedStreams.h" +#include "../Common/DummyOutStream.h" #include "../../Compress/Copy/CopyCoder.h" #include "../Common/ItemNameUtils.h" using namespace NWindows; -using namespace NTime; namespace NArchive { namespace NTar { -STATPROPSTG kProps[] = +STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, - { NULL, kpidIsFolder, VT_BOOL}, + { NULL, kpidIsDir, VT_BOOL}, { NULL, kpidSize, VT_UI8}, - { NULL, kpidPackedSize, VT_UI8}, - { NULL, kpidLastWriteTime, VT_FILETIME}, + { NULL, kpidPackSize, VT_UI8}, + { NULL, kpidMTime, VT_FILETIME}, { NULL, kpidUser, VT_BSTR}, - { NULL, kpidGroup, VT_BSTR}, + { NULL, kpidGroup, VT_BSTR} }; - - - - - - - - IMP_IInArchive_Props IMP_IInArchive_ArcProps_NO -STDMETHODIMP CHandler::Open(IInStream *stream, - const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback *openArchiveCallback) +HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) { - COM_TRY_BEGIN - // try + UInt64 endPos = 0; + if (callback != NULL) { - CInArchive archive; - - if (archive.Open(stream) != S_OK) + RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos)); + RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); + } + + UInt64 pos = 0; + for (;;) + { + CItemEx item; + bool filled; + item.HeaderPosition = pos; + RINOK(ReadItem(stream, filled, item)); + if (!filled) + break; + _items.Add(item); + + RINOK(stream->Seek(item.GetPackSize(), STREAM_SEEK_CUR, &pos)); + if (pos >= endPos) return S_FALSE; - - _items.Clear(); - - if (openArchiveCallback != NULL) + if (callback != NULL) { - RINOK(openArchiveCallback->SetTotal(NULL, NULL)); - UInt64 numFiles = _items.Size(); - RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); - } - - for (;;) - { - CItemEx item; - bool filled; - HRESULT result = archive.GetNextItem(filled, item); - if (result == S_FALSE) - return S_FALSE; - if (result != S_OK) - return S_FALSE; - if (!filled) - break; - _items.Add(item); - archive.SkeepDataRecords(item.Size); - if (openArchiveCallback != NULL) + if (_items.Size() == 1) + { + RINOK(callback->SetTotal(NULL, &endPos)); + } + if (_items.Size() % 100 == 0) { UInt64 numFiles = _items.Size(); - RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); + RINOK(callback->SetCompleted(&numFiles, &pos)); } } - if (_items.Size() == 0) - { - CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback; - if (!openArchiveCallback) - return S_FALSE; - openArchiveCallback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback); - if (!openVolumeCallback) - return S_FALSE; - NCOM::CPropVariant prop; - RINOK(openVolumeCallback->GetProperty(kpidName, &prop)); - if (prop.vt != VT_BSTR) - return S_FALSE; - UString baseName = prop.bstrVal; - baseName = baseName.Right(4); - if (baseName.CompareNoCase(L".tar") != 0) - return S_FALSE; - } - _inStream = stream; } - /* - catch(...) + + if (_items.Size() == 0) + { + CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback; + if (!callback) + return S_FALSE; + callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback); + if (!openVolumeCallback) + return S_FALSE; + NCOM::CPropVariant prop; + if (openVolumeCallback->GetProperty(kpidName, &prop) != S_OK) + return S_FALSE; + if (prop.vt != VT_BSTR) + return S_FALSE; + UString baseName = prop.bstrVal; + baseName = baseName.Right(4); + if (baseName.CompareNoCase(L".tar") != 0) + return S_FALSE; + } + return S_OK; +} + +STDMETHODIMP CHandler::Open(IInStream *stream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback *openArchiveCallback) +{ + COM_TRY_BEGIN { - return S_FALSE; + Close(); + RINOK(Open2(stream, openArchiveCallback)); + _inStream = stream; } - */ return S_OK; COM_TRY_END } @@ -138,38 +133,20 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val switch(propID) { - case kpidPath: - prop = (const wchar_t *)NItemName::GetOSName2( - MultiByteToUnicodeString(item.Name, CP_OEMCP)); - break; - case kpidIsFolder: - prop = item.IsDirectory(); - break; - case kpidSize: - case kpidPackedSize: - prop = (UInt64)item.Size; - break; - case kpidLastWriteTime: - { - FILETIME utcFileTime; - if (item.ModificationTime != 0) - NTime::UnixTimeToFileTime(item.ModificationTime, utcFileTime); - else + case kpidPath: prop = NItemName::GetOSName2(MultiByteToUnicodeString(item.Name, CP_OEMCP)); break; + case kpidIsDir: prop = item.IsDir(); break; + case kpidSize: prop = item.Size; break; + case kpidPackSize: prop = item.GetPackSize(); break; + case kpidMTime: + if (item.MTime != 0) { - utcFileTime.dwLowDateTime = 0; - utcFileTime.dwHighDateTime = 0; + FILETIME ft; + NTime::UnixTimeToFileTime(item.MTime, ft); + prop = ft; } - prop = utcFileTime; - break; - } - case kpidUser: - prop = (const wchar_t *) - MultiByteToUnicodeString(item.UserName, CP_OEMCP); - break; - case kpidGroup: - prop = (const wchar_t *) - MultiByteToUnicodeString(item.GroupName, CP_OEMCP); break; + case kpidUser: prop = MultiByteToUnicodeString(item.UserName, CP_OEMCP); break; + case kpidGroup: prop = MultiByteToUnicodeString(item.GroupName, CP_OEMCP); break; } prop.Detach(value); return S_OK; @@ -192,8 +169,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, totalSize += _items[allFilesMode ? i : indices[i]].Size; extractCallback->SetTotal(totalSize); - UInt64 currentTotalSize = 0; - UInt64 currentItemSize; + UInt64 totalPackSize, curPackSize, curSize; + totalSize = totalPackSize = 0; NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; @@ -206,19 +183,24 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, CMyComPtr<ISequentialInStream> inStream(streamSpec); streamSpec->SetStream(_inStream); - for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) + CDummyOutStream *outStreamSpec = new CDummyOutStream; + CMyComPtr<ISequentialOutStream> outStream(outStreamSpec); + + for (i = 0; i < numItems; i++, totalSize += curSize, totalPackSize += curPackSize) { - lps->InSize = lps->OutSize = currentTotalSize; + lps->InSize = totalPackSize; + lps->OutSize = totalSize; RINOK(lps->SetCur()); CMyComPtr<ISequentialOutStream> realOutStream; - Int32 askMode = testMode ? + 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()) + curSize = item.Size; + curPackSize = item.GetPackSize(); + if (item.IsDir()) { RINOK(extractCallback->PrepareOperation(askMode)); RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); @@ -227,16 +209,16 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, if (!testMode && (!realOutStream)) continue; RINOK(extractCallback->PrepareOperation(askMode)); - if (testMode) - { - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); - continue; - } + + outStreamSpec->SetStream(realOutStream); + realOutStream.Release(); + outStreamSpec->Init(); + 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) ? + RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); + outStreamSpec->ReleaseStream(); + RINOK(extractCallback->SetOperationResult(copyCoderSpec->TotalSize == item.Size ? NArchive::NExtract::NOperationResult::kOK: NArchive::NExtract::NOperationResult::kDataError)); } diff --git a/CPP/7zip/Archive/Tar/TarHandler.h b/CPP/7zip/Archive/Tar/TarHandler.h index 8332fbfe..a98b5404 100755 --- a/CPP/7zip/Archive/Tar/TarHandler.h +++ b/CPP/7zip/Archive/Tar/TarHandler.h @@ -11,7 +11,7 @@ namespace NArchive { namespace NTar { -class CHandler: +class CHandler: public IInArchive, public IOutArchive, public CMyUnknownImp @@ -25,6 +25,8 @@ public: INTERFACE_IInArchive(;) INTERFACE_IOutArchive(;) + HRESULT Open2(IInStream *stream, IArchiveOpenCallback *callback); + private: CObjectVector<CItemEx> _items; CMyComPtr<IInStream> _inStream; diff --git a/CPP/7zip/Archive/Tar/TarHandlerOut.cpp b/CPP/7zip/Archive/Tar/TarHandlerOut.cpp index ea39d7e2..3454868e 100755 --- a/CPP/7zip/Archive/Tar/TarHandlerOut.cpp +++ b/CPP/7zip/Archive/Tar/TarHandlerOut.cpp @@ -15,7 +15,6 @@ using namespace NWindows; using namespace NCOM; -using namespace NTime; namespace NArchive { namespace NTar { @@ -27,34 +26,33 @@ STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type) } STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, - IArchiveUpdateCallback *updateCallback) + IArchiveUpdateCallback *callback) { COM_TRY_BEGIN - CObjectVector<CUpdateItemInfo> updateItems; - for(UInt32 i = 0; i < numItems; i++) + CObjectVector<CUpdateItem> updateItems; + for (UInt32 i = 0; i < numItems; i++) { - CUpdateItemInfo updateItem; + CUpdateItem ui; Int32 newData; Int32 newProperties; UInt32 indexInArchive; - if (!updateCallback) + if (!callback) return E_FAIL; - RINOK(updateCallback->GetUpdateItemInfo(i, - &newData, &newProperties, &indexInArchive)); - updateItem.NewProperties = IntToBool(newProperties); - updateItem.NewData = IntToBool(newData); - updateItem.IndexInArchive = indexInArchive; - updateItem.IndexInClient = i; + RINOK(callback->GetUpdateItemInfo(i, &newData, &newProperties, &indexInArchive)); + ui.NewProperties = IntToBool(newProperties); + ui.NewData = IntToBool(newData); + ui.IndexInArchive = indexInArchive; + ui.IndexInClient = i; if (IntToBool(newProperties)) { FILETIME utcTime; UString name; - bool isDirectoryStatusDefined; + /* UInt32 attributes; { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(i, kpidAttributes, &prop)); + RINOK(callback->GetProperty(i, kpidAttrib, &prop)); if (prop.vt == VT_EMPTY) attributes = 0; else if (prop.vt != VT_UI4) @@ -62,16 +60,17 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt else attributes = prop.ulVal; } + */ { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(i, kpidLastWriteTime, &prop)); + RINOK(callback->GetProperty(i, kpidMTime, &prop)); if (prop.vt != VT_FILETIME) return E_INVALIDARG; utcTime = prop.filetime; } { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(i, kpidPath, &prop)); + RINOK(callback->GetProperty(i, kpidPath, &prop)); if (prop.vt == VT_EMPTY) name.Empty(); else if (prop.vt != VT_BSTR) @@ -81,27 +80,21 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt } { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(i, kpidIsFolder, &prop)); + RINOK(callback->GetProperty(i, kpidIsDir, &prop)); if (prop.vt == VT_EMPTY) - isDirectoryStatusDefined = false; + ui.IsDir = false; else if (prop.vt != VT_BOOL) return E_INVALIDARG; else - { - updateItem.IsDirectory = (prop.boolVal != VARIANT_FALSE); - isDirectoryStatusDefined = true; - } + ui.IsDir = (prop.boolVal != VARIANT_FALSE); } - updateItem.Name = UnicodeStringToMultiByte( - NItemName::MakeLegalName(name), CP_OEMCP); - if (!isDirectoryStatusDefined) - updateItem.IsDirectory = ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0); - if (updateItem.IsDirectory) - updateItem.Name += '/'; + ui.Name = UnicodeStringToMultiByte(NItemName::MakeLegalName(name), CP_OEMCP); + if (ui.IsDir) + ui.Name += '/'; - if(!FileTimeToUnixTime(utcTime, updateItem.Time)) + if (!NTime::FileTimeToUnixTime(utcTime, ui.Time)) { - updateItem.Time = 0; + ui.Time = 0; // return E_INVALIDARG; } } @@ -110,16 +103,16 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt UInt64 size; { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(i, kpidSize, &prop)); + RINOK(callback->GetProperty(i, kpidSize, &prop)); if (prop.vt != VT_UI8) return E_INVALIDARG; size = prop.uhVal.QuadPart; } - updateItem.Size = size; + ui.Size = size; } - updateItems.Add(updateItem); + updateItems.Add(ui); } - return UpdateArchive(_inStream, outStream, _items, updateItems, updateCallback); + return UpdateArchive(_inStream, outStream, _items, updateItems, callback); COM_TRY_END } diff --git a/CPP/7zip/Archive/Tar/TarHeader.cpp b/CPP/7zip/Archive/Tar/TarHeader.cpp index 35f0d0cf..3275b284 100755 --- a/CPP/7zip/Archive/Tar/TarHeader.cpp +++ b/CPP/7zip/Archive/Tar/TarHeader.cpp @@ -15,7 +15,7 @@ namespace NFileHeader { const char *kLongLink2 = "@LongLink"; // The magic field is filled with this if uname and gname are valid. - namespace NMagic + namespace NMagic { const char *kUsTar = "ustar"; // 5 chars const char *kGNUTar = "GNUtar "; // 7 chars and a null diff --git a/CPP/7zip/Archive/Tar/TarHeader.h b/CPP/7zip/Archive/Tar/TarHeader.h index 19bb1cac..0b78bdc2 100755 --- a/CPP/7zip/Archive/Tar/TarHeader.h +++ b/CPP/7zip/Archive/Tar/TarHeader.h @@ -45,7 +45,7 @@ namespace NFileHeader namespace NMode { const int kSetUID = 04000; // Set UID on execution - const int kSetGID = 02000; // Set GID on execution + const int kSetGID = 02000; // Set GID on execution const int kSaveText = 01000; // Save text (sticky bit) } @@ -67,7 +67,7 @@ namespace NFileHeader namespace NLinkFlag { const char kOldNormal = '\0'; // Normal disk file, Unix compatible - const char kNormal = '0'; // Normal disk file + const char kNormal = '0'; // Normal disk file const char kLink = '1'; // Link to previously dumped file const char kSymbolicLink = '2'; // Symbolic link const char kCharacter = '3'; // Character special file @@ -76,12 +76,12 @@ namespace NFileHeader const char kFIFO = '6'; // FIFO special file const char kContiguous = '7'; // Contiguous file - const char kDumpDir = 'D'; /* GNUTYPE_DUMPDIR. + const char kDumpDir = 'D'; /* GNUTYPE_DUMPDIR. data: list of files created by the --incremental (-G) option - Each file name is preceded by either - - 'Y' (file should be in this archive) - - 'N' (file is a directory, or is not stored in the archive.) - Each file name is terminated by a null + an additional null after + Each file name is preceded by either + - 'Y' (file should be in this archive) + - 'N' (file is a directory, or is not stored in the archive.) + Each file name is terminated by a null + an additional null after the last file name. */ } @@ -94,7 +94,7 @@ namespace NFileHeader extern const char *kLongLink2; // = "@LongLink"; // The magic field is filled with this if uname and gname are valid. - namespace NMagic + namespace NMagic { extern const char *kUsTar; // = "ustar"; // 5 chars extern const char *kGNUTar; // = "GNUtar "; // 7 chars and a null diff --git a/CPP/7zip/Archive/Tar/TarIn.cpp b/CPP/7zip/Archive/Tar/TarIn.cpp index 1318613a..55215ac7 100755 --- a/CPP/7zip/Archive/Tar/TarIn.cpp +++ b/CPP/7zip/Archive/Tar/TarIn.cpp @@ -13,21 +13,6 @@ namespace NArchive { namespace NTar { -HRESULT CInArchive::ReadBytes(void *data, size_t size, size_t &processedSize) -{ - processedSize = size; - RINOK(ReadStream(m_Stream, data, &processedSize)); - m_Position += processedSize; - return S_OK; -} - -HRESULT CInArchive::Open(IInStream *inStream) -{ - RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_Position)); - m_Stream = inStream; - return S_OK; -} - static void MyStrNCpy(char *dest, const char *src, int size) { for (int i = 0; i < size; i++) @@ -62,130 +47,76 @@ static bool OctalToNumber32(const char *srcString, int size, UInt32 &res) #define RIF(x) { if (!(x)) return S_FALSE; } -static bool IsRecordLast(const char *record) +static bool IsRecordLast(const char *buf) { for (int i = 0; i < NFileHeader::kRecordSize; i++) - if (record[i] != 0) + if (buf[i] != 0) return false; return true; } static void ReadString(const char *s, int size, AString &result) { - if (size > NFileHeader::kRecordSize) - size = NFileHeader::kNameSize; - char tempString[NFileHeader::kRecordSize + 1]; - MyStrNCpy(tempString, s, size); - tempString[size] = '\0'; - result = tempString; -} - -static char GetHex(Byte value) -{ - return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10))); + char temp[NFileHeader::kRecordSize + 1]; + MyStrNCpy(temp, s, size); + temp[size] = '\0'; + result = temp; } -HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item) +static HRESULT GetNextItemReal(ISequentialInStream *stream, bool &filled, CItemEx &item, size_t &processedSize) { item.LongLinkSize = 0; - // NFileHeader::CRecord record; - char record[NFileHeader::kRecordSize]; - char *cur = record; + char buf[NFileHeader::kRecordSize]; + char *p = buf; filled = false; - size_t processedSize; - item.HeaderPosition = m_Position; - RINOK(ReadBytes(record, NFileHeader::kRecordSize, processedSize)); - if (processedSize == 0 || - (processedSize == NFileHeader::kRecordSize && IsRecordLast(record))) + processedSize = NFileHeader::kRecordSize; + RINOK(ReadStream(stream, buf, &processedSize)); + if (processedSize == 0 || (processedSize == NFileHeader::kRecordSize && IsRecordLast(buf))) return S_OK; if (processedSize < NFileHeader::kRecordSize) return S_FALSE; - // NFileHeader::CHeader &header = record.Header; - - AString name; - ReadString(cur, NFileHeader::kNameSize, name); - cur += NFileHeader::kNameSize; - - item.Name.Empty(); - int i; - for (i = 0; i < name.Length(); i++) - { - char c = name[i]; - if (((Byte)c) < 0x08) - { - return S_FALSE; - } - if (((Byte)c) < 0x20) - { - item.Name += '['; - item.Name += GetHex((Byte)(((Byte)c) >> 4)); - item.Name += GetHex((Byte)(((Byte)c) & 0xF)); - item.Name += ']'; - } - else - item.Name += c; - } + ReadString(p, NFileHeader::kNameSize, item.Name); p += NFileHeader::kNameSize; - RIF(OctalToNumber32(cur, 8, item.Mode)); - cur += 8; + RIF(OctalToNumber32(p, 8, item.Mode)); p += 8; - if (!OctalToNumber32(cur, 8, item.UID)) - item.UID = 0; - cur += 8; + if (!OctalToNumber32(p, 8, item.UID)) item.UID = 0; p += 8; + if (!OctalToNumber32(p, 8, item.GID)) item.GID = 0; p += 8; - if (!OctalToNumber32(cur, 8, item.GID)) - item.GID = 0; - cur += 8; - - RIF(OctalToNumber(cur, 12, item.Size)); - cur += 12; - - RIF(OctalToNumber32(cur, 12, item.ModificationTime)); - cur += 12; + RIF(OctalToNumber(p, 12, item.Size)); p += 12; + RIF(OctalToNumber32(p, 12, item.MTime)); p += 12; UInt32 checkSum; - RIF(OctalToNumber32(cur, 8, checkSum)); - memmove(cur, NFileHeader::kCheckSumBlanks, 8); - cur += 8; + RIF(OctalToNumber32(p, 8, checkSum)); + memcpy(p, NFileHeader::kCheckSumBlanks, 8); p += 8; - item.LinkFlag = *cur++; + item.LinkFlag = *p++; - ReadString(cur, NFileHeader::kNameSize, item.LinkName); - cur += NFileHeader::kNameSize; + ReadString(p, NFileHeader::kNameSize, item.LinkName); p += NFileHeader::kNameSize; - memmove(item.Magic, cur, 8); - cur += 8; + memcpy(item.Magic, p, 8); p += 8; - ReadString(cur, NFileHeader::kUserNameSize, item.UserName); - cur += NFileHeader::kUserNameSize; - ReadString(cur, NFileHeader::kUserNameSize, item.GroupName); - cur += NFileHeader::kUserNameSize; + ReadString(p, NFileHeader::kUserNameSize, item.UserName); p += NFileHeader::kUserNameSize; + ReadString(p, NFileHeader::kUserNameSize, item.GroupName); p += NFileHeader::kUserNameSize; - item.DeviceMajorDefined = (cur[0] != 0); - RIF(OctalToNumber32(cur, 8, item.DeviceMajor)); - cur += 8; - - item.DeviceMinorDefined = (cur[0] != 0); - RIF(OctalToNumber32(cur, 8, item.DeviceMinor)); - cur += 8; + item.DeviceMajorDefined = (p[0] != 0); RIF(OctalToNumber32(p, 8, item.DeviceMajor)); p += 8; + item.DeviceMinorDefined = (p[0] != 0); RIF(OctalToNumber32(p, 8, item.DeviceMinor)); p += 8; AString prefix; - ReadString(cur, NFileHeader::kPrefixSize, prefix); - cur += NFileHeader::kPrefixSize; - if (!prefix.IsEmpty() && item.IsMagic() && + ReadString(p, NFileHeader::kPrefixSize, prefix); + p += NFileHeader::kPrefixSize; + if (!prefix.IsEmpty() && item.IsMagic() && (item.LinkFlag != 'L' /* || prefix != "00000000000" */ )) item.Name = prefix + AString('/') + item.Name; if (item.LinkFlag == NFileHeader::NLinkFlag::kLink) item.Size = 0; - UInt32 checkSumReal = 0; - for(i = 0; i < NFileHeader::kRecordSize; i++) - checkSumReal += Byte(record[i]); + for (int i = 0; i < NFileHeader::kRecordSize; i++) + checkSumReal += (Byte)buf[i]; if (checkSumReal != checkSum) return S_FALSE; @@ -194,9 +125,10 @@ HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item) return S_OK; } -HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item) +HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &item) { - RINOK(GetNextItemReal(filled, item)); + size_t processedSize; + RINOK(GetNextItemReal(stream, filled, item, processedSize)); if (!filled) return S_OK; // GNUtar extension @@ -205,22 +137,25 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item) if (item.Name.Compare(NFileHeader::kLongLink) != 0) if (item.Name.Compare(NFileHeader::kLongLink2) != 0) return S_FALSE; - UInt64 headerPosition = item.HeaderPosition; - size_t processedSize; AString fullName; if (item.Size > (1 << 15)) return S_FALSE; - char *buffer = fullName.GetBuffer((int)item.Size + 1); - RINOK(ReadBytes(buffer, (size_t)item.Size, processedSize)); + int packSize = (int)item.GetPackSize(); + char *buffer = fullName.GetBuffer(packSize + 1); + + RINOK(ReadStream_FALSE(stream, buffer, packSize)); + processedSize += packSize; buffer[item.Size] = '\0'; fullName.ReleaseBuffer(); - if (processedSize != item.Size) - return S_FALSE; - RINOK(Skeep((0 - item.Size) & 0x1FF)); - RINOK(GetNextItemReal(filled, item)); + + UInt64 headerPosition = item.HeaderPosition; + { + size_t processedSize2; + RINOK(GetNextItemReal(stream, filled, item, processedSize2)); + } + item.LongLinkSize = (unsigned)processedSize; item.Name = fullName; - item.LongLinkSize = item.HeaderPosition - headerPosition; item.HeaderPosition = headerPosition; } else if (item.LinkFlag == 'g' || item.LinkFlag == 'x' || item.LinkFlag == 'X') @@ -238,20 +173,4 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item) return S_OK; } -HRESULT CInArchive::Skeep(UInt64 numBytes) -{ - UInt64 newPostion; - RINOK(m_Stream->Seek(numBytes, STREAM_SEEK_CUR, &newPostion)); - m_Position += numBytes; - if (m_Position != newPostion) - return E_FAIL; - return S_OK; -} - - -HRESULT CInArchive::SkeepDataRecords(UInt64 dataSize) -{ - return Skeep((dataSize + 0x1FF) & (~((UInt64)0x1FF))); -} - }} diff --git a/CPP/7zip/Archive/Tar/TarIn.h b/CPP/7zip/Archive/Tar/TarIn.h index 20c030ef..cc6e3f5b 100755 --- a/CPP/7zip/Archive/Tar/TarIn.h +++ b/CPP/7zip/Archive/Tar/TarIn.h @@ -11,20 +11,8 @@ namespace NArchive { namespace NTar { -class CInArchive -{ - CMyComPtr<IInStream> m_Stream; - UInt64 m_Position; - - HRESULT ReadBytes(void *data, size_t size, size_t &processedSize); -public: - HRESULT Open(IInStream *inStream); - HRESULT GetNextItemReal(bool &filled, CItemEx &itemInfo); - HRESULT GetNextItem(bool &filled, CItemEx &itemInfo); - HRESULT Skeep(UInt64 numBytes); - HRESULT SkeepDataRecords(UInt64 dataSize); -}; - +HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &itemInfo); + }} #endif diff --git a/CPP/7zip/Archive/Tar/TarItem.h b/CPP/7zip/Archive/Tar/TarItem.h index 451d74bc..7d95844d 100755 --- a/CPP/7zip/Archive/Tar/TarItem.h +++ b/CPP/7zip/Archive/Tar/TarItem.h @@ -3,8 +3,6 @@ #ifndef __ARCHIVE_TAR_ITEM_H #define __ARCHIVE_TAR_ITEM_H -#include <time.h> - #include "Common/Types.h" #include "Common/MyString.h" @@ -14,28 +12,29 @@ namespace NArchive { namespace NTar { -class CItem +struct CItem { -public: AString Name; + UInt64 Size; + UInt32 Mode; UInt32 UID; UInt32 GID; - UInt64 Size; - UInt32 ModificationTime; - char LinkFlag; + UInt32 MTime; + UInt32 DeviceMajor; + UInt32 DeviceMinor; + AString LinkName; - char Magic[8]; AString UserName; AString GroupName; + char Magic[8]; + char LinkFlag; bool DeviceMajorDefined; - UInt32 DeviceMajor; bool DeviceMinorDefined; - UInt32 DeviceMinor; - bool IsDirectory() const - { + bool IsDir() const + { switch(LinkFlag) { case NFileHeader::NLinkFlag::kDirectory: @@ -48,22 +47,23 @@ public: return false; } - bool IsMagic() const - { + bool IsMagic() const + { for (int i = 0; i < 5; i++) if (Magic[i] != NFileHeader::NMagic::kUsTar[i]) return false; return true; } + + UInt64 GetPackSize() const { return (Size + 0x1FF) & (~((UInt64)0x1FF)); } }; -class CItemEx: public CItem +struct CItemEx: public CItem { -public: UInt64 HeaderPosition; - UInt64 LongLinkSize; - UInt64 GetDataPosition() const { return HeaderPosition + LongLinkSize + NFileHeader::kRecordSize; }; - UInt64 GetFullSize() const { return LongLinkSize + NFileHeader::kRecordSize + Size; }; + unsigned LongLinkSize; + UInt64 GetDataPosition() const { return HeaderPosition + LongLinkSize + NFileHeader::kRecordSize; } + UInt64 GetFullSize() const { return LongLinkSize + NFileHeader::kRecordSize + Size; } }; }} diff --git a/CPP/7zip/Archive/Tar/TarOut.cpp b/CPP/7zip/Archive/Tar/TarOut.cpp index a697b4d2..0892748f 100755 --- a/CPP/7zip/Archive/Tar/TarOut.cpp +++ b/CPP/7zip/Archive/Tar/TarOut.cpp @@ -100,7 +100,7 @@ HRESULT COutArchive::WriteHeaderReal(const CItem &item) RETURN_IF_NOT_TRUE(MakeOctalString12(cur, item.Size)); cur += 12; - RETURN_IF_NOT_TRUE(MakeOctalString12(cur, item.ModificationTime)); + RETURN_IF_NOT_TRUE(MakeOctalString12(cur, item.MTime)); cur += 12; memmove(cur, NFileHeader::kCheckSumBlanks, 8); diff --git a/CPP/7zip/Archive/Tar/TarUpdate.cpp b/CPP/7zip/Archive/Tar/TarUpdate.cpp index b4241e0d..62c6bff6 100755 --- a/CPP/7zip/Archive/Tar/TarUpdate.cpp +++ b/CPP/7zip/Archive/Tar/TarUpdate.cpp @@ -18,7 +18,7 @@ namespace NTar { HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, const CObjectVector<NArchive::NTar::CItemEx> &inputItems, - const CObjectVector<CUpdateItemInfo> &updateItems, + const CObjectVector<CUpdateItem> &updateItems, IArchiveUpdateCallback *updateCallback) { COutArchive outArchive; @@ -29,11 +29,11 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, int i; for(i = 0; i < updateItems.Size(); i++) { - const CUpdateItemInfo &updateItem = updateItems[i]; - if (updateItem.NewData) - complexity += updateItem.Size; + const CUpdateItem &ui = updateItems[i]; + if (ui.NewData) + complexity += ui.Size; else - complexity += inputItems[updateItem.IndexInArchive].GetFullSize(); + complexity += inputItems[ui.IndexInArchive].GetFullSize(); } RINOK(updateCallback->SetTotal(complexity)); @@ -56,13 +56,13 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, lps->InSize = lps->OutSize = complexity; RINOK(lps->SetCur()); - const CUpdateItemInfo &updateItem = updateItems[i]; + const CUpdateItem &ui = updateItems[i]; CItem item; - if (updateItem.NewProperties) + if (ui.NewProperties) { item.Mode = 0777; - item.Name = (updateItem.Name); - if (updateItem.IsDirectory) + item.Name = (ui.Name); + if (ui.IsDir) { item.LinkFlag = NFileHeader::NLinkFlag::kDirectory; item.Size = 0; @@ -70,9 +70,9 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, else { item.LinkFlag = NFileHeader::NLinkFlag::kNormal; - item.Size = updateItem.Size; + item.Size = ui.Size; } - item.ModificationTime = updateItem.Time; + item.MTime = ui.Time; item.DeviceMajorDefined = false; item.DeviceMinorDefined = false; item.UID = 0; @@ -81,30 +81,30 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, } else { - const CItemEx &existItemInfo = inputItems[updateItem.IndexInArchive]; + const CItemEx &existItemInfo = inputItems[ui.IndexInArchive]; item = existItemInfo; } - if (updateItem.NewData) + if (ui.NewData) { - item.Size = updateItem.Size; + item.Size = ui.Size; if (item.Size == UInt64(Int64(-1))) return E_INVALIDARG; } else { - const CItemEx &existItemInfo = inputItems[updateItem.IndexInArchive]; + const CItemEx &existItemInfo = inputItems[ui.IndexInArchive]; item.Size = existItemInfo.Size; } - if (updateItem.NewData) + if (ui.NewData) { CMyComPtr<ISequentialInStream> fileInStream; - HRESULT res = updateCallback->GetStream(updateItem.IndexInClient, &fileInStream); + HRESULT res = updateCallback->GetStream(ui.IndexInClient, &fileInStream); if (res != S_FALSE) { RINOK(res); RINOK(outArchive.WriteHeader(item)); - if (!updateItem.IsDirectory) + if (!ui.IsDir) { RINOK(copyCoder->Code(fileInStream, outStream, NULL, NULL, progress)); if (copyCoderSpec->TotalSize != item.Size) @@ -112,14 +112,14 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, RINOK(outArchive.FillDataResidual(item.Size)); } } - complexity += updateItem.Size; + complexity += ui.Size; RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); } else { - const CItemEx &existItemInfo = inputItems[updateItem.IndexInArchive]; + const CItemEx &existItemInfo = inputItems[ui.IndexInArchive]; UInt64 size; - if (updateItem.NewProperties) + if (ui.NewProperties) { RINOK(outArchive.WriteHeader(item)); RINOK(inStream->Seek(existItemInfo.GetDataPosition(), STREAM_SEEK_SET, NULL)); diff --git a/CPP/7zip/Archive/Tar/TarUpdate.h b/CPP/7zip/Archive/Tar/TarUpdate.h index 67d671f5..7d196d1c 100755 --- a/CPP/7zip/Archive/Tar/TarUpdate.h +++ b/CPP/7zip/Archive/Tar/TarUpdate.h @@ -9,7 +9,7 @@ namespace NArchive { namespace NTar { -struct CUpdateItemInfo +struct CUpdateItem { bool NewData; bool NewProperties; @@ -19,12 +19,12 @@ struct CUpdateItemInfo UInt32 Time; UInt64 Size; AString Name; - bool IsDirectory; + bool IsDir; }; HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, const CObjectVector<CItemEx> &inputItems, - const CObjectVector<CUpdateItemInfo> &updateItems, + const CObjectVector<CUpdateItem> &updateItems, IArchiveUpdateCallback *updateCallback); }} diff --git a/CPP/7zip/Archive/Tar/tar.ico b/CPP/7zip/Archive/Tar/tar.ico Binary files differdeleted file mode 100755 index 6835885b..00000000 --- a/CPP/7zip/Archive/Tar/tar.ico +++ /dev/null |