Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
371 additions
and
91 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
#include "asyncwriter.h" | ||
|
||
#include <QMutexLocker> | ||
|
||
#include "fileio.h" | ||
|
||
AsyncWriter::AsyncWriter(QObject *parent) : | ||
QThread(parent), abort(false), waiting(false) | ||
{ | ||
} | ||
|
||
AsyncWriter::~AsyncWriter() | ||
{ | ||
mutex.lock(); | ||
abort = true; | ||
workToDo.wakeOne(); | ||
mutex.unlock(); | ||
|
||
wait(); | ||
} | ||
|
||
void AsyncWriter::writeData(const QList<ScribblePage> &data, const QFile &file) | ||
{ | ||
QMutexLocker locker(&mutex); | ||
|
||
this->data = data; | ||
this->file.setFileName(file.fileName()); | ||
|
||
if (!isRunning()) { | ||
start(); | ||
} else { | ||
workToDo.wakeOne(); | ||
} | ||
} | ||
|
||
void AsyncWriter::stopWriting() | ||
{ | ||
QMutexLocker locker(&mutex); | ||
|
||
file.setFileName(QString()); | ||
|
||
if (!waiting && isRunning()) | ||
workFinished.wait(&mutex, 3000); | ||
} | ||
|
||
void AsyncWriter::run() | ||
{ | ||
forever { | ||
mutex.lock(); | ||
QFile f; | ||
f.setFileName(file.fileName()); | ||
const QList<ScribblePage> d = data; | ||
mutex.unlock(); | ||
|
||
if (abort) { | ||
workFinished.wakeAll(); | ||
return; | ||
} | ||
|
||
if (!f.fileName().isEmpty()) { | ||
QByteArray output = ScribbleDocument::toXournalXMLFormat(d); | ||
FileIO::writeGZFileLocked(f, output); | ||
} | ||
|
||
mutex.lock(); | ||
file.setFileName(QString()); | ||
if (abort) { | ||
workFinished.wakeAll(); | ||
mutex.unlock(); | ||
return; | ||
} | ||
waiting = true; | ||
workFinished.wakeAll(); | ||
workToDo.wait(&mutex); | ||
waiting = false; | ||
mutex.unlock(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
#ifndef ASYNCIO_H | ||
#define ASYNCIO_H | ||
|
||
#include <QThread> | ||
#include <QFile> | ||
#include <QByteArray> | ||
#include <QMutex> | ||
#include <QWaitCondition> | ||
|
||
#include "scribble_document.h" | ||
|
||
/* Thread that is used to write data to a file asynchronously. | ||
* At any time, there is at most one writing operation pending | ||
* and any operation is allowed to fail. */ | ||
class AsyncWriter : public QThread | ||
{ | ||
Q_OBJECT | ||
public: | ||
explicit AsyncWriter(QObject *parent = 0); | ||
~AsyncWriter(); | ||
|
||
void writeData(const QList<ScribblePage> &data, const QFile &file); | ||
void stopWriting(); | ||
|
||
signals: | ||
|
||
protected: | ||
void run(); | ||
|
||
private: | ||
bool abort; | ||
bool waiting; | ||
QFile file; | ||
QList<ScribblePage> data; | ||
|
||
QMutex mutex; | ||
QWaitCondition workToDo; | ||
QWaitCondition workFinished; | ||
}; | ||
|
||
#endif // ASYNCIO_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
#include "fileio.h" | ||
|
||
#include "filelocker.h" | ||
#include "zlib.h" | ||
|
||
QByteArray FileIO::readGZFileLocked(const QFile &file) | ||
{ | ||
FileLocker locker(file); | ||
|
||
gzFile f = gzopen(file.fileName().toLocal8Bit().constData(), "r"); | ||
if (f == 0) | ||
return QByteArray(); | ||
|
||
QByteArray data; | ||
|
||
char buffer[1024]; | ||
while (!gzeof(f)) { | ||
int len = gzread(f, buffer, 1024); | ||
if (len < 0) { | ||
gzclose(f); | ||
return QByteArray(); | ||
} | ||
data.append(buffer, len); | ||
} | ||
gzclose(f); | ||
|
||
return data; | ||
} | ||
|
||
bool FileIO::writeGZFileLocked(const QFile &file, const QByteArray &data) | ||
{ | ||
FileLocker locker(file); | ||
|
||
gzFile f = gzopen(file.fileName().toLocal8Bit().constData(), "w"); | ||
if (f == 0) { | ||
return false; | ||
} | ||
gzwrite(f, data.data(), data.size()); | ||
gzclose(f); | ||
return true; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
#ifndef FILEIO_H | ||
#define FILEIO_H | ||
|
||
#include <QByteArray> | ||
#include <QFile> | ||
|
||
class FileIO | ||
{ | ||
public: | ||
static QByteArray readGZFileLocked(const QFile &file); | ||
static bool writeGZFileLocked(const QFile &file, const QByteArray &data); | ||
}; | ||
|
||
#endif // FILEIO_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
#ifndef FILELOCKER_H | ||
#define FILELOCKER_H | ||
|
||
#include <QFile> | ||
#include <QFileInfo> | ||
#include <QMutex> | ||
#include <QSet> | ||
|
||
class FileLockerManager | ||
{ | ||
public: | ||
FileLockerManager() { | ||
} | ||
|
||
void lockFile(QString file) { | ||
QMutexLocker locker(&mutex); | ||
lockedFiles.insert(file); | ||
} | ||
void unlockFile(QString file) { | ||
QMutexLocker locker(&mutex); | ||
lockedFiles.remove(file); | ||
} | ||
|
||
static FileLockerManager &instance() { | ||
static FileLockerManager manager; | ||
return manager; | ||
} | ||
|
||
private: | ||
QSet<QString> lockedFiles; | ||
QMutex mutex; | ||
|
||
Q_DISABLE_COPY(FileLockerManager) | ||
}; | ||
|
||
class FileLocker | ||
{ | ||
public: | ||
inline explicit FileLocker(QString file) { | ||
lockedFile = file; | ||
lock(); | ||
} | ||
|
||
inline explicit FileLocker(const QFile &file) { | ||
lockedFile = QFileInfo(file).absoluteFilePath(); | ||
lock(); | ||
} | ||
|
||
inline ~FileLocker() { | ||
unlock(); | ||
} | ||
private: | ||
inline void lock() { | ||
FileLockerManager::instance().lockFile(lockedFile); | ||
} | ||
inline void unlock() { | ||
FileLockerManager::instance().unlockFile(lockedFile); | ||
} | ||
|
||
QString lockedFile; | ||
Q_DISABLE_COPY(FileLocker) | ||
}; | ||
|
||
#endif // FILELOCKER_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.