From 900456ca312acc789e7d3bbe22cf58bbbd79675f Mon Sep 17 00:00:00 2001 From: Leonardo Zide Date: Sat, 14 Apr 2018 11:44:39 -0700 Subject: [PATCH] Refactored http download code. --- common/lc_http.cpp | 92 ++++++++++++++++++++++++++++++++++++ common/lc_http.h | 72 ++++++++++++++++++++++++++++ leocad.pro | 10 ++-- qt/lc_qupdatedialog.cpp | 28 ++--------- qt/lc_qupdatedialog.h | 9 ++-- qt/lc_setsdatabasedialog.cpp | 91 ++++------------------------------- qt/lc_setsdatabasedialog.h | 57 ++-------------------- 7 files changed, 193 insertions(+), 166 deletions(-) create mode 100644 common/lc_http.cpp create mode 100644 common/lc_http.h diff --git a/common/lc_http.cpp b/common/lc_http.cpp new file mode 100644 index 00000000..4a7b9fe4 --- /dev/null +++ b/common/lc_http.cpp @@ -0,0 +1,92 @@ +#include "lc_global.h" +#include "lc_http.h" + +#ifdef Q_OS_WIN + +#include + +lcHttpReply::lcHttpReply(QObject* Parent, const QString& URL) + : QThread(Parent) +{ + mError = true; + mAbort = false; + mURL = URL; +} + +void lcHttpReply::run() +{ + HINTERNET Session = nullptr; + HINTERNET Request = nullptr; + + if (sizeof(wchar_t) != sizeof(QChar)) + return; + + Session = InternetOpen(L"LeoCAD", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); + if (!Session) + return; + + Request = InternetOpenUrl(Session, (WCHAR*)mURL.data(), NULL, 0, 0, 0); + if (!Request) + { + InternetCloseHandle(Session); + return; + } + + for (;;) + { + char Buffer[1024]; + DWORD BytesRead; + + if (mAbort) + break; + + if (!InternetReadFile(Request, Buffer, sizeof(Buffer), &BytesRead)) + break; + + if (BytesRead) + mBuffer.append(Buffer, BytesRead); + else + { + mError = false; + break; + } + + Sleep(0); + } + + InternetCloseHandle(Request); + InternetCloseHandle(Session); +} + +lcHttpManager::lcHttpManager(QObject* Owner) + : QObject(Owner) +{ +} + +lcHttpReply* lcHttpManager::DownloadFile(const QString& Url) +{ + lcHttpReply* Reply = new lcHttpReply(this, Url); + connect(Reply, &QThread::finished, [this, Reply] { emit DownloadFinished(Reply); }); + Reply->start(); + return Reply; +} + +#else + +lcHttpManager::lcHttpManager(QObject* Owner) + : QNetworkAccessManager(Owner) +{ + connect(this, SIGNAL(finished(QNetworkReply*)), this, SLOT(Finished(QNetworkReply*))); +} + +lcHttpReply* lcHttpManager::lcHttpManager::DownloadFile(const QString& Url) +{ + return mNetworkManager.get(QNetworkRequest(QUrl(Url))); +} + +void lcHttpManager::Finished(QNetworkReply* Reply) +{ + emit DownloadFinished(Reply); +} + +#endif diff --git a/common/lc_http.h b/common/lc_http.h new file mode 100644 index 00000000..985450a2 --- /dev/null +++ b/common/lc_http.h @@ -0,0 +1,72 @@ +#pragma once + +#include +#include + +#ifdef Q_OS_WIN + +class lcHttpReply : public QThread +{ + Q_OBJECT + +public: + lcHttpReply(QObject* Parent, const QString& URL); + + void run(); + + bool error() const + { + return mError; + } + + void abort() + { + mAbort = true; + } + + QByteArray readAll() const + { + return mBuffer; + } + +protected: + bool mError; + bool mAbort; + QByteArray mBuffer; + QString mURL; +}; + +class lcHttpManager : public QObject +{ + Q_OBJECT + +public: + lcHttpManager(QObject* Owner = nullptr); + + lcHttpReply* DownloadFile(const QString& Url); + +signals: + void DownloadFinished(lcHttpReply* Reply); +}; + +#else + +typedef QNetworkReply lcHttpReply; + +class lcHttpManager : public QNetworkAccessManager +{ + Q_OBJECT + +public: + lcHttpManager(QObject* Owner = nullptr); + + lcHttpReply* DownloadFile(const QString& Url); + +signals: + void DownloadFinished(lcHttpReply* Reply); + +protected slots: + void Finished(QNetworkReply* Reply); +}; + +#endif diff --git a/leocad.pro b/leocad.pro index 55dc12b1..d60bcdb0 100644 --- a/leocad.pro +++ b/leocad.pro @@ -139,8 +139,9 @@ SOURCES += common/view.cpp \ common/lc_context.cpp \ common/lc_file.cpp \ common/lc_glextensions.cpp \ + common/lc_http.cpp \ common/lc_library.cpp \ - common/lc_lxf.cpp \ + common/lc_lxf.cpp \ common/lc_mainwindow.cpp \ common/lc_mesh.cpp \ common/lc_model.cpp \ @@ -175,7 +176,7 @@ SOURCES += common/view.cpp \ qt/lc_qcolorlist.cpp \ qt/lc_qfinddialog.cpp \ qt/lc_qmodellistdialog.cpp \ - common/lc_partselectionwidget.cpp \ + common/lc_partselectionwidget.cpp \ common/lc_timelinewidget.cpp \ qt/lc_renderdialog.cpp \ qt/lc_setsdatabasedialog.cpp @@ -200,8 +201,9 @@ HEADERS += \ common/lc_glextensions.h \ common/lc_global.h \ common/lc_glwidget.h \ + common/lc_http.h \ common/lc_library.h \ - common/lc_lxf.h \ + common/lc_lxf.h \ common/lc_mainwindow.h \ common/lc_math.h \ common/lc_mesh.h \ @@ -235,7 +237,7 @@ HEADERS += \ qt/lc_qcolorlist.h \ qt/lc_qfinddialog.h \ qt/lc_qmodellistdialog.h \ - common/lc_partselectionwidget.h \ + common/lc_partselectionwidget.h \ common/lc_timelinewidget.h \ qt/lc_renderdialog.h \ qt/lc_setsdatabasedialog.h diff --git a/qt/lc_qupdatedialog.cpp b/qt/lc_qupdatedialog.cpp index 7dff3dda..7d749bb5 100644 --- a/qt/lc_qupdatedialog.cpp +++ b/qt/lc_qupdatedialog.cpp @@ -4,6 +4,7 @@ #include "lc_application.h" #include "lc_library.h" #include "lc_profile.h" +#include "lc_http.h" void lcDoInitialUpdateCheck() { @@ -39,23 +40,14 @@ lcQUpdateDialog::lcQUpdateDialog(QWidget* Parent, bool InitialUpdate) ui->status->setText(tr("Connecting to update server...")); - manager = new QNetworkAccessManager(this); - connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*))); + mHttpManager = new lcHttpManager(this); + connect(mHttpManager, SIGNAL(DownloadFinished(lcHttpReply*)), this, SLOT(DownloadFinished(lcHttpReply*))); - updateReply = manager->get(QNetworkRequest(QUrl("https://www.leocad.org/updates.txt"))); + mHttpManager->DownloadFile(QLatin1String("https://www.leocad.org/updates.txt")); } lcQUpdateDialog::~lcQUpdateDialog() { - if (updateReply) - { - updateReply->abort(); - updateReply->deleteLater(); - } - - if (manager) - manager->deleteLater(); - delete ui; } @@ -69,13 +61,6 @@ void lcQUpdateDialog::accept() void lcQUpdateDialog::reject() { - if (updateReply) - { - updateReply->abort(); - updateReply->deleteLater(); - updateReply = nullptr; - } - QDialog::reject(); } @@ -87,7 +72,7 @@ void lcQUpdateDialog::finished(int result) deleteLater(); } -void lcQUpdateDialog::replyFinished(QNetworkReply *reply) +void lcQUpdateDialog::DownloadFinished(lcHttpReply *reply) { bool updateAvailable = false; @@ -156,9 +141,6 @@ void lcQUpdateDialog::replyFinished(QNetworkReply *reply) #else settings.setValue("Updates/LastCheck", QDateTime::currentDateTime()); #endif - - updateReply = nullptr; - reply->deleteLater(); } else ui->status->setText(tr("Error connecting to the update server.")); diff --git a/qt/lc_qupdatedialog.h b/qt/lc_qupdatedialog.h index 3117bb85..8a495418 100644 --- a/qt/lc_qupdatedialog.h +++ b/qt/lc_qupdatedialog.h @@ -1,7 +1,9 @@ #pragma once #include -#include + +class lcHttpReply; +class lcHttpManager; namespace Ui { class lcQUpdateDialog; @@ -20,7 +22,7 @@ public: void parseUpdate(const char *update); public slots: - void replyFinished(QNetworkReply *reply); + void DownloadFinished(lcHttpReply* Reply); void accept(); void reject(); void finished(int result); @@ -28,8 +30,7 @@ public slots: private: Ui::lcQUpdateDialog *ui; - QNetworkReply *updateReply; - QNetworkAccessManager *manager; + lcHttpManager* mHttpManager; QByteArray versionData; bool mInitialUpdate; }; diff --git a/qt/lc_setsdatabasedialog.cpp b/qt/lc_setsdatabasedialog.cpp index 4d427882..43861629 100644 --- a/qt/lc_setsdatabasedialog.cpp +++ b/qt/lc_setsdatabasedialog.cpp @@ -1,63 +1,7 @@ #include "lc_global.h" #include "lc_setsdatabasedialog.h" #include "ui_lc_setsdatabasedialog.h" -#include -#include - -#ifdef Q_OS_WIN - -lcHttpReply::lcHttpReply(QObject* Parent, const QString& URL) - : QThread(Parent) -{ - mError = true; - mAbort = false; - mURL = URL; -} - -void lcHttpReply::run() -{ - HINTERNET Session = nullptr; - HINTERNET Request = nullptr; - - if (sizeof(wchar_t) != sizeof(QChar)) - return; - - Session = InternetOpen(L"LeoCAD", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); - if (!Session) - return; - - Request = InternetOpenUrl(Session, (WCHAR*)mURL.data(), NULL, 0, 0, 0); - if (!Request) - { - InternetCloseHandle(Session); - return; - } - - for (;;) - { - char Buffer[1024]; - DWORD BytesRead; - - if (mAbort) - break; - - if (!InternetReadFile(Request, Buffer, sizeof(Buffer), &BytesRead)) - break; - - if (BytesRead) - mBuffer.append(Buffer, BytesRead); - else - { - mError = false; - break; - } - } - - InternetCloseHandle(Request); - InternetCloseHandle(Session); -} - -#endif +#include "lc_http.h" lcSetsDatabaseDialog::lcSetsDatabaseDialog(QWidget* Parent) : QDialog(Parent), @@ -66,13 +10,13 @@ lcSetsDatabaseDialog::lcSetsDatabaseDialog(QWidget* Parent) ui->setupUi(this); ui->SearchEdit->installEventFilter(this); + mHttpManager = new lcHttpManager(this); + connect(ui->SetsTree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(accept())); connect(this, SIGNAL(finished(int)), this, SLOT(Finished(int))); -#ifndef Q_OS_WIN - connect(&mNetworkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(DownloadFinished(QNetworkReply*))); -#endif + connect(mHttpManager, SIGNAL(DownloadFinished(lcHttpReply*)), this, SLOT(DownloadFinished(lcHttpReply*))); - mKeyListReply = RequestURL("https://www.leocad.org/rebrickable.json"); + mKeyListReply = mHttpManager->DownloadFile(QLatin1String("https://www.leocad.org/rebrickable.json")); } lcSetsDatabaseDialog::~lcSetsDatabaseDialog() @@ -80,18 +24,6 @@ lcSetsDatabaseDialog::~lcSetsDatabaseDialog() delete ui; } -lcHttpReply* lcSetsDatabaseDialog::RequestURL(const QString& URL) -{ -#ifdef Q_OS_WIN - lcHttpReply* Reply = new lcHttpReply(this, URL); - connect(Reply, &QThread::finished, [this, Reply] { ProcessReply(Reply); }); - Reply->start(); - return Reply; -#else - return mNetworkManager.get(QNetworkRequest(QUrl(URL))); -#endif -} - QString lcSetsDatabaseDialog::GetSetName() const { QTreeWidgetItem* Current = ui->SetsTree->currentItem(); @@ -144,7 +76,7 @@ void lcSetsDatabaseDialog::accept() int KeyIndex = QTime::currentTime().msec() % mKeys.size(); QString DownloadUrl = QString("https://rebrickable.com/api/v3/lego/sets/%1/parts/?key=%2").arg(SetNum, mKeys[KeyIndex]); - mInventoryReply = RequestURL(DownloadUrl); + mInventoryReply = mHttpManager->DownloadFile(DownloadUrl); while (mInventoryReply) { @@ -205,7 +137,7 @@ void lcSetsDatabaseDialog::on_SearchButton_clicked() int KeyIndex = QTime::currentTime().msec() % mKeys.size(); QString SearchUrl = QString("https://rebrickable.com/api/v3/lego/sets/?search=%1&key=%2").arg(Keyword, mKeys[KeyIndex]); - mSearchReply = RequestURL(SearchUrl); + mSearchReply = mHttpManager->DownloadFile(SearchUrl); while (mSearchReply) { @@ -221,14 +153,7 @@ void lcSetsDatabaseDialog::on_SearchButton_clicked() } } -#ifndef Q_OS_WIN -void lcSetsDatabaseDialog::DownloadFinished(QNetworkReply* Reply) -{ - ProcessReply(Reply); -} -#endif - -void lcSetsDatabaseDialog::ProcessReply(lcHttpReply* Reply) +void lcSetsDatabaseDialog::DownloadFinished(lcHttpReply* Reply) { #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) if (Reply == mKeyListReply) diff --git a/qt/lc_setsdatabasedialog.h b/qt/lc_setsdatabasedialog.h index 726fb47f..4989d8e1 100644 --- a/qt/lc_setsdatabasedialog.h +++ b/qt/lc_setsdatabasedialog.h @@ -1,54 +1,14 @@ #pragma once #include -#include + +class lcHttpReply; +class lcHttpManager; namespace Ui { class lcSetsDatabaseDialog; } -#ifdef Q_OS_WIN - -#include - -class lcHttpReply : public QThread -{ - Q_OBJECT - -public: - lcHttpReply(QObject* Parent, const QString& URL); - - void run(); - - bool error() const - { - return mError; - } - - void abort() - { - mAbort = true; - } - - QByteArray readAll() const - { - return mBuffer; - } - -protected: - bool mError; - bool mAbort; - QByteArray mBuffer; - QString mURL; -}; - -#else - -typedef QNetworkReply lcHttpReply; - -#endif - - class lcSetsDatabaseDialog : public QDialog { Q_OBJECT @@ -68,20 +28,13 @@ public: virtual bool eventFilter(QObject* Object, QEvent* Event) override; public slots: -#ifndef Q_OS_WIN - void DownloadFinished(QNetworkReply* Reply); -#endif + void DownloadFinished(lcHttpReply* Reply); void on_SearchButton_clicked(); void accept() override; void Finished(int Result); protected: - lcHttpReply* RequestURL(const QString& URL); - void ProcessReply(lcHttpReply* Reply); - -#ifndef Q_OS_WIN - QNetworkAccessManager mNetworkManager; -#endif + lcHttpManager* mHttpManager; lcHttpReply* mKeyListReply; lcHttpReply* mSearchReply;