Skip to content

AVE-346: Implement all the archives option #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/publish-7z.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
DOWNLOAD_ARTIFACTS_DIR: ${{ github.workspace }}\build\downloaded-artifacts
UPLOAD_ARTIFACTS_DIR: ${{ github.workspace }}\build\upload-artifacts
ARTIFACTS_NAME: 7zip-x64-Release
GDRIVE_ARTIFACTS_RELEASES_DIR: ${{ secrets.ARTIFACTS_STORAGE_ROOT_PATH }}/7z/releases
GDRIVE_ARTIFACTS_RELEASES_DIR: ${{ secrets.ARTIFACTS_SDK_STORAGE_ROOT_PATH }}/7zSDK/releases

steps:
- uses: actions/checkout@v4
Expand Down
63 changes: 60 additions & 3 deletions CPP/7zip/UI/Common/Extract.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ static HRESULT DecompressArchive(
CArchiveExtractCallback *ecs,
UString &errorMessage,
UInt64& stdInProcessed,
ScanFileState* pScanFileState)
ScanFileState* pScanFileState,
ArchiveOptions pArchiveOption)
{
const CArc &arc = arcLink.Arcs.Back();
stdInProcessed = 0;
Expand Down Expand Up @@ -95,13 +96,68 @@ static HRESULT DecompressArchive(
{
UInt32 numItems;
RINOK(archive->GetNumberOfItems(&numItems))
UInt32 fileCountWithinArchive = 0;
UInt64 totalUncompressedSize = 0;
UInt64 totalCompressedSize = 0;
for (UInt32 i = 0; i < numItems; ++i)
{
NCOM::CPropVariant prop;
archive->GetProperty(i, kpidIsDir, &prop);
if (prop.vt == VT_BOOL && !prop.boolVal)
{
fileCountWithinArchive++;

// Get uncompressed size
NCOM::CPropVariant sizeProp;
if (SUCCEEDED(archive->GetProperty(i, kpidSize, &sizeProp)) && sizeProp.vt == VT_UI8)
{
totalUncompressedSize += sizeProp.uhVal.QuadPart;
}
// Get compressed size
NCOM::CPropVariant packSizeProp;
if (SUCCEEDED(archive->GetProperty(i, kpidPackSize, &packSizeProp)) && packSizeProp.vt == VT_UI8)
{
totalCompressedSize += packSizeProp.uhVal.QuadPart;
}
}
}

if (totalUncompressedSize > 0)
{
double compressionRatio = (totalCompressedSize * 100.0) / totalUncompressedSize;
if (compressionRatio > pArchiveOption.ArchiveMaxRatio)
{
return S_OK;
}
}

if (pArchiveOption.ArchiveMaxCount != 0 && fileCountWithinArchive > pArchiveOption.ArchiveMaxCount)
{
return S_OK;
}

CReadArcItem item;

UString result;
CScannerCommonFunctions objScannerCommonFunctions;
UInt64 totalFileSize = 0;
for (UInt32 i = 0; i < numItems; i++)
{
if (pArchiveOption.ArchiveTotalMaxSize != 0 && fileCountWithinArchive > 0 && totalFileSize > pArchiveOption.ArchiveTotalMaxSize)
{
break;
}
NCOM::CPropVariant sizeProp;
HRESULT res = archive->GetProperty(i, kpidSize, &sizeProp);
if (SUCCEEDED(res) && sizeProp.vt == VT_UI8)
{
UInt64 fileSize = sizeProp.uhVal.QuadPart;
totalFileSize = totalFileSize + fileSize;
if (pArchiveOption.ArchiveMaxSize != 0 && fileSize > pArchiveOption.ArchiveMaxSize)
{
continue;
}
}
if (objScannerCommonFunctions.CheckForScanAbortState(pScanFileState))
{
realIndices.Clear();
Expand Down Expand Up @@ -299,7 +355,8 @@ HRESULT Extract(
#endif
UString &errorMessage,
CDecompressStat &st,
ScanFileState* pScanFileState)
ScanFileState* pScanFileState,
ArchiveOptions pArchiveOption)
{
st.Clear();
UInt64 totalPackSize = 0;
Expand Down Expand Up @@ -523,7 +580,7 @@ HRESULT Extract(
options,
calcCrc,
extractCallback, faeCallback, ecs,
errorMessage, packProcessed, pScanFileState))
errorMessage, packProcessed, pScanFileState, pArchiveOption))

if (!options.StdInMode)
packProcessed = fi.Size + arcLink.VolumesSize;
Expand Down
3 changes: 2 additions & 1 deletion CPP/7zip/UI/Common/Extract.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ HRESULT Extract(
#endif
UString &errorMessage,
CDecompressStat &st,
ScanFileState* pScanFileState);
ScanFileState* pScanFileState,
ArchiveOptions pArchiveOption);

#endif
10 changes: 9 additions & 1 deletion CPP/7zip/UI/Common/ScannerCommonFunctions.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
#pragma once

#include <iostream>
enum class ScanFileState
{
E_ScanFileState_None, //File scan state: running
E_ScanFileState_Abort //File scan state: scan abort by service
};

struct ArchiveOptions
{
uint64_t ArchiveMaxSize;
uint64_t ArchiveTotalMaxSize;
uint64_t ArchiveMaxRatio;
uint64_t ArchiveMaxCount;
};

class CScannerCommonFunctions
{
public:
Expand Down
11 changes: 6 additions & 5 deletions CPP/7zip/UI/Console/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -813,7 +813,7 @@ int Main2(
}

int ExtractArchiveFile(const TCHAR* chAction, const TCHAR* chArchiveName, const TCHAR* chInOutputFolderName,
const TCHAR* chPassword, const TCHAR* chFileFilter, ScanFileState* pScanFileState)
const TCHAR* chPassword, const TCHAR* chFileFilter, ScanFileState* pScanFileState, ArchiveOptions pArchiveOption)
{
#if defined(MY_CPU_SIZEOF_POINTER)
{ unsigned k = sizeof(void *); if (k != MY_CPU_SIZEOF_POINTER) throw "incorrect MY_CPU_PTR_SIZE"; }
Expand Down Expand Up @@ -1377,7 +1377,7 @@ int ExtractArchiveFile(const TCHAR* chAction, const TCHAR* chArchiveName, const
ArchivePathsFullSorted,
options.Censor.Pairs.Front().Head,
eo, ecs, ecs, ecs,
hashCalc, errorMessage, stat, pScanFileState);
hashCalc, errorMessage, stat, pScanFileState, pArchiveOption);

ecs->ClosePercents();

Expand Down Expand Up @@ -1639,10 +1639,10 @@ int ExtractArchiveFile(const TCHAR* chAction, const TCHAR* chArchiveName, const

bool WINAPI __stdcall UnMax7zArchive(const TCHAR* chAction, const TCHAR* chArchiveName,
const TCHAR* chOutputFolderName, const TCHAR* chPassword, const TCHAR* chFileFilter,
ScanFileState* pScanFileState)
ScanFileState* pScanFileState, ArchiveOptions pArchiveOption)
{
int iRet = ExtractArchiveFile(chAction, chArchiveName, chOutputFolderName,
chPassword, chFileFilter, pScanFileState);
chPassword, chFileFilter, pScanFileState, pArchiveOption);
return iRet == 0;
}

