22#include <QDirIterator>
29 OnScopeExit(
delete mz);
30 mz_zip_zero_struct(mz);
32 mz_bool readOk = mz_zip_reader_init_file(mz, utf8Bytes.
constData(), 0);
34 mz_zip_error read_err = mz_zip_get_last_error(mz);
36 mz_bool closeOk = mz_zip_reader_end(mz);
38 mz_zip_error close_err = mz_zip_get_last_error(mz);
40 if (!readOk || !closeOk) {
43 dd <<
"\n[Miniz sanity check]\n";
44 if (read_err != MZ_ZIP_NO_ERROR) {
45 dd <<
QString(
"Found an error while reading the file. Error code: %2, reason: %3").
arg(
static_cast<int>(read_err)).
arg(mz_zip_get_error_string(read_err));
47 if (close_err != MZ_ZIP_NO_ERROR) {
48 dd <<
QString(
"Found an error while closing the file. Error code: %2, reason: %3").
arg(
static_cast<int>(close_err)).
arg(mz_zip_get_error_string(close_err));
50 return Status(Status::ERROR_MINIZ_FAIL, dd);
57size_t MiniZ::istreamReadCallback(
void *pOpaque, mz_uint64 file_ofs,
void * pBuf,
size_t n)
59 std::istream *stream =
static_cast<std::istream*
>(pOpaque);
60 mz_int64 cur_ofs = stream->tellg();
61 if ((mz_int64)file_ofs < 0 || (cur_ofs != (mz_int64)file_ofs && stream->seekg((mz_int64)file_ofs, std::ios_base::beg)))
63 stream->read(
static_cast<char*
>(pBuf), n);
64 return stream->gcount();
71 dd <<
"\n[Miniz COMPRESSION diagnostics]\n";
72 dd <<
QString(
"Creating Zip %1 from folder %2").
arg(zipFilePath, srcFolderPath);
76 dd <<
"Adding / to path";
85 mz_zip_zero_struct(mz);
87 mz_bool ok = mz_zip_writer_init_file(mz, zipFilePath.
toUtf8().
data(), 0);
91 mz_zip_error err = mz_zip_get_last_error(mz);
92 dd <<
QString(
"Error: Failed to init writer. Error code: %1, reason: %2").
arg(
static_cast<int>(err)).
arg(mz_zip_get_error_string(err));
93 return Status(Status::FAIL, dd);
96 mz_zip_writer_end(mz);
102 std::stringstream mimeStream(mimeData.
toStdString());
103 ok = mz_zip_writer_add_read_buf_callback(mz,
"mimetype", MiniZ::istreamReadCallback, &mimeStream, mimeData.
length(),
104 0,
"", 0, MZ_NO_COMPRESSION, 0, 0,
108 mz_zip_error err = mz_zip_get_last_error(mz);
109 dd <<
QString(
"ERROR: Unable to add mimetype. Error code: %1, reason: %2").
arg(
static_cast<int>(err)).
arg(mz_zip_get_error_string(err));
110 return Status(Status::FAIL, dd);
117 dd <<
QString(
"Error: Source folder does not exist: %1").
arg(srcFolderPath);
118 return Status(Status::FAIL, dd);
120 QDir baseDir(canonicalFolder);
121 for (
const QString& filePath : fileList)
124 if (canonicalFilePath.
isEmpty())
126 dd <<
QString(
"Error: File does not exist: %1").
arg(filePath);
127 return Status(Status::FAIL, dd);
129 QString sRelativePath = baseDir.relativeFilePath(canonicalFilePath);
130 if (sRelativePath.
startsWith(
"../") || sRelativePath ==
"..")
132 dd <<
QString(
"Error: File is outside the base folder: %1").
arg(filePath);
133 return Status(Status::FAIL, dd);
135 if (sRelativePath ==
"mimetype")
continue;
139 ok = mz_zip_writer_add_file(mz,
141 filePath.toUtf8().data(),
142 "", 0, MZ_BEST_SPEED);
145 mz_zip_error err = mz_zip_get_last_error(mz);
146 dd <<
QString(
"Error: Unable to add file: %3. Error code: %1, reason: %2 - Aborting!").
arg(
static_cast<int>(err)).
arg(mz_zip_get_error_string(err), sRelativePath);
147 return Status(Status::FAIL, dd);
150 ok &= mz_zip_writer_finalize_archive(mz);
153 mz_zip_error err = mz_zip_get_last_error(mz);
154 dd <<
QString(
"Error: Failed to finalize archive. Error code %1, reason: %2").
arg(
static_cast<int>(err)).
arg(mz_zip_get_error_string(err));
155 return Status(Status::FAIL, dd);
164 dd <<
"\n[Miniz EXTRACTION diagnostics]\n";
165 dd <<
QString(
"Unzip file %1 to folder %2").
arg(zipFilePath, destPath);
167 if (!QFile::exists(zipFilePath))
169 dd <<
QString(
"Error: Zip file does not exist.");
170 return Status::FILE_NOT_FOUND;
174 QDir baseDir(sBaseDir);
175 if (!baseDir.exists())
177 bool ok = baseDir.mkpath(
".");
181 baseDir.makeAbsolute();
188 mz_zip_zero_struct(mz);
190 mz_bool ok = mz_zip_reader_init_file(mz, zipFilePath.
toUtf8().
data(), 0);
192 mz_zip_error err = mz_zip_get_last_error(mz);
193 dd <<
QString(
"Error: Failed to init reader. Error code: %1, reason: %2").
arg(
static_cast<int>(err)).
arg(mz_zip_get_error_string(err));
194 return Status(Status::FAIL, dd);
197 mz_zip_reader_end(mz);
200 int num = mz_zip_reader_get_num_files(mz);
203 OnScopeExit(
delete stat);
205 for (
int i = 0; i < num; ++i)
207 ok &= mz_zip_reader_file_stat(mz, i, stat);
209 if (stat->m_is_directory)
214 bool mkDirOK = baseDir.mkpath(sFolderPath);
217 dd <<
"Make Dir failed.";
221 for (
int i = 0; i < num; ++i)
223 ok &= mz_zip_reader_file_stat(mz, i, stat);
225 if (!stat->m_is_directory)
227 if (
QString(stat->m_filename) ==
"mimetype")
continue;
233 bool extractOK = mz_zip_reader_extract_to_file(mz, i, sFullPath.
toUtf8(), 0);
237 mz_zip_error err = mz_zip_get_last_error(mz);
238 dd <<
QString(
"WARNING: Unable to extract file. Error code: %1, reason: %2").
arg(
static_cast<int>(err)).
arg(mz_zip_get_error_string(err));
245 return Status(Status::FAIL, dd);
const char * constData() const const
int toStdString() const const
bool mkpath(const QString &dirPath) const const
QDir absoluteDir() const const
QString absolutePath() const const
QString canonicalFilePath() const const
QString & append(QChar ch)
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const const
QString fromUtf8(const char *str, int size)
bool isEmpty() const const
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const const
QByteArray toUtf8() const const