#include "httpglobal.h"
+namespace stefanfrings {
+
/**
This object represents a single HTTP request. It reads the request
from a TCP socket and provides getters for the individual parts
@@ -46,7 +48,7 @@ public:
Constructor.
@param settings Configuration settings
*/
- HttpRequest(QSettings* settings);
+ HttpRequest(const QSettings* settings);
/**
Destructor.
@@ -59,7 +61,7 @@ public:
until the status is RequestStatus::complete or RequestStatus::abort.
@param socket Source of the data
*/
- void readFromSocket(QTcpSocket* socket);
+ void readFromSocket(QTcpSocket *socket);
/**
Get the status of this reqeust.
@@ -207,9 +209,9 @@ private:
QByteArray boundary;
/** Temp file, that is used to store the multipart/form-data body */
- QTemporaryFile tempFile;
+ QTemporaryFile* tempFile;
- /** Parset he multipart body, that has been stored in the temp file. */
+ /** Parse the multipart body, that has been stored in the temp file. */
void parseMultiPartFile();
/** Sub-procedure of readFromSocket(), read the first line of a request. */
@@ -232,4 +234,6 @@ private:
};
+} // end of namespace
+
#endif // HTTPREQUEST_H
diff --git a/third_party/QtWebApp/httpserver/httprequesthandler.cpp b/third_party/QtWebApp/httpserver/httprequesthandler.cpp
index 879ccd4f..f3a5fbe7 100644
--- a/third_party/QtWebApp/httpserver/httprequesthandler.cpp
+++ b/third_party/QtWebApp/httpserver/httprequesthandler.cpp
@@ -5,6 +5,8 @@
#include "httprequesthandler.h"
+using namespace stefanfrings;
+
HttpRequestHandler::HttpRequestHandler(QObject* parent)
: QObject(parent)
{}
diff --git a/third_party/QtWebApp/httpserver/httprequesthandler.h b/third_party/QtWebApp/httpserver/httprequesthandler.h
index 913cc3ca..ea24612a 100644
--- a/third_party/QtWebApp/httpserver/httprequesthandler.h
+++ b/third_party/QtWebApp/httpserver/httprequesthandler.h
@@ -10,6 +10,8 @@
#include "httprequest.h"
#include "httpresponse.h"
+namespace stefanfrings {
+
/**
The request handler generates a response for each HTTP request. Web Applications
usually have one central request handler that maps incoming requests to several
@@ -46,4 +48,6 @@ public:
};
+} // end of namespace
+
#endif // HTTPREQUESTHANDLER_H
diff --git a/third_party/QtWebApp/httpserver/httpresponse.cpp b/third_party/QtWebApp/httpserver/httpresponse.cpp
index 7dbb600a..a2afba89 100644
--- a/third_party/QtWebApp/httpserver/httpresponse.cpp
+++ b/third_party/QtWebApp/httpserver/httpresponse.cpp
@@ -5,7 +5,9 @@
#include "httpresponse.h"
-HttpResponse::HttpResponse(QTcpSocket* socket)
+using namespace stefanfrings;
+
+HttpResponse::HttpResponse(QTcpSocket *socket)
{
this->socket=socket;
statusCode=200;
@@ -67,6 +69,7 @@ void HttpResponse::writeHeaders()
}
buffer.append("\r\n");
writeToSocket(buffer);
+ socket->flush();
sentHeaders=true;
}
@@ -82,7 +85,7 @@ bool HttpResponse::writeToSocket(QByteArray data)
socket->waitForBytesWritten(-1);
}
- int written=socket->write(ptr,remaining);
+ qint64 written=socket->write(ptr,remaining);
if (written==-1)
{
return false;
diff --git a/third_party/QtWebApp/httpserver/httpresponse.h b/third_party/QtWebApp/httpserver/httpresponse.h
index 44054806..62050d02 100644
--- a/third_party/QtWebApp/httpserver/httpresponse.h
+++ b/third_party/QtWebApp/httpserver/httpresponse.h
@@ -12,6 +12,8 @@
#include "httpglobal.h"
#include "httpcookie.h"
+namespace stefanfrings {
+
/**
This object represents a HTTP response, used to return something to the web client.
@@ -39,7 +41,7 @@ public:
Constructor.
@param socket used to write the response
*/
- HttpResponse(QTcpSocket* socket);
+ HttpResponse(QTcpSocket *socket);
/**
Set a HTTP response header.
@@ -47,7 +49,7 @@ public:
@param name name of the header
@param value value of the header
*/
- void setHeader(QByteArray name, QByteArray value);
+ void setHeader(const QByteArray name, const QByteArray value);
/**
Set a HTTP response header.
@@ -55,7 +57,7 @@ public:
@param name name of the header
@param value value of the header
*/
- void setHeader(QByteArray name, int value);
+ void setHeader(const QByteArray name, const int value);
/** Get the map of HTTP response headers */
QMap& getHeaders();
@@ -67,7 +69,7 @@ public:
Set status code and description. The default is 200,OK.
You must call this method before the first write().
*/
- void setStatus(int statusCode, QByteArray description=QByteArray());
+ void setStatus(const int statusCode, const QByteArray description=QByteArray());
/** Return the status code. */
int getStatusCode() const;
@@ -85,7 +87,7 @@ public:
@param data Data bytes of the body
@param lastPart Indicates that this is the last chunk of data and flushes the output buffer.
*/
- void write(QByteArray data, bool lastPart=false);
+ void write(const QByteArray data, const bool lastPart=false);
/**
Indicates whether the body has been sent completely (write() has been called with lastPart=true).
@@ -156,4 +158,6 @@ private:
};
+} // end of namespace
+
#endif // HTTPRESPONSE_H
diff --git a/third_party/QtWebApp/httpserver/httpsession.cpp b/third_party/QtWebApp/httpserver/httpsession.cpp
index b3977730..4337082b 100644
--- a/third_party/QtWebApp/httpserver/httpsession.cpp
+++ b/third_party/QtWebApp/httpserver/httpsession.cpp
@@ -7,6 +7,7 @@
#include
#include
+using namespace stefanfrings;
HttpSession::HttpSession(bool canStore)
{
@@ -17,7 +18,7 @@ HttpSession::HttpSession(bool canStore)
dataPtr->lastAccess=QDateTime::currentMSecsSinceEpoch();
dataPtr->id=QUuid::createUuid().toString().toLocal8Bit();
#ifdef SUPERVERBOSE
- qDebug("HttpSession: created new session data with id %s",dataPtr->id.data());
+ qDebug("HttpSession: (constructor) new session %s with refCount=1",dataPtr->id.constData());
#endif
}
else
@@ -34,7 +35,7 @@ HttpSession::HttpSession(const HttpSession& other)
dataPtr->lock.lockForWrite();
dataPtr->refCount++;
#ifdef SUPERVERBOSE
- qDebug("HttpSession: refCount of %s is %i",dataPtr->id.data(),dataPtr->refCount);
+ qDebug("HttpSession: (constructor) copy session %s refCount=%i",dataPtr->id.constData(),dataPtr->refCount);
#endif
dataPtr->lock.unlock();
}
@@ -49,7 +50,7 @@ HttpSession& HttpSession::operator= (const HttpSession& other)
dataPtr->lock.lockForWrite();
dataPtr->refCount++;
#ifdef SUPERVERBOSE
- qDebug("HttpSession: refCount of %s is %i",dataPtr->id.data(),dataPtr->refCount);
+ qDebug("HttpSession: (operator=) session %s refCount=%i",dataPtr->id.constData(),dataPtr->refCount);
#endif
dataPtr->lastAccess=QDateTime::currentMSecsSinceEpoch();
dataPtr->lock.unlock();
@@ -57,14 +58,15 @@ HttpSession& HttpSession::operator= (const HttpSession& other)
if (oldPtr)
{
int refCount;
- oldPtr->lock.lockForRead();
- refCount=oldPtr->refCount--;
+ oldPtr->lock.lockForWrite();
+ refCount=--oldPtr->refCount;
#ifdef SUPERVERBOSE
- qDebug("HttpSession: refCount of %s is %i",oldPtr->id.data(),oldPtr->refCount);
+ qDebug("HttpSession: (operator=) session %s refCount=%i",oldPtr->id.constData(),oldPtr->refCount);
#endif
oldPtr->lock.unlock();
if (refCount==0)
{
+ qDebug("HttpSession: deleting old data");
delete oldPtr;
}
}
@@ -75,10 +77,10 @@ HttpSession::~HttpSession()
{
if (dataPtr) {
int refCount;
- dataPtr->lock.lockForRead();
+ dataPtr->lock.lockForWrite();
refCount=--dataPtr->refCount;
#ifdef SUPERVERBOSE
- qDebug("HttpSession: refCount of %s is %i",dataPtr->id.data(),dataPtr->refCount);
+ qDebug("HttpSession: (destructor) session %s refCount=%i",dataPtr->id.constData(),dataPtr->refCount);
#endif
dataPtr->lock.unlock();
if (refCount==0)
@@ -179,7 +181,7 @@ void HttpSession::setLastAccess()
{
if (dataPtr)
{
- dataPtr->lock.lockForRead();
+ dataPtr->lock.lockForWrite();
dataPtr->lastAccess=QDateTime::currentMSecsSinceEpoch();
dataPtr->lock.unlock();
}
diff --git a/third_party/QtWebApp/httpserver/httpsession.h b/third_party/QtWebApp/httpserver/httpsession.h
index 2ddb9b94..35ed1f26 100644
--- a/third_party/QtWebApp/httpserver/httpsession.h
+++ b/third_party/QtWebApp/httpserver/httpsession.h
@@ -11,6 +11,8 @@
#include
#include "httpglobal.h"
+namespace stefanfrings {
+
/**
This class stores data for a single HTTP session.
A session can store any number of key/value pairs. This class uses implicit
@@ -27,7 +29,7 @@ public:
@param canStore The session can store data, if this parameter is true.
Otherwise all calls to set() and remove() do not have any effect.
*/
- HttpSession(bool canStore=false);
+ HttpSession(const bool canStore=false);
/**
Copy constructor. Creates another HttpSession object that shares the
@@ -115,4 +117,6 @@ private:
};
+} // end of namespace
+
#endif // HTTPSESSION_H
diff --git a/third_party/QtWebApp/httpserver/httpsessionstore.cpp b/third_party/QtWebApp/httpserver/httpsessionstore.cpp
index 04f9cd04..6703f753 100644
--- a/third_party/QtWebApp/httpserver/httpsessionstore.cpp
+++ b/third_party/QtWebApp/httpserver/httpsessionstore.cpp
@@ -7,7 +7,9 @@
#include
#include
-HttpSessionStore::HttpSessionStore(QSettings* settings, QObject* parent)
+using namespace stefanfrings;
+
+HttpSessionStore::HttpSessionStore(const QSettings *settings, QObject* parent)
:QObject(parent)
{
this->settings=settings;
diff --git a/third_party/QtWebApp/httpserver/httpsessionstore.h b/third_party/QtWebApp/httpserver/httpsessionstore.h
index f3e11ae5..de86ecd2 100644
--- a/third_party/QtWebApp/httpserver/httpsessionstore.h
+++ b/third_party/QtWebApp/httpserver/httpsessionstore.h
@@ -15,6 +15,8 @@
#include "httpresponse.h"
#include "httprequest.h"
+namespace stefanfrings {
+
/**
Stores HTTP sessions and deletes them when they have expired.
The following configuration settings are required in the config file:
@@ -35,8 +37,17 @@ class DECLSPEC HttpSessionStore : public QObject {
Q_DISABLE_COPY(HttpSessionStore)
public:
- /** Constructor. */
- HttpSessionStore(QSettings* settings, QObject* parent=nullptr);
+ /**
+ Constructor.
+ @param settings Configuration settings, usually stored in an INI file. Must not be 0.
+ Settings are read from the current group, so the caller must have called settings->beginGroup().
+ Because the group must not change during runtime, it is recommended to provide a
+ separate QSettings instance that is not used by other parts of the program.
+ The HttpSessionStore does not take over ownership of the QSettings instance, so the
+ caller should destroy it during shutdown.
+ @param parent Parent object
+ */
+ HttpSessionStore(const QSettings* settings, QObject* parent=nullptr);
/** Destructor */
virtual ~HttpSessionStore();
@@ -62,7 +73,7 @@ public:
@return If autoCreate is disabled, the function returns a null session if there is no session.
@see HttpSession::isNull()
*/
- HttpSession getSession(HttpRequest& request, HttpResponse& response, bool allowCreate=true);
+ HttpSession getSession(HttpRequest& request, HttpResponse& response, const bool allowCreate=true);
/**
Get a HTTP session by it's ID number.
@@ -74,7 +85,7 @@ public:
HttpSession getSession(const QByteArray id);
/** Delete a session */
- void removeSession(HttpSession session);
+ void removeSession(const HttpSession session);
protected:
/** Storage for the sessions */
@@ -83,7 +94,7 @@ protected:
private:
/** Configuration settings */
- QSettings* settings;
+ const QSettings* settings;
/** Timer to remove expired sessions */
QTimer cleanupTimer;
@@ -103,4 +114,6 @@ private slots:
void sessionTimerEvent();
};
+} // end of namespace
+
#endif // HTTPSESSIONSTORE_H
diff --git a/third_party/QtWebApp/httpserver/staticfilecontroller.cpp b/third_party/QtWebApp/httpserver/staticfilecontroller.cpp
index 679f5bae..9510aec9 100644
--- a/third_party/QtWebApp/httpserver/staticfilecontroller.cpp
+++ b/third_party/QtWebApp/httpserver/staticfilecontroller.cpp
@@ -8,13 +8,9 @@
#include
#include
-//YACReader-----
-#include "httpsession.h"
-#include "yacreader_http_session.h"
-#include "static.h"
-//--
+using namespace stefanfrings;
-StaticFileController::StaticFileController(QSettings* settings, QObject* parent)
+StaticFileController::StaticFileController(const QSettings *settings, QObject* parent)
:HttpRequestHandler(parent)
{
maxAge=settings->value("maxAge","60000").toInt();
@@ -41,7 +37,7 @@ StaticFileController::StaticFileController(QSettings* settings, QObject* parent)
}
-void StaticFileController::service(HttpRequest& request, HttpResponse& response)
+void StaticFileController::service(HttpRequest &request, HttpResponse &response)
{
QByteArray path=request.getPath();
// Check if we have the file in cache
@@ -61,32 +57,6 @@ void StaticFileController::service(HttpRequest& request, HttpResponse& response)
else
{
mutex.unlock();
-
- //TODO(DONE) carga sensible al dispositivo y a la localización
- QString stringPath = path;
- QStringList paths = QString(path).split('/');
- QString fileName = paths.last();
- stringPath.remove(fileName);
- HttpSession session=Static::sessionStore->getSession(request,response,false);
- YACReaderHttpSession *ySession = Static::yacreaderSessionStore->getYACReaderSessionHttpSession(session.getId());
- QString device = "ipad";
- QString display = "@2x";
- if (ySession != nullptr) {
- device = ySession->getDeviceType();
- display = ySession->getDisplayType();
- }
-
- if(fileName.endsWith(".png"))
- fileName = getDeviceAwareFileName(fileName, device, display, request.getHeader("Accept-Language"), stringPath);
- else
- fileName = getDeviceAwareFileName(fileName, device, request.getHeader("Accept-Language"), stringPath);
- QString newPath = stringPath.append(fileName);
- path = newPath.toLocal8Bit();
-
- //CAMBIADO
- //response.setHeader("Connection","close");
- //END_TODO
-
// The file is not in cache.
qDebug("StaticFileController: Cache miss for %s",path.data());
// Forbid access to files outside the docroot directory
@@ -151,7 +121,7 @@ void StaticFileController::service(HttpRequest& request, HttpResponse& response)
}
}
-void StaticFileController::setContentType(QString fileName, HttpResponse& response) const
+void StaticFileController::setContentType(const QString fileName, HttpResponse &response) const
{
if (fileName.endsWith(".png"))
{
@@ -209,85 +179,17 @@ void StaticFileController::setContentType(QString fileName, HttpResponse& respon
{
response.setHeader("Content-Type", "application/font-otf");
}
+ else if (fileName.endsWith(".json"))
+ {
+ response.setHeader("Content-Type", "application/json");
+ }
+ else if (fileName.endsWith(".xml"))
+ {
+ response.setHeader("Content-Type", "text/xml");
+ }
// Todo: add all of your content types
else
{
qDebug("StaticFileController: unknown MIME type for filename '%s'", qPrintable(fileName));
}
}
-
-//YACReader------------------------------------------------------------------------
-
-bool StaticFileController::exists(QString localizedName, QString path) const
-{
- QString fileName=docroot+"/"+path + localizedName;
- QFile file(fileName);
- return file.exists();
-}
-
-//retorna fileName si no se encontró alternativa traducida ó fileName-locale.extensión si se encontró
-QString StaticFileController::getLocalizedFileName(QString fileName, QString locales, QString path) const
-{
- QSet tried; // used to suppress duplicate attempts
- QStringList locs=locales.split(',',QString::SkipEmptyParts);
- QStringList fileNameParts = fileName.split('.');
- QString file = fileNameParts.first();
- QString extension = fileNameParts.last();
- // Search for exact match
- foreach (QString loc,locs) {
- loc.replace(QRegExp(";.*"),"");
- loc.replace('-','_');
- QString localizedName=file+"-"+loc.trimmed()+"."+extension;
- if (!tried.contains(localizedName)) {
- if(exists(localizedName, path))
- return localizedName;
- tried.insert(localizedName);
- }
- }
-
- // Search for correct language but any country
- foreach (QString loc,locs) {
- loc.replace(QRegExp("[;_-].*"),"");
- QString localizedName=file+"-"+loc.trimmed()+"."+extension;
- if (!tried.contains(localizedName)) {
- if(exists(localizedName, path))
- return localizedName;
- tried.insert(localizedName);
- }
- }
-
- return fileName;
-}
-
-QString StaticFileController::getDeviceAwareFileName(QString fileName, QString device, QString locales, QString path) const
-{
- QFileInfo fi(fileName);
- QString baseName = fi.baseName();
- QString extension = fi.completeSuffix();
-
- QString completeFileName = getLocalizedFileName(baseName+"_"+device+"."+extension,locales,path);
-
- if(QFile(docroot+"/"+path+completeFileName).exists())
- return completeFileName; //existe un archivo específico para este dispositivo y locales
- else
- return getLocalizedFileName(fileName,locales,path); //no hay archivo específico para el dispositivo, pero puede haberlo para estas locales
-}
-
-QString StaticFileController::getDeviceAwareFileName(QString fileName, QString device, QString display, QString /* locales */, QString path) const
-{
- QFileInfo fi(fileName);
- QString baseName = fi.baseName();
- QString extension = fi.completeSuffix();
-
- QString completeFileName = baseName+display+"."+extension;
- if(QFile(docroot+"/"+path+completeFileName).exists())
- return completeFileName;
- else
- {
- completeFileName = baseName+"_"+device+display+"."+extension;
- if((QFile(docroot+"/"+path+completeFileName).exists()))
- return completeFileName;
- }
-
- return fileName;
-}
diff --git a/third_party/QtWebApp/httpserver/staticfilecontroller.h b/third_party/QtWebApp/httpserver/staticfilecontroller.h
index bda713d8..8e61a9e0 100644
--- a/third_party/QtWebApp/httpserver/staticfilecontroller.h
+++ b/third_party/QtWebApp/httpserver/staticfilecontroller.h
@@ -13,6 +13,8 @@
#include "httpresponse.h"
#include "httprequesthandler.h"
+namespace stefanfrings {
+
/**
Delivers static files. It is usually called by the applications main request handler when
the caller requests a path that is mapped to static files.
@@ -45,11 +47,20 @@ class DECLSPEC StaticFileController : public HttpRequestHandler {
Q_DISABLE_COPY(StaticFileController)
public:
- /** Constructor */
- StaticFileController(QSettings* settings, QObject* parent = nullptr);
+ /**
+ Constructor.
+ @param settings Configuration settings, usually stored in an INI file. Must not be 0.
+ Settings are read from the current group, so the caller must have called settings->beginGroup().
+ Because the group must not change during runtime, it is recommended to provide a
+ separate QSettings instance that is not used by other parts of the program.
+ The StaticFileController does not take over ownership of the QSettings instance, so the
+ caller should destroy it during shutdown.
+ @param parent Parent object
+ */
+ StaticFileController(const QSettings* settings, QObject* parent = nullptr);
/** Generates the response */
- void service(HttpRequest& request, HttpResponse& response) override;
+ void service(HttpRequest& request, HttpResponse& response);
private:
@@ -81,14 +92,9 @@ private:
QMutex mutex;
/** Set a content-type header in the response depending on the ending of the filename */
- void setContentType(QString file, HttpResponse& response) const;
-
- //YACReader------------------------------------------------------------------------
- QString getLocalizedFileName(QString fileName, QString locales, QString path) const;
- QString getDeviceAwareFileName(QString fileName, QString device, QString locales, QString path) const;
- QString getDeviceAwareFileName(QString fileName, QString device, QString display, QString locales, QString path) const;
-
- bool exists(QString localizedName, QString path) const;
+ void setContentType(const QString file, HttpResponse &response) const;
};
+} // end of namespace
+
#endif // STATICFILECONTROLLER_H
diff --git a/third_party/QtWebApp/templateengine/template.cpp b/third_party/QtWebApp/templateengine/template.cpp
index 37941c99..a150dd80 100644
--- a/third_party/QtWebApp/templateengine/template.cpp
+++ b/third_party/QtWebApp/templateengine/template.cpp
@@ -6,14 +6,16 @@
#include "template.h"
#include
-Template::Template(QString source, QString sourceName)
+using namespace stefanfrings;
+
+Template::Template(const QString source, const QString sourceName)
: QString(source)
{
this->sourceName=sourceName;
this->warnings=false;
}
-Template::Template(QFile& file, QTextCodec* textCodec)
+Template::Template(QFile& file, const QTextCodec* textCodec)
{
this->warnings=false;
sourceName=QFileInfo(file.fileName()).baseName();
@@ -34,7 +36,7 @@ Template::Template(QFile& file, QTextCodec* textCodec)
}
-int Template::setVariable(QString name, QString value)
+int Template::setVariable(const QString name, const QString value)
{
int count=0;
QString variable="{"+name+"}";
@@ -52,7 +54,7 @@ int Template::setVariable(QString name, QString value)
return count;
}
-int Template::setCondition(QString name, bool value)
+int Template::setCondition(const QString name, const bool value)
{
int count=0;
QString startTag=QString("{if %1}").arg(name);
@@ -150,7 +152,7 @@ int Template::setCondition(QString name, bool value)
return count;
}
-int Template::loop(QString name, int repetitions)
+int Template::loop(const QString name, const int repetitions)
{
Q_ASSERT(repetitions>=0);
int count=0;
@@ -234,7 +236,7 @@ int Template::loop(QString name, int repetitions)
return count;
}
-void Template::enableWarnings(bool enable)
+void Template::enableWarnings(const bool enable)
{
warnings=enable;
}
diff --git a/third_party/QtWebApp/templateengine/template.h b/third_party/QtWebApp/templateengine/template.h
index d2782d9c..01716c53 100644
--- a/third_party/QtWebApp/templateengine/template.h
+++ b/third_party/QtWebApp/templateengine/template.h
@@ -14,6 +14,8 @@
#include
#include "templateglobal.h"
+namespace stefanfrings {
+
/**
Enhanced version of QString for template processing. Templates
are usually loaded from files, but may also be loaded from
@@ -41,10 +43,10 @@
t.setVariable("username", "Stefan");
t.setCondition("locked",false);
t.loop("user",2);
- t.setVariable("user0.name,"Markus");
- t.setVariable("user0.time,"8:30");
- t.setVariable("user1.name,"Roland");
- t.setVariable("user1.time,"8:45");
+ t.setVariable("user0.name","Markus");
+ t.setVariable("user0.time","8:30");
+ t.setVariable("user1.name","Roland");
+ t.setVariable("user1.time","8:45");
The code example above shows how variable within loops are numbered.
@@ -95,7 +97,7 @@ public:
@param source The template source text
@param sourceName Name of the source file, used for logging
*/
- Template(QString source, QString sourceName);
+ Template(const QString source, const QString sourceName);
/**
Constructor that reads the template from a file. Note that this class does not
@@ -106,7 +108,7 @@ public:
@see TemplateLoader
@see TemplateCache
*/
- Template(QFile& file, QTextCodec* textCodec);
+ Template(QFile &file, const QTextCodec* textCodec);
/**
Replace a variable by the given value.
@@ -121,7 +123,7 @@ public:
@param value new value
@return The count of variables that have been processed
*/
- int setVariable(QString name, QString value);
+ int setVariable(const QString name, const QString value);
/**
Set a condition. This affects tags with the syntax
@@ -135,7 +137,7 @@ public:
@param value Value of the condition
@return The count of conditions that have been processed
*/
- int setCondition(QString name, bool value);
+ int setCondition(const QString name, bool value);
/**
Set number of repetitions of a loop.
@@ -148,13 +150,13 @@ public:
@param repetitions The number of repetitions
@return The number of loops that have been processed
*/
- int loop(QString name, int repetitions);
+ int loop(QString name, const int repetitions);
/**
Enable warnings for missing tags
@param enable Warnings are enabled, if true
*/
- void enableWarnings(bool enable=true);
+ void enableWarnings(const bool enable=true);
private:
@@ -165,4 +167,6 @@ private:
bool warnings;
};
+} // end of namespace
+
#endif // TEMPLATE_H
diff --git a/third_party/QtWebApp/templateengine/templatecache.cpp b/third_party/QtWebApp/templateengine/templatecache.cpp
index 06b1a0a7..e0f22bf5 100644
--- a/third_party/QtWebApp/templateengine/templatecache.cpp
+++ b/third_party/QtWebApp/templateengine/templatecache.cpp
@@ -3,7 +3,9 @@
#include
#include
-TemplateCache::TemplateCache(QSettings* settings, QObject* parent)
+using namespace stefanfrings;
+
+TemplateCache::TemplateCache(const QSettings* settings, QObject* parent)
:TemplateLoader(settings,parent)
{
cache.setMaxCost(settings->value("cacheSize","1000000").toInt());
@@ -11,14 +13,16 @@ TemplateCache::TemplateCache(QSettings* settings, QObject* parent)
qDebug("TemplateCache: timeout=%i, size=%i",cacheTimeout,cache.maxCost());
}
-QString TemplateCache::tryFile(QString localizedName)
+QString TemplateCache::tryFile(const QString localizedName)
{
qint64 now=QDateTime::currentMSecsSinceEpoch();
+ mutex.lock();
// search in cache
qDebug("TemplateCache: trying cached %s",qPrintable(localizedName));
CacheEntry* entry=cache.object(localizedName);
if (entry && (cacheTimeout==0 || entry->created>now-cacheTimeout))
{
+ mutex.unlock();
return entry->document;
}
// search on filesystem
@@ -27,6 +31,7 @@ QString TemplateCache::tryFile(QString localizedName)
entry->document=TemplateLoader::tryFile(localizedName);
// Store in cache even when the file did not exist, to remember that there is no such file
cache.insert(localizedName,entry,entry->document.size());
+ mutex.unlock();
return entry->document;
}
diff --git a/third_party/QtWebApp/templateengine/templatecache.h b/third_party/QtWebApp/templateengine/templatecache.h
index c9d95c1c..9251254b 100644
--- a/third_party/QtWebApp/templateengine/templatecache.h
+++ b/third_party/QtWebApp/templateengine/templatecache.h
@@ -5,6 +5,8 @@
#include "templateglobal.h"
#include "templateloader.h"
+namespace stefanfrings {
+
/**
Caching template loader, reduces the amount of I/O and improves performance
on remote file systems. The cache has a limited size, it prefers to keep
@@ -46,10 +48,15 @@ public:
/**
Constructor.
- @param settings configurations settings
+ @param settings Configuration settings, usually stored in an INI file. Must not be 0.
+ Settings are read from the current group, so the caller must have called settings->beginGroup().
+ Because the group must not change during runtime, it is recommended to provide a
+ separate QSettings instance that is not used by other parts of the program.
+ The TemplateCache does not take over ownership of the QSettings instance, so the caller
+ should destroy it during shutdown.
@param parent Parent object
*/
- TemplateCache(QSettings* settings, QObject* parent=nullptr);
+ TemplateCache(const QSettings* settings, QObject* parent=nullptr);
protected:
@@ -58,7 +65,7 @@ protected:
@param localizedName Name of the template with locale to find
@return The template document, or empty string if not found
*/
- virtual QString tryFile(QString localizedName);
+ virtual QString tryFile(const QString localizedName);
private:
@@ -73,6 +80,10 @@ private:
/** Cache storage */
QCache cache;
+ /** Used to synchronize threads */
+ QMutex mutex;
};
+} // end of namespace
+
#endif // TEMPLATECACHE_H
diff --git a/third_party/QtWebApp/templateengine/templateloader.cpp b/third_party/QtWebApp/templateengine/templateloader.cpp
index 91fdee02..2379755c 100644
--- a/third_party/QtWebApp/templateengine/templateloader.cpp
+++ b/third_party/QtWebApp/templateengine/templateloader.cpp
@@ -10,7 +10,9 @@
#include
#include
-TemplateLoader::TemplateLoader(QSettings* settings, QObject* parent)
+using namespace stefanfrings;
+
+TemplateLoader::TemplateLoader(const QSettings *settings, QObject *parent)
: QObject(parent)
{
templatePath=settings->value("path",".").toString();
@@ -64,7 +66,6 @@ QString TemplateLoader::tryFile(QString localizedName)
Template TemplateLoader::getTemplate(QString templateName, QString locales)
{
- mutex.lock();
QSet tried; // used to suppress duplicate attempts
QStringList locs=locales.split(',',QString::SkipEmptyParts);
@@ -78,7 +79,6 @@ Template TemplateLoader::getTemplate(QString templateName, QString locales)
{
QString document=tryFile(localizedName);
if (!document.isEmpty()) {
- mutex.unlock();
return Template(document,localizedName);
}
tried.insert(localizedName);
@@ -95,7 +95,6 @@ Template TemplateLoader::getTemplate(QString templateName, QString locales)
QString document=tryFile(localizedName);
if (!document.isEmpty())
{
- mutex.unlock();
return Template(document,localizedName);
}
tried.insert(localizedName);
@@ -106,11 +105,9 @@ Template TemplateLoader::getTemplate(QString templateName, QString locales)
QString document=tryFile(templateName);
if (!document.isEmpty())
{
- mutex.unlock();
return Template(document,templateName);
}
qCritical("TemplateCache: cannot find template %s",qPrintable(templateName));
- mutex.unlock();
return Template("",templateName);
}
diff --git a/third_party/QtWebApp/templateengine/templateloader.h b/third_party/QtWebApp/templateengine/templateloader.h
index 464ad1ea..dd41fa53 100644
--- a/third_party/QtWebApp/templateengine/templateloader.h
+++ b/third_party/QtWebApp/templateengine/templateloader.h
@@ -13,6 +13,8 @@
#include "templateglobal.h"
#include "template.h"
+namespace stefanfrings {
+
/**
Loads localized versions of template files. If the caller requests a file with the
name "index" and the suffix is ".tpl" and the requested locale is "de_DE, de, en-US",
@@ -20,7 +22,7 @@
- index-de_DE.tpl
- index-de.tpl
- - index-en_US.tpl
+ - index-en_US.tpl
- index-en.tpl
- index.tpl
@@ -45,7 +47,7 @@ public:
@param settings configurations settings
@param parent parent object
*/
- TemplateLoader(QSettings* settings, QObject* parent=nullptr);
+ TemplateLoader(const QSettings* settings, QObject* parent=nullptr);
/** Destructor */
virtual ~TemplateLoader();
@@ -59,7 +61,7 @@ public:
ignored.
@return If the template cannot be loaded, an error message is logged and an empty template is returned.
*/
- Template getTemplate(QString templateName, QString locales=QString());
+ Template getTemplate(const QString templateName, const QString locales=QString());
protected:
@@ -68,7 +70,7 @@ protected:
@param localizedName Name of the template with locale to find
@return The template document, or empty string if not found
*/
- virtual QString tryFile(QString localizedName);
+ virtual QString tryFile(const QString localizedName);
/** Directory where the templates are searched */
QString templatePath;
@@ -78,9 +80,8 @@ protected:
/** Codec for decoding the files */
QTextCodec* textCodec;
-
- /** Used to synchronize threads */
- QMutex mutex;
};
+} // end of namespace
+
#endif // TEMPLATELOADER_H