195 changes: 195 additions & 0 deletions mythtv/libs/libmythbase/unziputil.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
#include "unziputil.h"

#include <array>

// Qt headers
#include <QByteArray>
#include <QFile>

// libmythbase headers
#include "mythlogging.h"
#include "unzip2.h"

bool extractZIP(QString zipFile, QString outDir)
{
UnZip unzip(std::move(zipFile));
return unzip.extractFile(std::move(outDir));
}

bool gzipFile(const QString &inFilename, const QString &gzipFilename)
{
QFile infile(inFilename);
QFile outfile(gzipFilename);

if (!infile.open(QIODevice::ReadOnly))
{
LOG(VB_GENERAL, LOG_ERR, QString("gzipFile(): Error opening file for reading '%1'").arg(inFilename));
return false;
}

if (!outfile.open(QIODevice::WriteOnly))
{
LOG(VB_GENERAL, LOG_ERR, QString("gzipFile(): Error opening file for writing '%1'").arg(gzipFilename));
infile.close();
return false;
}

QByteArray uncompressedData = infile.readAll();
QByteArray compressedData = gzipCompress(uncompressedData);

if (!outfile.write(compressedData))
{
LOG(VB_GENERAL, LOG_ERR, QString("gzipFile(): Error while writing to '%1'").arg(gzipFilename));
infile.close();
outfile.close();
return false;
}

infile.close();
outfile.close();

return true;
}

bool gunzipFile(const QString &gzipFilename, const QString &outFilename)
{
QFile infile(gzipFilename);
QFile outfile(outFilename);

if (!infile.open(QIODevice::ReadOnly))
{
LOG(VB_GENERAL, LOG_ERR, QString("gunzipFile(): Error opening file for reading '%1'").arg(gzipFilename));
return false;
}

if (!outfile.open(QIODevice::WriteOnly))
{
LOG(VB_GENERAL, LOG_ERR, QString("gunzipFile(): Error opening file for writing '%1'").arg(outFilename));
infile.close();
return false;
}

QByteArray compressedData = infile.readAll();
QByteArray uncompressedData = gzipUncompress(compressedData);

if (outfile.write(uncompressedData) < uncompressedData.size())
{
LOG(VB_GENERAL, LOG_ERR, QString("gunzipFile(): Error while writing to '%1'").arg(outFilename));
infile.close();
outfile.close();
return false;
}

infile.close();
outfile.close();

return true;
}

QByteArray gzipCompress(const QByteArray& data)
{
if (data.length() == 0)
return QByteArray();

std::array <char,1024> out {};

// allocate inflate state
z_stream strm {};

strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = data.length();
strm.next_in = (Bytef*)(data.data());

int ret = deflateInit2(&strm,
Z_DEFAULT_COMPRESSION,
Z_DEFLATED,
15 + 16,
8,
Z_DEFAULT_STRATEGY ); // gzip encoding
if (ret != Z_OK)
return QByteArray();

QByteArray result;

// run deflate()
do
{
strm.avail_out = out.size();
strm.next_out = (Bytef*)(out.data());

ret = deflate(&strm, Z_FINISH);

Q_ASSERT(ret != Z_STREAM_ERROR); // state not clobbered

switch (ret)
{
case Z_NEED_DICT:
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void)deflateEnd(&strm);
return QByteArray();
}

result.append(out.data(), out.size() - strm.avail_out);
}
while (strm.avail_out == 0);

// clean up and return

deflateEnd(&strm);

return result;
}

QByteArray gzipUncompress(const QByteArray &data)
{
if (data.length() == 0)
return QByteArray();

std::array<char,1024> out {};

// allocate inflate state
z_stream strm;
strm.total_in = 0;
strm.total_out = 0;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = data.length();
strm.next_in = (Bytef*)(data.data());

int ret = inflateInit2(&strm, 15 + 16);

if (ret != Z_OK)
return QByteArray();

QByteArray result;

do
{
strm.avail_out = out.size();
strm.next_out = (Bytef*)out.data();
ret = inflate(&strm, Z_NO_FLUSH);

Q_ASSERT(ret != Z_STREAM_ERROR); // state not clobbered

switch (ret)
{
case Z_NEED_DICT:
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void) deflateEnd(&strm);
return QByteArray();
}

result.append(out.data(), out.size() - strm.avail_out);
}
while (strm.avail_out == 0);

(void) inflateEnd(& strm);

return result;
}

17 changes: 17 additions & 0 deletions mythtv/libs/libmythbase/unziputil.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef UNZIPUTIL_H_
#define UNZIPUTIL_H_

#include <QByteArray>
#include <QString>

#include "mythbaseexp.h"

MBASE_PUBLIC bool extractZIP(QString zipFile, QString outDir);

MBASE_PUBLIC bool gzipFile(const QString &inFilename, const QString &zipFilename);
MBASE_PUBLIC bool gunzipFile(const QString &zipFilename, const QString &outFilename);

MBASE_PUBLIC QByteArray gzipCompress(const QByteArray &data);
MBASE_PUBLIC QByteArray gzipUncompress(const QByteArray &data);

#endif // UNZIPUTIL_H_
2 changes: 1 addition & 1 deletion mythtv/libs/libmythmetadata/musicmetadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#include "remotefile.h"
#include "storagegroup.h"
#include "mythsystem.h"
#include "mythcoreutil.h"
#include "unziputil.h"

// mythbase
#include "mythsorthelper.h"
Expand Down
2 changes: 1 addition & 1 deletion mythtv/libs/libmythupnp/httprequest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
#include "mythdate.h"
#include "mythcorecontext.h"
#include "mythtimer.h"
#include "mythcoreutil.h"
#include "unziputil.h"
#include "configuration.h"

#include "serializers/xmlSerializer.h"
Expand Down
2 changes: 1 addition & 1 deletion mythtv/programs/mythbackend/backendhousekeeper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#include "exitcodes.h"
#include "mythsystemlegacy.h"
#include "mythversion.h"
#include "mythcoreutil.h"
#include "unziputil.h"
#include "programtypes.h"
#include "recordingtypes.h"
#include "mythcorecontext.h"
Expand Down
2 changes: 1 addition & 1 deletion mythtv/programs/mythbackend/httpconfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#include "mythdirs.h"
#include "storagegroup.h"
#include "mythdownloadmanager.h"
#include "mythcoreutil.h"
#include "unziputil.h"

HttpConfig::HttpConfig() : HttpServerExtension("HttpConfig", QString())
{
Expand Down
1 change: 1 addition & 0 deletions mythtv/programs/mythfrontend/themechooser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
// MythTV headers
#include "mythcorecontext.h"
#include "mythcoreutil.h"
#include "unziputil.h" // for extractZIP
#include "mthreadpool.h"
#include "remotefile.h"
#include "mythdownloadmanager.h"
Expand Down