Expand All @@ -1659,6 +1659,7 @@ Description : It is a exported function which calls "ExtractFile" for extractio
bool WINAPI __stdcall Max7zArchive(const TCHAR* chAction, const TCHAR* chArchiveName,
const TCHAR* chInputFileFolderName, const TCHAR* chPassword, const TCHAR* chFileFilter)
{
int iRet = ExtractArchiveFile(chAction, chArchiveName, chInputFileFolderName, chPassword, chFileFilter, NULL);
ArchiveOptions pArchiveOption = { 0 };
int iRet = ExtractArchiveFile(chAction, chArchiveName, chInputFileFolderName, chPassword, chFileFilter, NULL, pArchiveOption);
return iRet == 0;
}
9 changes: 7 additions & 2 deletions Test_7zip/test_7zip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
namespace fs = std::filesystem;

using UnpackFunc = bool (*)(const TCHAR* chAction, const TCHAR* chArchiveName, const TCHAR* chOutputFolderName,
const TCHAR* chPassword, const TCHAR* chFileFilter, ScanFileState* pScanFileState);
const TCHAR* chPassword, const TCHAR* chFileFilter, ScanFileState* pScanFileState, ArchiveOptions pArchiveOption);
using PackFunc = bool (*)(const TCHAR* chAction, const TCHAR* chArchiveName, const TCHAR* chInputFileFolderName,
const TCHAR* chPassword, const TCHAR* chFileFilter);

Expand Down Expand Up @@ -75,8 +75,13 @@ TEST_CASE("Zipping/Unzipping the file", "[7zip]")
{
std::wstring unpackDirName = L"-o" + kTestDir.wstring();
ScanFileState fileState = ScanFileState::E_ScanFileState_None;
ArchiveOptions ArchiveConfig = { 0 };
ArchiveConfig.ArchiveMaxCount = 12;
ArchiveConfig.ArchiveMaxRatio = 250;
ArchiveConfig.ArchiveMaxSize = 0;
ArchiveConfig.ArchiveTotalMaxSize = 0;
bool result = g_UnpackFunc(L"x", kPackedFile.wstring().data(),
unpackDirName.data(), kPassword.data(), nullptr, &fileState);
unpackDirName.data(), kPassword.data(), nullptr, &fileState,ArchiveConfig);
REQUIRE(result);
REQUIRE(fs::exists(kUnpackedFile));
std::ifstream unpackedFile(kUnpackedFile);
Expand Down