Add support of zip archived components
This commit is contained in:
parent
7bc5030ed5
commit
0c3893ddf8
22
external/miniz/LICENSE
vendored
Normal file
22
external/miniz/LICENSE
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
Copyright 2013-2014 RAD Game Tools and Valve Software
|
||||||
|
Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
|
||||||
|
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
7657
external/miniz/miniz.c
vendored
Normal file
7657
external/miniz/miniz.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1338
external/miniz/miniz.h
vendored
Normal file
1338
external/miniz/miniz.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@ -18,6 +18,9 @@ linux{
|
|||||||
LIBS += -lX11
|
LIBS += -lX11
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SOURCES += $$PWD/external/miniz/miniz.c
|
||||||
|
INCLUDEPATH += $$PWD/external
|
||||||
|
|
||||||
VER=3.0.0
|
VER=3.0.0
|
||||||
DEFINES += VERSION="$$VER"
|
DEFINES += VERSION="$$VER"
|
||||||
VERSION = $$VER.0
|
VERSION = $$VER.0
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QNetworkReply>
|
#include <QNetworkReply>
|
||||||
|
#include <QScopeGuard>
|
||||||
#include <QSortFilterProxyModel>
|
#include <QSortFilterProxyModel>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
@ -17,6 +18,56 @@
|
|||||||
|
|
||||||
#include <random>
|
#include <random>
|
||||||
|
|
||||||
|
#define MINIZ_NO_ZLIB_APIS
|
||||||
|
#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES
|
||||||
|
#define MINIZ_NO_MALLOC
|
||||||
|
#define MINIZ_NO_STDIO
|
||||||
|
#define MINIZ_NO_ARCHIVE_WRITING_APIS
|
||||||
|
#include <miniz/miniz.h>
|
||||||
|
|
||||||
|
static QByteArray unpack(const QByteArray &data)
|
||||||
|
{
|
||||||
|
if (data.size() <= 4 || data.left(2) != "PK") {
|
||||||
|
LTRACE() << "Incorrect data to unpack" << LARG(data.size())
|
||||||
|
<< data.left(10);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
mz_zip_archive zip;
|
||||||
|
memset(&zip, 0, sizeof(zip));
|
||||||
|
if (!mz_zip_reader_init_mem(&zip, data.data(), data.size(), 0)) {
|
||||||
|
LTRACE() << "Failed to init zip reader for " << data.left(10)
|
||||||
|
<< mz_zip_get_error_string(zip.m_last_error);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto guard = qScopeGuard([&zip] { mz_zip_reader_end(&zip); });
|
||||||
|
|
||||||
|
const auto fileCount = mz_zip_reader_get_num_files(&zip);
|
||||||
|
if (fileCount < 1) {
|
||||||
|
LTRACE() << "No files in zip archive";
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto i = 0u; i < fileCount; ++i) {
|
||||||
|
mz_zip_archive_file_stat file_stat;
|
||||||
|
if (!mz_zip_reader_file_stat(&zip, i, &file_stat)) {
|
||||||
|
LTRACE() << "Failed to get file info" << LARG(i)
|
||||||
|
<< mz_zip_get_error_string(zip.m_last_error);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file_stat.m_is_directory)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
QByteArray result(file_stat.m_uncomp_size, 0);
|
||||||
|
mz_zip_reader_extract_to_mem(&zip, 0, result.data(), result.size(), 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
namespace update
|
namespace update
|
||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
@ -150,27 +201,36 @@ void Loader::handleUpdateReply(QNetworkReply *reply)
|
|||||||
{
|
{
|
||||||
reply->deleteLater();
|
reply->deleteLater();
|
||||||
|
|
||||||
|
const auto url = reply->url();
|
||||||
if (reply->error() != QNetworkReply::NoError) {
|
if (reply->error() != QNetworkReply::NoError) {
|
||||||
emit error(toError(*reply));
|
emit error(toError(*reply));
|
||||||
startDownloadUpdates(reply->url());
|
startDownloadUpdates(url);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto replyData = reply->readAll();
|
const auto replyData = reply->readAll();
|
||||||
if (replyData.isEmpty()) {
|
if (replyData.isEmpty()) {
|
||||||
emit error(
|
emit error(tr("Received empty updates info from %1").arg(url.toString()));
|
||||||
tr("Received empty updates info from %1").arg(reply->url().toString()));
|
startDownloadUpdates(url);
|
||||||
startDownloadUpdates(reply->url());
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto unpacked =
|
||||||
|
url.toString().endsWith(".zip") ? unpack(replyData) : replyData;
|
||||||
|
|
||||||
|
if (unpacked.isEmpty()) {
|
||||||
|
emit error(
|
||||||
|
tr("Empty updates info after unpacking from %1").arg(url.toString()));
|
||||||
|
startDownloadUpdates(url);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
SOFT_ASSERT(model_, return );
|
SOFT_ASSERT(model_, return );
|
||||||
const auto parseError = model_->parse(replyData);
|
const auto parseError = model_->parse(unpacked);
|
||||||
if (!parseError.isEmpty()) {
|
if (!parseError.isEmpty()) {
|
||||||
emit error(tr("Failed to parse updates from %1 (%2)")
|
emit error(tr("Failed to parse updates from %1 (%2)")
|
||||||
.arg(reply->url().toString(), parseError));
|
.arg(url.toString(), parseError));
|
||||||
startDownloadUpdates(reply->url());
|
startDownloadUpdates(url);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,20 +318,44 @@ bool Loader::handleComponentReply(QNetworkReply *reply)
|
|||||||
|
|
||||||
const auto &fileName = file->downloadPath;
|
const auto &fileName = file->downloadPath;
|
||||||
auto dir = QFileInfo(fileName).absoluteDir();
|
auto dir = QFileInfo(fileName).absoluteDir();
|
||||||
if (!dir.exists())
|
if (!dir.exists() && !dir.mkpath(".")) {
|
||||||
dir.mkpath(".");
|
finishUpdate(tr("Failed to create temp path %1").arg(dir.absolutePath()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto url = reply->url();
|
||||||
|
const auto replyData = reply->readAll();
|
||||||
|
if (replyData.isEmpty()) {
|
||||||
|
emit error(tr("Empty data downloaded from %1").arg(url.toString()));
|
||||||
|
|
||||||
|
if (!startDownload(*file))
|
||||||
|
finishUpdate();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto mustUnpack =
|
||||||
|
url.toString().endsWith(".zip") && !fileName.endsWith(".zip");
|
||||||
|
const auto unpacked = mustUnpack ? unpack(replyData) : replyData;
|
||||||
|
|
||||||
|
if (unpacked.isEmpty()) {
|
||||||
|
emit error(tr("Empty data after unpacking from %1").arg(url.toString()));
|
||||||
|
|
||||||
|
if (!startDownload(*file))
|
||||||
|
finishUpdate();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
QFile f(fileName);
|
QFile f(fileName);
|
||||||
if (!f.open(QFile::WriteOnly)) {
|
if (!f.open(QFile::WriteOnly)) {
|
||||||
const auto error =
|
const auto error = tr("Failed to save downloaded file %1 to %2. Error %3")
|
||||||
tr("Failed to save downloaded file %1 to %2. Error %3")
|
.arg(url.toString(), f.fileName(), f.errorString());
|
||||||
.arg(reply->url().toString(), f.fileName(), f.errorString());
|
|
||||||
finishUpdate(error);
|
finishUpdate(error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto replyData = reply->readAll();
|
f.write(unpacked);
|
||||||
f.write(replyData);
|
|
||||||
f.close();
|
f.close();
|
||||||
|
|
||||||
if (downloads_.empty())
|
if (downloads_.empty())
|
||||||
|
Loading…
Reference in New Issue
Block a user