server-sdk/src/serversdk/compression.cpp
2019-11-06 14:52:09 +01:00

114 lines
2.7 KiB
C++

#include "compression.h"
#include <QFileInfo>
#include <QDir>
#include <zlib.h> // gzip decompress
namespace core {
/**
* @brief Decompress gzip data
* @param compressed gzip data
* @return decompressed data
*/
QByteArray Compression::decompress(const QByteArray &compressed)
{
if (compressed.size() <= 4) {
qWarning("gUncompress: Input data is truncated");
return QByteArray();
}
QByteArray result;
int ret;
z_stream strm;
static const int CHUNK_SIZE = 1024;
char out[CHUNK_SIZE];
/* allocate inflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = compressed.size();
strm.next_in = (Bytef*)(compressed.data());
ret = inflateInit2(&strm, 15 + 32); // gzip decoding
if (ret != Z_OK)
return QByteArray();
// run inflate()
do {
strm.avail_out = CHUNK_SIZE;
strm.next_out = (Bytef*)(out);
ret = inflate(&strm, Z_NO_FLUSH);
Q_ASSERT(ret != Z_STREAM_ERROR); // state not clobbered
switch (ret) {
case Z_NEED_DICT:
return QByteArray();
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void)inflateEnd(&strm);
return QByteArray();
}
result.append(out, CHUNK_SIZE - strm.avail_out);
} while (strm.avail_out == 0);
// clean up and return
inflateEnd(&strm);
// Calculate compression ratio
// original :200
// compressed :100
// ratio = 0.5
float ratio = (float)compressed.count() / (float)result.count();
float compression = ratio * 100.0;
qCInfo(sdkcompress) << "compress data:" << compressed.count()
<< "uncompressed data:" << result.count()
<< "compression:" << compression;
return result;
}
/**
* @brief Return path to source directory
* @param subpath ( e.g. test/data )
* @return absolute path to desired subpath in source folder
*/
QString Compression::sourcePath(const QString &subpath)
{
QDir dir(__FILE__);
dir.cdUp();
dir.cdUp();
dir.cdUp();
return dir.absoluteFilePath(subpath);
}
/**
* @brief Return data from source directory
* @param subpath ( e.g. test/data/gizp.src )
* @return data of file - QByteArray
*/
QByteArray Compression::sourceData(const QString &subpath)
{
// Get data from file
QString filePath = sourcePath(subpath);
if (! QFileInfo::exists(filePath)) {
qCWarning(sdkcompress) << "path does not exists:" << filePath;
return QByteArray();
}
QFile file(filePath);
if ( file.open(QIODevice::ReadOnly) )
return file.readAll();
return QByteArray();
}
} // namespace core