multi-thread zip and unzip code. option to download appstore zip to mem. hasher mem support.
This commit is contained in:
@@ -14,9 +14,9 @@
|
||||
#include "download.hpp"
|
||||
#include "i18n.hpp"
|
||||
#include "yyjson_helper.hpp"
|
||||
#include "threaded_file_transfer.hpp"
|
||||
|
||||
#include <minIni.h>
|
||||
#include <minizip/unzip.h>
|
||||
#include <dirent.h>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
@@ -83,7 +83,6 @@ void from_json(const fs::FsPath& path, GhApiEntry& e) {
|
||||
|
||||
auto DownloadApp(ProgressBox* pbox, const GhApiAsset& gh_asset, const AssetEntry* entry) -> Result {
|
||||
static const fs::FsPath temp_file{"/switch/sphaira/cache/github/ghdl.temp"};
|
||||
constexpr auto chunk_size = 1024 * 512; // 512KiB
|
||||
|
||||
fs::FsNativeSd fs;
|
||||
R_TRY(fs.GetFsOpenResult());
|
||||
@@ -113,77 +112,7 @@ auto DownloadApp(ProgressBox* pbox, const GhApiAsset& gh_asset, const AssetEntry
|
||||
// 3. extract the zip / file
|
||||
if (gh_asset.content_type.find("zip") != gh_asset.content_type.npos) {
|
||||
log_write("found zip\n");
|
||||
auto zfile = unzOpen64(temp_file);
|
||||
R_UNLESS(zfile, 0x1);
|
||||
ON_SCOPE_EXIT(unzClose(zfile));
|
||||
|
||||
unz_global_info64 pglobal_info;
|
||||
if (UNZ_OK != unzGetGlobalInfo64(zfile, &pglobal_info)) {
|
||||
R_THROW(0x1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < pglobal_info.number_entry; i++) {
|
||||
if (i > 0) {
|
||||
if (UNZ_OK != unzGoToNextFile(zfile)) {
|
||||
log_write("failed to unzGoToNextFile\n");
|
||||
R_THROW(0x1);
|
||||
}
|
||||
}
|
||||
|
||||
if (UNZ_OK != unzOpenCurrentFile(zfile)) {
|
||||
log_write("failed to open current file\n");
|
||||
R_THROW(0x1);
|
||||
}
|
||||
ON_SCOPE_EXIT(unzCloseCurrentFile(zfile));
|
||||
|
||||
unz_file_info64 info;
|
||||
fs::FsPath file_path;
|
||||
if (UNZ_OK != unzGetCurrentFileInfo64(zfile, &info, file_path, sizeof(file_path), 0, 0, 0, 0)) {
|
||||
log_write("failed to get current info\n");
|
||||
R_THROW(0x1);
|
||||
}
|
||||
|
||||
file_path = fs::AppendPath(root_path, file_path);
|
||||
|
||||
Result rc;
|
||||
if (file_path[strlen(file_path) -1] == '/') {
|
||||
if (R_FAILED(rc = fs.CreateDirectoryRecursively(file_path)) && rc != FsError_PathAlreadyExists) {
|
||||
log_write("failed to create folder: %s 0x%04X\n", file_path.s, rc);
|
||||
R_THROW(rc);
|
||||
}
|
||||
} else {
|
||||
if (R_FAILED(rc = fs.CreateDirectoryRecursivelyWithPath(file_path)) && rc != FsError_PathAlreadyExists) {
|
||||
log_write("failed to create folder: %s 0x%04X\n", file_path.s, rc);
|
||||
R_THROW(rc);
|
||||
}
|
||||
|
||||
if (R_FAILED(rc = fs.CreateFile(file_path, info.uncompressed_size, 0)) && rc != FsError_PathAlreadyExists) {
|
||||
log_write("failed to create file: %s 0x%04X\n", file_path.s, rc);
|
||||
R_THROW(rc);
|
||||
}
|
||||
|
||||
fs::File f;
|
||||
R_TRY(fs.OpenFile(file_path, FsOpenMode_Write, &f));
|
||||
R_TRY(f.SetSize(info.uncompressed_size));
|
||||
|
||||
std::vector<char> buf(chunk_size);
|
||||
s64 offset{};
|
||||
while (offset < info.uncompressed_size) {
|
||||
R_TRY(pbox->ShouldExitResult());
|
||||
|
||||
const auto bytes_read = unzReadCurrentFile(zfile, buf.data(), buf.size());
|
||||
if (bytes_read <= 0) {
|
||||
log_write("failed to read zip file: %s\n", file_path.s);
|
||||
R_THROW(0x1);
|
||||
}
|
||||
|
||||
R_TRY(f.Write(offset, buf.data(), bytes_read, FsWriteOption_None));
|
||||
|
||||
pbox->UpdateTransfer(offset, info.uncompressed_size);
|
||||
offset += bytes_read;
|
||||
}
|
||||
}
|
||||
}
|
||||
R_TRY(thread::TransferUnzipAll(pbox, temp_file, &fs, root_path));
|
||||
} else {
|
||||
fs.CreateDirectoryRecursivelyWithPath(root_path);
|
||||
fs.DeleteFile(root_path);
|
||||
|
||||
Reference in New Issue
Block a user