summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron McCarthy <aaron.mccarthy@jollamobile.com>2014-02-19 16:38:10 +1000
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-03-14 06:16:11 +0100
commit3f4a3acab163fa6675a1513ab1fccdbda7723dd6 (patch)
tree16e63e4fedd6c9c8391593b4ae41d83c7e09245a
parent5f0023a7469e01bada70fbe677b76bb535eaa953 (diff)
Parse Nokia geocode response in helper thread.
Change-Id: I151bd5988d0340a8203aa9e014371989b023228b Reviewed-by: Alex Blasche <alexander.blasche@digia.com>
-rw-r--r--src/plugins/geoservices/nokia/qgeocodereply_nokia.cpp73
-rw-r--r--src/plugins/geoservices/nokia/qgeocodereply_nokia.h3
-rw-r--r--src/plugins/geoservices/nokia/qgeocodexmlparser.cpp40
-rw-r--r--src/plugins/geoservices/nokia/qgeocodexmlparser.h26
4 files changed, 79 insertions, 63 deletions
diff --git a/src/plugins/geoservices/nokia/qgeocodereply_nokia.cpp b/src/plugins/geoservices/nokia/qgeocodereply_nokia.cpp
index cb76fbca..8690eb65 100644
--- a/src/plugins/geoservices/nokia/qgeocodereply_nokia.cpp
+++ b/src/plugins/geoservices/nokia/qgeocodereply_nokia.cpp
@@ -51,22 +51,19 @@
#include <QtPositioning/QGeoShape>
+Q_DECLARE_METATYPE(QList<QGeoLocation>)
+
QT_BEGIN_NAMESPACE
QGeoCodeReplyNokia::QGeoCodeReplyNokia(QNetworkReply *reply, int limit, int offset,
const QGeoShape &viewport, QObject *parent)
- : QGeoCodeReply(parent),
- m_reply(reply)
+: QGeoCodeReply(parent), m_reply(reply), m_parsing(false)
{
- connect(m_reply,
- SIGNAL(finished()),
- this,
- SLOT(networkFinished()));
+ qRegisterMetaType<QList<QGeoLocation> >();
- connect(m_reply,
- SIGNAL(error(QNetworkReply::NetworkError)),
- this,
- SLOT(networkError(QNetworkReply::NetworkError)));
+ connect(m_reply, SIGNAL(finished()), this, SLOT(networkFinished()));
+ connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)),
+ this, SLOT(networkError(QNetworkReply::NetworkError)));
setLimit(limit);
setOffset(offset);
@@ -75,18 +72,19 @@ QGeoCodeReplyNokia::QGeoCodeReplyNokia(QNetworkReply *reply, int limit, int offs
QGeoCodeReplyNokia::~QGeoCodeReplyNokia()
{
- //TODO: possible mem leak -> m_reply->deleteLater() ?
+ abort();
}
void QGeoCodeReplyNokia::abort()
{
- if (!m_reply)
+ if (!m_reply && !m_parsing)
return;
m_reply->abort();
m_reply->deleteLater();
m_reply = 0;
+ m_parsing = false;
}
void QGeoCodeReplyNokia::networkFinished()
@@ -94,29 +92,17 @@ void QGeoCodeReplyNokia::networkFinished()
if (!m_reply)
return;
- if (m_reply->error() != QNetworkReply::NoError) {
- // Removed because this is already done in networkError, which previously caused _two_ errors to be raised for every error.
- //setError(QGeoCodeReply::CommunicationError, m_reply->errorString());
- //m_reply->deleteLater();
- //m_reply = 0;
+ if (m_reply->error() != QNetworkReply::NoError)
return;
- }
-
- QGeoCodeXmlParser parser;
- if (parser.parse(m_reply)) {
- QList<QGeoLocation> locations = parser.results();
- QGeoShape bounds = viewport();
- if (bounds.isValid()) {
- for (int i = locations.size() - 1; i >= 0; --i) {
- if (!bounds.contains(locations[i].coordinate()))
- locations.removeAt(i);
- }
- }
- setLocations(locations);
- setFinished(true);
- } else {
- setError(QGeoCodeReply::ParseError, parser.errorString());
- }
+
+ QGeoCodeXmlParser *parser = new QGeoCodeXmlParser;
+ parser->setBounds(viewport());
+ connect(parser, SIGNAL(results(QList<QGeoLocation>)),
+ this, SLOT(appendResults(QList<QGeoLocation>)));
+ connect(parser, SIGNAL(error(QString)), this, SLOT(parseError(QString)));
+
+ m_parsing = true;
+ parser->parse(m_reply->readAll());
m_reply->deleteLater();
m_reply = 0;
@@ -135,4 +121,23 @@ void QGeoCodeReplyNokia::networkError(QNetworkReply::NetworkError error)
m_reply = 0;
}
+void QGeoCodeReplyNokia::appendResults(const QList<QGeoLocation> &locations)
+{
+ if (!m_parsing)
+ return;
+
+ m_parsing = false;
+ setLocations(locations);
+ setFinished(true);
+}
+
+void QGeoCodeReplyNokia::parseError(const QString &errorString)
+{
+ Q_UNUSED(errorString)
+
+ setError(QGeoCodeReply::ParseError,
+ tr("The response from the service was not in a recognisable format."));
+ abort();
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/nokia/qgeocodereply_nokia.h b/src/plugins/geoservices/nokia/qgeocodereply_nokia.h
index 6b72cd40..af3f4dec 100644
--- a/src/plugins/geoservices/nokia/qgeocodereply_nokia.h
+++ b/src/plugins/geoservices/nokia/qgeocodereply_nokia.h
@@ -66,9 +66,12 @@ public:
private Q_SLOTS:
void networkFinished();
void networkError(QNetworkReply::NetworkError error);
+ void appendResults(const QList<QGeoLocation> &locations);
+ void parseError(const QString &errorString);
private:
QNetworkReply *m_reply;
+ bool m_parsing;
};
QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/nokia/qgeocodexmlparser.cpp b/src/plugins/geoservices/nokia/qgeocodexmlparser.cpp
index b9dbd934..d19246ff 100644
--- a/src/plugins/geoservices/nokia/qgeocodexmlparser.cpp
+++ b/src/plugins/geoservices/nokia/qgeocodexmlparser.cpp
@@ -48,10 +48,9 @@
#include "qgeocodexmlparser.h"
-#include <QXmlStreamReader>
-#include <QIODevice>
-
-#include <qgeolocation.h>
+#include <QtCore/QXmlStreamReader>
+#include <QtCore/QThreadPool>
+#include <QtPositioning/QGeoLocation>
#include <QtPositioning/QGeoAddress>
#include <QtPositioning/QGeoCoordinate>
#include <QtPositioning/QGeoRectangle>
@@ -66,28 +65,28 @@ QGeoCodeXmlParser::~QGeoCodeXmlParser()
{
}
-bool QGeoCodeXmlParser::parse(QIODevice *source)
+void QGeoCodeXmlParser::setBounds(const QGeoShape &bounds)
{
- m_reader.reset(new QXmlStreamReader(source));
-
- if (!parseRootElement()) {
- m_errorString = m_reader->errorString();
- return false;
- }
-
- m_errorString = "";
-
- return true;
+ m_bounds = bounds;
}
-QList<QGeoLocation> QGeoCodeXmlParser::results() const
+void QGeoCodeXmlParser::parse(const QByteArray &data)
{
- return m_results;
+ m_data = data;
+ QThreadPool::globalInstance()->start(this);
}
-QString QGeoCodeXmlParser::errorString() const
+void QGeoCodeXmlParser::run()
{
- return m_errorString;
+ m_reader = new QXmlStreamReader(m_data);
+
+ if (!parseRootElement())
+ emit error(m_reader->errorString());
+ else
+ emit results(m_results);
+
+ delete m_reader;
+ m_reader = 0;
}
bool QGeoCodeXmlParser::parseRootElement()
@@ -137,7 +136,8 @@ bool QGeoCodeXmlParser::parseRootElement()
if (!parsePlace(&location))
return false;
- m_results.append(location);
+ if (!m_bounds.isValid() || m_bounds.contains(location.coordinate()))
+ m_results.append(location);
} else {
m_reader->raiseError(QString("The element \"places\" did not expect a child element named \"%1\".").arg(m_reader->name().toString()));
return false;
diff --git a/src/plugins/geoservices/nokia/qgeocodexmlparser.h b/src/plugins/geoservices/nokia/qgeocodexmlparser.h
index 8eeb6cc3..67c9da9e 100644
--- a/src/plugins/geoservices/nokia/qgeocodexmlparser.h
+++ b/src/plugins/geoservices/nokia/qgeocodexmlparser.h
@@ -49,29 +49,35 @@
#ifndef QGEOCODEXMLPARSER_H
#define QGEOCODEXMLPARSER_H
-#include <QString>
-#include <QList>
-#include <QScopedPointer>
+#include <QtCore/QObject>
+#include <QtCore/QRunnable>
+#include <QtCore/QString>
+#include <QtCore/QList>
+#include <QtPositioning/QGeoShape>
QT_BEGIN_NAMESPACE
-class QIODevice;
class QGeoLocation;
class QGeoAddress;
class QGeoRectangle;
class QGeoCoordinate;
class QXmlStreamReader;
-class QGeoCodeXmlParser
+class QGeoCodeXmlParser : public QObject, public QRunnable
{
+ Q_OBJECT
+
public:
QGeoCodeXmlParser();
~QGeoCodeXmlParser();
- bool parse(QIODevice *source);
+ void setBounds(const QGeoShape &bounds);
+ void parse(const QByteArray &data);
+ void run();
- QList<QGeoLocation> results() const;
- QString errorString() const;
+signals:
+ void results(const QList<QGeoLocation> &locations);
+ void error(const QString &errorString);
private:
bool parseRootElement();
@@ -81,7 +87,9 @@ private:
bool parseBoundingBox(QGeoRectangle *bounds);
bool parseCoordinate(QGeoCoordinate *coordinate, const QString &elementName);
- QScopedPointer<QXmlStreamReader> m_reader;
+ QGeoShape m_bounds;
+ QByteArray m_data;
+ QXmlStreamReader *m_reader;
QList<QGeoLocation> m_results;
QString m_errorString;