diff --git a/win-linux/extras/update-daemon/src/classes/platform_linux/cunzip.cpp b/win-linux/extras/update-daemon/src/classes/platform_linux/cunzip.cpp index 38e4c6840..9a0a0c242 100644 --- a/win-linux/extras/update-daemon/src/classes/platform_linux/cunzip.cpp +++ b/win-linux/extras/update-daemon/src/classes/platform_linux/cunzip.cpp @@ -39,96 +39,112 @@ #define BLOCK_SIZE 10240 -int unzipArchive(const string &zipFilePath, const string &folderPath, std::atomic_bool &run, string &error) +class CUnzip::CUnzipPrivate { - if (!NS_File::fileExists(zipFilePath) || !NS_File::dirExists(folderPath)) { - error = "Archive path is empty or dest dir not exist"; - return UNZIP_ERROR; - } +public: + CUnzipPrivate() + {} + ~CUnzipPrivate() + {} - struct archive *arch = archive_read_new(); - archive_read_support_filter_xz(arch); - archive_read_support_format_tar(arch); - if (archive_read_open_filename(arch, zipFilePath.c_str(), BLOCK_SIZE) != ARCHIVE_OK) { - error = "Cannot open archive"; - archive_read_free(arch); - return UNZIP_ERROR; - } - - int res = ARCHIVE_OK; - int ex_code = UNZIP_OK; - struct archive_entry *entry; - while ((res = archive_read_next_header(arch, &entry)) == ARCHIVE_OK) { - if (!run) { - ex_code = UNZIP_ABORT; - break; + int unzipArchive(const string &zipFilePath, const string &folderPath, string &error) + { + if (!NS_File::fileExists(zipFilePath) || !NS_File::dirExists(folderPath)) { + error = "Archive path is empty or dest dir not exist"; + return UNZIP_ERROR; + } + struct archive *arch = archive_read_new(); + archive_read_support_filter_xz(arch); + archive_read_support_format_tar(arch); + if (archive_read_open_filename(arch, zipFilePath.c_str(), BLOCK_SIZE) != ARCHIVE_OK) { + error = "Cannot open archive"; + archive_read_free(arch); + return UNZIP_ERROR; } - const char *entryname = archive_entry_pathname(entry); - if (!entryname) { - error = "Invalid entry name"; - break; - } - - char outpath[1024] = {0}; - snprintf(outpath, sizeof(outpath), "%s/%s", folderPath.c_str(), entryname); - - if (archive_entry_filetype(entry) == AE_IFREG) { - archive_entry_set_pathname(entry, outpath); - res = archive_read_extract(arch, entry, ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM - | ARCHIVE_EXTRACT_ACL | ARCHIVE_EXTRACT_FFLAGS - | ARCHIVE_EXTRACT_NO_OVERWRITE); - if (res != ARCHIVE_OK) { - error = "Cannot extract entry"; + int res = ARCHIVE_OK; + int ex_code = UNZIP_OK; + struct archive_entry *entry; + while ((res = archive_read_next_header(arch, &entry)) == ARCHIVE_OK) { + if (!run) { + ex_code = UNZIP_ABORT; break; } + + const char *entryname = archive_entry_pathname(entry); + if (!entryname) { + error = "Invalid entry name"; + break; + } + + char outpath[1024] = {0}; + snprintf(outpath, sizeof(outpath), "%s/%s", folderPath.c_str(), entryname); + + if (archive_entry_filetype(entry) == AE_IFREG) { + archive_entry_set_pathname(entry, outpath); + res = archive_read_extract(arch, entry, ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM + | ARCHIVE_EXTRACT_ACL | ARCHIVE_EXTRACT_FFLAGS + | ARCHIVE_EXTRACT_NO_OVERWRITE); + if (res != ARCHIVE_OK) { + error = "Cannot extract entry"; + break; + } + } } + + if (res != ARCHIVE_EOF && ex_code != UNZIP_ABORT) { + error = string("Error reading archive: ") + archive_error_string(arch); + ex_code = UNZIP_ERROR; + } + + archive_read_close(arch); + archive_read_free(arch); + return ex_code; } - if (res != ARCHIVE_EOF && ex_code != UNZIP_ABORT) { - error = string("Error reading archive: ") + archive_error_string(arch); - ex_code = UNZIP_ERROR; - } + FnVoidInt complete_callback = nullptr; + std::atomic_bool run; + std::future future; +}; - archive_read_close(arch); - archive_read_free(arch); - return ex_code; -} -CUnzip::CUnzip() + +CUnzip::CUnzip() : + pimpl(new CUnzipPrivate) { - m_run = false; + pimpl->run = false; } CUnzip::~CUnzip() { - m_run = false; - if (m_future.valid()) - m_future.wait(); + pimpl->run = false; + if (pimpl->future.valid()) + pimpl->future.wait(); + delete pimpl, pimpl = nullptr; } void CUnzip::extractArchive(const string &zipFilePath, const string &folderPath) { - m_run = false; - if (m_future.valid()) - m_future.wait(); - m_run = true; - m_future = std::async(std::launch::async, [=]() { + pimpl->run = false; + if (pimpl->future.valid()) + pimpl->future.wait(); + pimpl->run = true; + pimpl->future = std::async(std::launch::async, [=]() { string error; - int res = unzipArchive(zipFilePath, folderPath, m_run, error); + int res = pimpl->unzipArchive(zipFilePath, folderPath, error); if (!error.empty()) fprintf(stderr, "%s", error.c_str()); - if (m_complete_callback) - m_complete_callback(res); + if (pimpl->complete_callback) + pimpl->complete_callback(res); }); } void CUnzip::stop() { - m_run = false; + pimpl->run = false; } void CUnzip::onComplete(FnVoidInt callback) { - m_complete_callback = callback; + pimpl->complete_callback = callback; } diff --git a/win-linux/extras/update-daemon/src/classes/platform_linux/cunzip.h b/win-linux/extras/update-daemon/src/classes/platform_linux/cunzip.h index 710a1aee5..60bfe68b0 100644 --- a/win-linux/extras/update-daemon/src/classes/platform_linux/cunzip.h +++ b/win-linux/extras/update-daemon/src/classes/platform_linux/cunzip.h @@ -59,9 +59,8 @@ public: void onComplete(FnVoidInt callback); private: - FnVoidInt m_complete_callback = nullptr; - std::atomic_bool m_run; - std::future m_future; + class CUnzipPrivate; + CUnzipPrivate *pimpl = nullptr; }; #endif // CUNZIP_H diff --git a/win-linux/extras/update-daemon/src/classes/platform_win/cunzip.cpp b/win-linux/extras/update-daemon/src/classes/platform_win/cunzip.cpp index 683b4ad6d..faa44e8d0 100644 --- a/win-linux/extras/update-daemon/src/classes/platform_win/cunzip.cpp +++ b/win-linux/extras/update-daemon/src/classes/platform_win/cunzip.cpp @@ -36,123 +36,137 @@ #include -int extractRecursively(IShellDispatch *pISD, const CComPtr &pSrcFolder, const wstring &destFolder, std::atomic_bool &run) +class CUnzip::CUnzipPrivate { - CComPtr pItems; - if (FAILED(pSrcFolder->Items(&pItems))) - return UNZIP_ERROR; +public: + CUnzipPrivate() + {} + ~CUnzipPrivate() + {} - long itemCount = 0; - if (FAILED(pItems->get_Count(&itemCount))) - return UNZIP_ERROR; - - for (int i = 0; i < itemCount; i++) { - if (!run) - return UNZIP_ABORT; - - CComPtr pItem; - if (FAILED(pItems->Item(CComVariant(i), &pItem))) + int extractRecursively(IShellDispatch *pISD, const CComPtr &pSrcFolder, const wstring &destFolder) + { + CComPtr pItems; + if (FAILED(pSrcFolder->Items(&pItems))) return UNZIP_ERROR; - VARIANT_BOOL isFolder = VARIANT_FALSE; - if (FAILED(pItem->get_IsFolder(&isFolder))) + long itemCount = 0; + if (FAILED(pItems->get_Count(&itemCount))) return UNZIP_ERROR; - if (isFolder == VARIANT_TRUE) { - // Source path - CComPtr pSubFolder; - if (FAILED(pISD->NameSpace(CComVariant(pItem), &pSubFolder))) + for (int i = 0; i < itemCount; i++) { + if (!run) + return UNZIP_ABORT; + + CComPtr pItem; + if (FAILED(pItems->Item(CComVariant(i), &pItem))) return UNZIP_ERROR; - // Dest path - BSTR bstrName; - if (FAILED(pItem->get_Name(&bstrName))) + VARIANT_BOOL isFolder = VARIANT_FALSE; + if (FAILED(pItem->get_IsFolder(&isFolder))) return UNZIP_ERROR; - wstring targetFolder = destFolder + L"\\" + bstrName; - SysFreeString(bstrName); - if (CreateDirectory(targetFolder.c_str(), NULL) == 0) - return UNZIP_ERROR; + if (isFolder == VARIANT_TRUE) { + // Source path + CComPtr pSubFolder; + if (FAILED(pISD->NameSpace(CComVariant(pItem), &pSubFolder))) + return UNZIP_ERROR; - int res = extractRecursively(pISD, pSubFolder, targetFolder, run); - if (res != UNZIP_OK) - return res; + // Dest path + BSTR bstrName; + if (FAILED(pItem->get_Name(&bstrName))) + return UNZIP_ERROR; - } else { - CComPtr pDestFolder; - if (FAILED(pISD->NameSpace(CComVariant(destFolder.c_str()), &pDestFolder))) - return UNZIP_ERROR; - if (FAILED(pDestFolder->CopyHere(CComVariant(pItem), CComVariant(1024 | 512 | 16 | 4)))) - return UNZIP_ERROR; + wstring targetFolder = destFolder + L"\\" + bstrName; + SysFreeString(bstrName); + if (CreateDirectory(targetFolder.c_str(), NULL) == 0) + return UNZIP_ERROR; + + int res = extractRecursively(pISD, pSubFolder, targetFolder); + if (res != UNZIP_OK) + return res; + + } else { + CComPtr pDestFolder; + if (FAILED(pISD->NameSpace(CComVariant(destFolder.c_str()), &pDestFolder))) + return UNZIP_ERROR; + if (FAILED(pDestFolder->CopyHere(CComVariant(pItem), CComVariant(1024 | 512 | 16 | 4)))) + return UNZIP_ERROR; + } } - } - return UNZIP_OK; -} - -int unzipArchive(const wstring &zipFilePath, const wstring &folderPath, std::atomic_bool &run) -{ - if (!NS_File::fileExists(zipFilePath) || !NS_File::dirExists(folderPath)) - return UNZIP_ERROR; - - wstring file = NS_File::toNativeSeparators(zipFilePath); - wstring path = NS_File::toNativeSeparators(folderPath); - - HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); - if (FAILED(hr)) - return UNZIP_ERROR; - - IShellDispatch *pShell = NULL; - hr = CoCreateInstance(CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pShell)); - if (FAILED(hr)) { - CoUninitialize(); - return UNZIP_ERROR; + return UNZIP_OK; } - CComPtr pSrcFolder; - if (FAILED(pShell->NameSpace(CComVariant(file.c_str()), &pSrcFolder))) { + int unzipArchive(const wstring &zipFilePath, const wstring &folderPath) + { + if (!NS_File::fileExists(zipFilePath) || !NS_File::dirExists(folderPath)) + return UNZIP_ERROR; + + wstring file = NS_File::toNativeSeparators(zipFilePath); + wstring path = NS_File::toNativeSeparators(folderPath); + + HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + if (FAILED(hr)) + return UNZIP_ERROR; + + IShellDispatch *pShell = NULL; + hr = CoCreateInstance(CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pShell)); + if (FAILED(hr)) { + CoUninitialize(); + return UNZIP_ERROR; + } + + CComPtr pSrcFolder; + if (FAILED(pShell->NameSpace(CComVariant(file.c_str()), &pSrcFolder))) { + pShell->Release(); + CoUninitialize(); + return UNZIP_ERROR; + } + int res = extractRecursively(pShell, pSrcFolder, path); + pSrcFolder.Release(); pShell->Release(); CoUninitialize(); - return UNZIP_ERROR; + return res; } - int res = extractRecursively(pShell, pSrcFolder, path, run); - pSrcFolder.Release(); - pShell->Release(); - CoUninitialize(); - return res; -} + FnVoidInt complete_callback = nullptr; + std::atomic_bool run; + std::future future; +}; -CUnzip::CUnzip() +CUnzip::CUnzip() : + pimpl(new CUnzipPrivate) { - m_run = false; + pimpl->run = false; } CUnzip::~CUnzip() { - m_run = false; - if (m_future.valid()) - m_future.wait(); + pimpl->run = false; + if (pimpl->future.valid()) + pimpl->future.wait(); + delete pimpl, pimpl = nullptr; } void CUnzip::extractArchive(const wstring &zipFilePath, const wstring &folderPath) { - m_run = false; - if (m_future.valid()) - m_future.wait(); - m_run = true; - m_future = std::async(std::launch::async, [=]() { - int res = unzipArchive(zipFilePath, folderPath, m_run); - if (m_complete_callback) - m_complete_callback(res); + pimpl->run = false; + if (pimpl->future.valid()) + pimpl->future.wait(); + pimpl->run = true; + pimpl->future = std::async(std::launch::async, [=]() { + int res = pimpl->unzipArchive(zipFilePath, folderPath); + if (pimpl->complete_callback) + pimpl->complete_callback(res); }); } void CUnzip::stop() { - m_run = false; + pimpl->run = false; } void CUnzip::onComplete(FnVoidInt callback) { - m_complete_callback = callback; + pimpl->complete_callback = callback; } diff --git a/win-linux/extras/update-daemon/src/classes/platform_win/cunzip.h b/win-linux/extras/update-daemon/src/classes/platform_win/cunzip.h index 50872d07c..5938fea96 100644 --- a/win-linux/extras/update-daemon/src/classes/platform_win/cunzip.h +++ b/win-linux/extras/update-daemon/src/classes/platform_win/cunzip.h @@ -59,9 +59,8 @@ public: void onComplete(FnVoidInt callback); private: - FnVoidInt m_complete_callback = nullptr; - std::atomic_bool m_run; - std::future m_future; + class CUnzipPrivate; + CUnzipPrivate *pimpl = nullptr; }; #endif // CUNZIP_H