diff --git a/include/utils/extract.hpp b/include/utils/extract.hpp index 13b4307..5437f4b 100644 --- a/include/utils/extract.hpp +++ b/include/utils/extract.hpp @@ -39,6 +39,8 @@ enum ExtractError { EXTRACT_ERROR_WRITEFILE, }; +Result getExtractedSize(const std::string &archivePath, const std::string &wantedFile); + Result extractArchive(const std::string &archivePath, const std::string &wantedFile, const std::string &outputPath); #endif \ No newline at end of file diff --git a/source/utils/download.cpp b/source/utils/download.cpp index 56a8089..5c80a90 100644 --- a/source/utils/download.cpp +++ b/source/utils/download.cpp @@ -68,7 +68,7 @@ static bool killThread = false; static bool writeError = false; #define FILE_ALLOC_SIZE 0x60000 -extern int filesExtracted; +extern int filesExtracted, extractFilesCount; extern std::string extractingFile; char progressBarMsg[128] = ""; bool showProgressBar = false; @@ -477,7 +477,7 @@ void displayProgressBar() { case ProgressBar::Extracting: Gui::DrawStringCentered(0, 180, 0.6f, TEXT_COLOR, str, 400); - Gui::DrawStringCentered(0, 100, 0.6f, TEXT_COLOR, std::to_string(filesExtracted) + " " + (filesExtracted == 1 ? (Lang::get("FILE_EXTRACTED")).c_str() :(Lang::get("FILES_EXTRACTED"))), 400); + Gui::DrawStringCentered(0, 100, 0.6f, TEXT_COLOR, std::to_string(filesExtracted) + " / " + std::to_string(extractFilesCount) + " " + (filesExtracted == 1 ? (Lang::get("FILE_EXTRACTED")).c_str() :(Lang::get("FILES_EXTRACTED"))), 400); Gui::DrawStringCentered(0, 40, 0.6f, TEXT_COLOR, Lang::get("CURRENTLY_EXTRACTING") + "\n" + extractingFile, 400); Animation::DrawProgressBar(writeOffset, extractSize); break; diff --git a/source/utils/extract.cpp b/source/utils/extract.cpp index a71237f..88a3597 100644 --- a/source/utils/extract.cpp +++ b/source/utils/extract.cpp @@ -30,24 +30,42 @@ #include #include -int filesExtracted = 0; +int filesExtracted = 0, extractFilesCount = 0; std::string extractingFile = ""; /* That are our File Progressbar variable. */ u64 extractSize = 0, writeOffset = 0; -Result extractArchive(const std::string &archivePath, const std::string &wantedFile, const std::string &outputPath) { +Result getExtractedSize(const std::string &archivePath, const std::string &wantedFile) { extractSize = 0, writeOffset = 0, filesExtracted = 0; archive *a = archive_read_new(); archive_entry *entry; - int flags; - /* Select which attributes we want to restore. */ - flags = ARCHIVE_EXTRACT_TIME; - flags |= ARCHIVE_EXTRACT_PERM; - flags |= ARCHIVE_EXTRACT_ACL; - flags |= ARCHIVE_EXTRACT_FFLAGS; + archive_read_support_format_all(a); + + if (archive_read_open_filename(a, archivePath.c_str(), 0x4000) != ARCHIVE_OK) return EXTRACT_ERROR_OPENFILE; + + while(archive_read_next_header(a, &entry) == ARCHIVE_OK) { + int size = archive_entry_size(entry); + if (size > 0) { /* Ignore folders. */ + std::smatch match; + std::string entryName(); + if (std::regex_search(entryName, match, std::regex(wantedFile))) { + extractSize += size; + extractFilesCount++; + } + } + } + + archive_read_close(a); + archive_read_free(a); + return EXTRACT_ERROR_NONE; +} + +Result extractArchive(const std::string &archivePath, const std::string &wantedFile, const std::string &outputPath) { + archive *a = archive_read_new(); + archive_entry *entry; a = archive_read_new(); archive_read_support_format_all(a); @@ -69,8 +87,6 @@ Result extractArchive(const std::string &archivePath, const std::string &wantedF } uint sizeLeft = archive_entry_size(entry); - extractSize = sizeLeft; - writeOffset = 0; FILE *file = fopen(extractingFile.c_str(), "wb"); if (!file) return EXTRACT_ERROR_WRITEFILE; diff --git a/source/utils/scriptUtils.cpp b/source/utils/scriptUtils.cpp index d591e03..f729423 100644 --- a/source/utils/scriptUtils.cpp +++ b/source/utils/scriptUtils.cpp @@ -219,6 +219,7 @@ void ScriptUtils::extractFile(const std::string &file, const std::string &input, svcGetThreadPriority(&prio, CUR_THREAD_HANDLE); thread = threadCreate((ThreadFunc)displayProgressBar, NULL, 64 * 1024, prio - 1, -2, false); + getExtractedSize(in, input); extractArchive(in, input, out); showProgressBar = false; threadJoin(thread, U64_MAX);