Add LZMA writing to the Linux backend

Won't build in Qt Creator unless you get xz-libs yourself

Part of #61
This commit is contained in:
Martin Briza 2017-01-17 15:19:56 +01:00
parent 35929e23e3
commit 18fa7bfa3f
4 changed files with 108 additions and 3 deletions

2
dist/win/build.sh vendored
View File

@ -31,7 +31,7 @@ fi
PACKAGES="mingw32-mediawriter mingw32-qt5-qtbase mingw32-qt5-qtdeclarative mingw32-qt5-qtquickcontrols mingw32-nsis mono-devel"
BINARIES="libstdc++-6.dll libwinpthread-1.dll libgcc_s_sjlj-1.dll libcrypto-10.dll libssl-10.dll libpng16-16.dll libharfbuzz-0.dll libpcre-1.dll libintl-8.dll iconv.dll libpcre16-0.dll libEGL.dll libglib-2.0-0.dll libGLESv2.dll zlib1.dll Qt5Core.dll Qt5Gui.dll Qt5Network.dll Qt5Qml.dll Qt5Quick.dll Qt5Svg.dll Qt5Widgets.dll Qt5WinExtras.dll"
BINARIES="libstdc++-6.dll libwinpthread-1.dll libgcc_s_sjlj-1.dll libcrypto-10.dll libssl-10.dll libpng16-16.dll liblzma-5.dll libharfbuzz-0.dll libpcre-1.dll libintl-8.dll iconv.dll libpcre16-0.dll libEGL.dll libglib-2.0-0.dll libGLESv2.dll zlib1.dll Qt5Core.dll Qt5Gui.dll Qt5Network.dll Qt5Qml.dll Qt5Quick.dll Qt5Svg.dll Qt5Widgets.dll Qt5WinExtras.dll"
PLUGINS="imageformats/qjpeg.dll imageformats/qsvg.dll platforms/qwindows.dll"
QMLMODULES="Qt QtQml QtQuick/Controls QtQuick/Dialogs QtQuick/Extras QtQuick/Layouts QtQuick/PrivateWidgets QtQuick/Window.2 QtQuick.2"

View File

@ -2,7 +2,7 @@ TEMPLATE = app
QT += core network
LIBS += -lisomd5
LIBS += -lisomd5 -lliblzma
CONFIG += c++11
CONFIG += console

View File

@ -31,8 +31,11 @@
#include <io.h>
#include <windows.h>
#include <lzma.h>
#include "isomd5/libcheckisomd5.h"
WriteJob::WriteJob(const QString &what, const QString &where)
: QObject(nullptr), what(what), dd(new QProcess(this))
{
@ -270,7 +273,6 @@ void WriteJob::work() {
}
bool WriteJob::write() {
removeMountPoints(where);
cleanDrive(where);
@ -280,6 +282,102 @@ bool WriteJob::write() {
return false;
}
if (what.endsWith(".xz"))
return writeCompressed(drive);
else
return writePlain(drive);
}
bool WriteJob::writeCompressed(HANDLE drive) {
qint64 totalRead = 0;
lzma_stream strm = LZMA_STREAM_INIT;
lzma_ret ret;
uint8_t *inBuffer = new uint8_t[BLOCK_SIZE];
uint8_t *outBuffer = new uint8_t[BLOCK_SIZE];
QFile file(what);
file.open(QIODevice::ReadOnly);
ret = lzma_stream_decoder(&strm, MEDIAWRITER_LZMA_LIMIT, LZMA_CONCATENATED);
if (ret != LZMA_OK) {
err << tr("Failed to start decompressing.");
return false;
}
strm.next_in = inBuffer;
strm.avail_in = 0;
strm.next_out = outBuffer;
strm.avail_out = BLOCK_SIZE;
OVERLAPPED osWrite;
memset(&osWrite, 0, sizeof(osWrite));
osWrite.hEvent = 0;
while (true) {
if (strm.avail_in == 0) {
qint64 len = file.read((char*) inBuffer, BLOCK_SIZE);
totalRead += len;
strm.next_in = inBuffer;
strm.avail_in = len;
out << totalRead << "\n";
out.flush();
}
ret = lzma_code(&strm, strm.avail_in == 0 ? LZMA_FINISH : LZMA_RUN);
if (ret == LZMA_STREAM_END) {
if (!writeBlock(drive, &osWrite, (char *) outBuffer, BLOCK_SIZE - strm.avail_out)) {
qApp->exit(1);
return false;
}
if (osWrite.Offset + BLOCK_SIZE < osWrite.Offset)
osWrite.OffsetHigh++;
osWrite.Offset += BLOCK_SIZE;
return true;
}
if (ret != LZMA_OK) {
switch (ret) {
case LZMA_MEM_ERROR:
err << tr("There is not enough memory to decompress the file.");
break;
case LZMA_FORMAT_ERROR:
case LZMA_DATA_ERROR:
case LZMA_BUF_ERROR:
err << tr("The downloaded compressed file is corrupted.");
break;
case LZMA_OPTIONS_ERROR:
err << tr("Unsupported compression options.");
break;
default:
err << tr("Unknown decompression error.");
break;
}
qApp->exit(4);
return false;
}
if (strm.avail_out == 0) {
if (!writeBlock(drive, &osWrite, (char *) outBuffer, BLOCK_SIZE - strm.avail_out)) {
qApp->exit(1);
return false;
}
if (osWrite.Offset + BLOCK_SIZE < osWrite.Offset)
osWrite.OffsetHigh++;
osWrite.Offset += BLOCK_SIZE;
strm.next_out = outBuffer;
strm.avail_out = BLOCK_SIZE;
}
}
}
bool WriteJob::writePlain(HANDLE drive) {
OVERLAPPED osWrite;
memset(&osWrite, 0, sizeof(osWrite));
osWrite.hEvent = 0;

View File

@ -26,6 +26,11 @@
#include <windows.h>
#ifndef MEDIAWRITER_LZMA_LIMIT
// 256MB memory limit for the decompressor
# define MEDIAWRITER_LZMA_LIMIT (1024*1024*256)
#endif
class WriteJob : public QObject
{
Q_OBJECT
@ -51,6 +56,8 @@ private slots:
void work();
bool write();
bool writeCompressed(HANDLE drive);
bool writePlain(HANDLE drive);
bool check();
private:
QString what;