summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@theqtcompany.com>2014-12-16 00:51:08 +0100
committerSimon Hausmann <simon.hausmann@theqtcompany.com>2014-12-16 00:51:38 +0100
commitc5c391e87636e5c4dbc3022b9d58626c1533f226 (patch)
tree679a8bbbc63395be30ebf5f6c80c1136f74a971f
parent86b7ed4df30f57fb994e5d032070ed118a9a7afa (diff)
Clean up the loading
Unify the load API and implementation to always go through FPDFAvail.
-rw-r--r--src/pdf/qpdfdocument.cpp111
-rw-r--r--src/pdf/qpdfdocument.h12
-rw-r--r--src/pdf/qpdfdocument_p.h9
-rw-r--r--tests/auto/qpdfdocument/tst_qpdfdocument.cpp15
4 files changed, 85 insertions, 62 deletions
diff --git a/src/pdf/qpdfdocument.cpp b/src/pdf/qpdfdocument.cpp
index b6c04e9..b48bbda 100644
--- a/src/pdf/qpdfdocument.cpp
+++ b/src/pdf/qpdfdocument.cpp
@@ -61,6 +61,9 @@ void QPdfDocumentPrivate::clear()
asyncBuffer.close();
asyncBuffer.setData(QByteArray());
asyncBuffer.open(QIODevice::ReadWrite);
+
+ if (sequentialSourceDevice)
+ sequentialSourceDevice->disconnect(q);
}
void QPdfDocumentPrivate::updateLastError()
@@ -81,7 +84,7 @@ void QPdfDocumentPrivate::updateLastError()
}
}
-QPdfDocument::Error QPdfDocumentPrivate::load(QIODevice *newDevice, bool transferDeviceOwnership, const QString &documentPassword)
+void QPdfDocumentPrivate::load(QIODevice *newDevice, bool transferDeviceOwnership)
{
clear();
@@ -89,57 +92,69 @@ QPdfDocument::Error QPdfDocumentPrivate::load(QIODevice *newDevice, bool transfe
ownDevice.reset(newDevice);
else
ownDevice.reset();
- device = newDevice;
-
- if (!device->isOpen() && !device->open(QIODevice::ReadOnly))
- return QPdfDocument::FileNotFoundError;
-
- // FPDF_FILEACCESS setup
- m_FileLen = device->size();
-
- password = documentPassword.toUtf8();
- doc = FPDF_LoadCustomDocument(this, password.constData());
- updateLastError();
- return lastError;
+ if (newDevice->isSequential()) {
+ sequentialSourceDevice = newDevice;
+ device = &asyncBuffer;
+ QNetworkReply *reply = qobject_cast<QNetworkReply*>(sequentialSourceDevice);
+ if (!reply) {
+ qWarning() << "QPdfDocument: Loading from sequential devices only supported with QNetworkAccessManager.";
+ return;
+ }
+
+ if (reply->header(QNetworkRequest::ContentLengthHeader).isValid())
+ _q_tryLoadingWithSizeFromContentHeader();
+ else
+ QObject::connect(reply, SIGNAL(metaDataChanged()), q, SLOT(_q_tryLoadingWithSizeFromContentHeader()));
+ } else {
+ device = newDevice;
+ initiateAsyncLoadWithTotalSizeKnown(device->size());
+ checkComplete();
+ }
}
-void QPdfDocumentPrivate::_q_initiateAsyncLoad()
+void QPdfDocumentPrivate::_q_tryLoadingWithSizeFromContentHeader()
{
QMutexLocker lock(pdfMutex());
if (avail)
return;
- QVariant contentLength = remoteDevice->header(QNetworkRequest::ContentLengthHeader);
+ QNetworkReply *networkReply = qobject_cast<QNetworkReply*>(sequentialSourceDevice);
+ if(!networkReply)
+ return;
+
+ QVariant contentLength = networkReply->header(QNetworkRequest::ContentLengthHeader);
if (!contentLength.isValid())
return;
- // FPDF_FILEACCESS setup
- m_FileLen = contentLength.toULongLong();
+ QObject::connect(sequentialSourceDevice, SIGNAL(readyRead()), q, SLOT(_q_copyFromSequentialSourceDevice()));
- QObject::connect(remoteDevice, SIGNAL(readyRead()), q, SLOT(_q_readFromDevice()));
+ initiateAsyncLoadWithTotalSizeKnown(contentLength.toULongLong());
- avail = FPDFAvail_Create(this, this);
+ if (sequentialSourceDevice->bytesAvailable())
+ _q_copyFromSequentialSourceDevice();
+}
- if (remoteDevice->bytesAvailable())
- _q_readFromDevice();
+void QPdfDocumentPrivate::initiateAsyncLoadWithTotalSizeKnown(quint64 totalSize)
+{
+ // FPDF_FILEACCESS setup
+ m_FileLen = totalSize;
+
+ avail = FPDFAvail_Create(this, this);
}
-void QPdfDocumentPrivate::_q_readFromDevice()
+void QPdfDocumentPrivate::_q_copyFromSequentialSourceDevice()
{
QMutexLocker lock(pdfMutex());
if (loadComplete)
return;
- QByteArray data = remoteDevice->read(remoteDevice->bytesAvailable());
+ QByteArray data = sequentialSourceDevice->read(sequentialSourceDevice->bytesAvailable());
if (data.isEmpty())
return;
asyncBuffer.seek(asyncBuffer.size());
asyncBuffer.write(data);
- if (!doc)
- tryLoadDocument();
- if (doc)
- checkComplete();
+ checkComplete();
}
void QPdfDocumentPrivate::tryLoadDocument()
@@ -161,7 +176,13 @@ void QPdfDocumentPrivate::tryLoadDocument()
void QPdfDocumentPrivate::checkComplete()
{
QMutexLocker lock(pdfMutex());
- if (!doc || !avail)
+ if (!avail || loadComplete)
+ return;
+
+ if (!doc)
+ tryLoadDocument();
+
+ if (!doc)
return;
loadComplete = true;
@@ -175,7 +196,7 @@ void QPdfDocumentPrivate::checkComplete()
bool QPdfDocumentPrivate::fpdf_IsDataAvail(_FX_FILEAVAIL *pThis, size_t offset, size_t size)
{
QPdfDocumentPrivate *d = static_cast<QPdfDocumentPrivate*>(pThis);
- return offset + size <= static_cast<quint64>(d->asyncBuffer.size());
+ return offset + size <= static_cast<quint64>(d->device->size());
}
int QPdfDocumentPrivate::fpdf_GetBlock(void *param, unsigned long position, unsigned char *pBuf, unsigned long size)
@@ -204,35 +225,27 @@ QPdfDocument::~QPdfDocument()
{
}
-QPdfDocument::Error QPdfDocument::load(const QString &fileName, const QString &password)
+QPdfDocument::Error QPdfDocument::load(const QString &fileName)
{
QMutexLocker lock(pdfMutex());
- return d->load(new QFile(fileName), /*transfer ownership*/true, password);
+ QScopedPointer<QFile> f(new QFile(fileName));
+ if (!f->open(QIODevice::ReadOnly)) {
+ d->lastError = FileNotFoundError;
+ } else {
+ d->load(f.take(), /*transfer ownership*/true);
+ }
+ return d->lastError;
}
-QPdfDocument::Error QPdfDocument::load(QIODevice *device, const QString &password)
+bool QPdfDocument::isLoading() const
{
- QMutexLocker lock(pdfMutex());
- return d->load(device, /*transfer ownership*/false, password);
+ return !d->loadComplete;
}
-void QPdfDocument::loadAsynchronously(QNetworkReply *device)
+void QPdfDocument::load(QIODevice *device)
{
QMutexLocker lock(pdfMutex());
- d->clear();
-
- d->ownDevice.reset();
- d->device = &d->asyncBuffer;
-
- if (d->remoteDevice)
- d->remoteDevice->disconnect(this);
-
- d->remoteDevice = device;
-
- if (d->remoteDevice->header(QNetworkRequest::ContentLengthHeader).isValid())
- d->_q_initiateAsyncLoad();
- else
- connect(d->remoteDevice, SIGNAL(metaDataChanged()), this, SLOT(_q_initiateAsyncLoad()));
+ d->load(device, /*transfer ownership*/false);
}
void QPdfDocument::setPassword(const QString &password)
diff --git a/src/pdf/qpdfdocument.h b/src/pdf/qpdfdocument.h
index ed87cac..6459f39 100644
--- a/src/pdf/qpdfdocument.h
+++ b/src/pdf/qpdfdocument.h
@@ -15,6 +15,7 @@ class Q_PDF_EXPORT QPdfDocument : public QObject
Q_OBJECT
Q_PROPERTY(int pageCount READ pageCount NOTIFY pageCountChanged FINAL)
Q_PROPERTY(QString password READ password WRITE setPassword FINAL)
+ Q_PROPERTY(bool loading READ isLoading FINAL)
public:
enum Error {
@@ -29,10 +30,11 @@ public:
explicit QPdfDocument(QObject *parent = 0);
~QPdfDocument();
- Error load(const QString &fileName, const QString &password = QString());
- Error load(QIODevice *device, const QString &password = QString());
+ Error load(const QString &fileName);
- void loadAsynchronously(QNetworkReply *device);
+ bool isLoading() const;
+
+ void load(QIODevice *device);
void setPassword(const QString &password);
QString password() const;
@@ -51,8 +53,8 @@ Q_SIGNALS:
void pageCountChanged();
private:
- Q_PRIVATE_SLOT(d, void _q_initiateAsyncLoad())
- Q_PRIVATE_SLOT(d, void _q_readFromDevice())
+ Q_PRIVATE_SLOT(d, void _q_tryLoadingWithSizeFromContentHeader())
+ Q_PRIVATE_SLOT(d, void _q_copyFromSequentialSourceDevice())
QScopedPointer<QPdfDocumentPrivate> d;
};
diff --git a/src/pdf/qpdfdocument_p.h b/src/pdf/qpdfdocument_p.h
index f37881d..7850c65 100644
--- a/src/pdf/qpdfdocument_p.h
+++ b/src/pdf/qpdfdocument_p.h
@@ -27,18 +27,19 @@ public:
QPointer<QIODevice> device;
QScopedPointer<QIODevice> ownDevice;
QBuffer asyncBuffer;
- QPointer<QNetworkReply> remoteDevice;
+ QPointer<QIODevice> sequentialSourceDevice;
QByteArray password;
QPdfDocument::Error lastError;
void clear();
- QPdfDocument::Error load(QIODevice *device, bool ownDevice, const QString &documentPassword);
+ void load(QIODevice *device, bool ownDevice);
void loadAsync(QIODevice *device);
- void _q_initiateAsyncLoad();
- void _q_readFromDevice();
+ void _q_tryLoadingWithSizeFromContentHeader();
+ void initiateAsyncLoadWithTotalSizeKnown(quint64 totalSize);
+ void _q_copyFromSequentialSourceDevice();
void tryLoadDocument();
void checkComplete();
diff --git a/tests/auto/qpdfdocument/tst_qpdfdocument.cpp b/tests/auto/qpdfdocument/tst_qpdfdocument.cpp
index 6ebd197..336c6e8 100644
--- a/tests/auto/qpdfdocument/tst_qpdfdocument.cpp
+++ b/tests/auto/qpdfdocument/tst_qpdfdocument.cpp
@@ -66,7 +66,12 @@ void tst_QPdfDocument::loadFromIODevice()
{
TemporaryPdf tempPdf;
QPdfDocument doc;
- QCOMPARE(doc.load(&tempPdf), QPdfDocument::NoError);
+ QSignalSpy startedSpy(&doc, SIGNAL(documentLoadStarted()));
+ QSignalSpy finishedSpy(&doc, SIGNAL(documentLoadFinished()));
+ doc.load(&tempPdf);
+ QCOMPARE(startedSpy.count(), 1);
+ QCOMPARE(finishedSpy.count(), 1);
+ QCOMPARE(doc.error(), QPdfDocument::NoError);
QCOMPARE(doc.pageCount(), 2);
}
@@ -83,7 +88,7 @@ void tst_QPdfDocument::loadAsync()
QSignalSpy startedSpy(&doc, SIGNAL(documentLoadStarted()));
QSignalSpy finishedSpy(&doc, SIGNAL(documentLoadFinished()));
- doc.loadAsynchronously(reply.data());
+ doc.load(reply.data());
QCOMPARE(startedSpy.count(), 1);
QCOMPARE(finishedSpy.count(), 1);
@@ -95,8 +100,10 @@ void tst_QPdfDocument::password()
QPdfDocument doc;
QCOMPARE(doc.pageCount(), 0);
QCOMPARE(doc.load(QFINDTESTDATA("pdf-sample.protected.pdf")), QPdfDocument::IncorrectPasswordError);
- QCOMPARE(doc.load(QFINDTESTDATA("pdf-sample.protected.pdf"), QStringLiteral("WrongPassword")), QPdfDocument::IncorrectPasswordError);
- QCOMPARE(doc.load(QFINDTESTDATA("pdf-sample.protected.pdf"), QStringLiteral("Qt")), QPdfDocument::NoError);
+ doc.setPassword(QStringLiteral("WrongPassword"));
+ QCOMPARE(doc.load(QFINDTESTDATA("pdf-sample.protected.pdf")), QPdfDocument::IncorrectPasswordError);
+ doc.setPassword(QStringLiteral("Qt"));
+ QCOMPARE(doc.load(QFINDTESTDATA("pdf-sample.protected.pdf")), QPdfDocument::NoError);
QCOMPARE(doc.pageCount(), 1);
}