mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-20 04:41:36 +02:00
Move rtaudio, alsa-playback and qxt into thirdparty/.
This commit is contained in:
104
thirdparty/qxt/qxtweb-standalone/CMakeLists.txt
vendored
Normal file
104
thirdparty/qxt/qxtweb-standalone/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
PROJECT(libqxtweb-standalone)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
|
||||
SET(CMAKE_VERBOSE_MAKEFILE ON)
|
||||
SET(CMAKE_INSTALL_PREFIX ".")
|
||||
|
||||
FIND_PACKAGE( Qt4 4.6.0 COMPONENTS QtCore QtNetwork REQUIRED )
|
||||
set(QT_USE_QTNETWORK TRUE)
|
||||
include( ${QT_USE_FILE} )
|
||||
|
||||
SET(qxtweb "qxtweb")
|
||||
|
||||
ADD_DEFINITIONS(-Wall -O2 -DNDEBUG)
|
||||
IF(NOT WIN32)
|
||||
ADD_DEFINITIONS(-fPIC)
|
||||
ENDIF()
|
||||
ADD_DEFINITIONS( -DBUILD_QXT_CORE -DBUILD_QXT_WEB )
|
||||
|
||||
|
||||
INCLUDE_DIRECTORIES( ${qxtweb} )
|
||||
|
||||
|
||||
SET( sources
|
||||
# QxtWeb:
|
||||
${qxtweb}/qxtabstracthttpconnector.cpp
|
||||
${qxtweb}/qxtabstractwebservice.cpp
|
||||
${qxtweb}/qxtabstractwebsessionmanager.cpp
|
||||
${qxtweb}/qxthtmltemplate.cpp
|
||||
${qxtweb}/qxthttpserverconnector.cpp
|
||||
${qxtweb}/qxthttpsessionmanager.cpp
|
||||
${qxtweb}/qxtscgiserverconnector.cpp
|
||||
${qxtweb}/qxtwebcontent.cpp
|
||||
${qxtweb}/qxtwebevent.cpp
|
||||
${qxtweb}/qxtwebservicedirectory.cpp
|
||||
${qxtweb}/qxtwebslotservice.cpp
|
||||
${qxtweb}/qxtwebcgiservice.cpp
|
||||
|
||||
# Ripped bits of QxtCore:
|
||||
${qxtweb}/qxtmetaobject.cpp
|
||||
${qxtweb}/qxtnull.cpp
|
||||
)
|
||||
|
||||
SET( headers
|
||||
# QxtWeb:
|
||||
${qxtweb}/qxtabstracthttpconnector.h
|
||||
${qxtweb}/qxtabstractwebservice.h
|
||||
${qxtweb}/qxtabstractwebsessionmanager.h
|
||||
${qxtweb}/qxtabstractwebsessionmanager_p.h
|
||||
# ${qxtweb}/qxthtmltemplate.h
|
||||
${qxtweb}/qxthttpsessionmanager.h
|
||||
# ${qxtweb}/qxtweb.h
|
||||
${qxtweb}/qxtwebcontent.h
|
||||
# ${qxtweb}/qxtwebevent.h
|
||||
${qxtweb}/qxtwebservicedirectory.h
|
||||
${qxtweb}/qxtwebservicedirectory_p.h
|
||||
${qxtweb}/qxtwebslotservice.h
|
||||
${qxtweb}/qxtwebcgiservice.h
|
||||
${qxtweb}/qxtwebcgiservice_p.h
|
||||
|
||||
# Ripped bits of QxtCore:
|
||||
# ${qxtweb}/qxtmetaobject.h
|
||||
# ${qxtweb}/qxtnullable.h
|
||||
# ${qxtweb}/qxtnull.h
|
||||
${qxtweb}/qxtboundfunction.h
|
||||
# ${qxtweb}/qxtboundfunctionbase.h
|
||||
# ${qxtweb}/qxtboundcfunction.h
|
||||
# ${qxtweb}/qxtmetatype.h
|
||||
)
|
||||
|
||||
qt4_wrap_cpp( mocstuff ${headers} )
|
||||
|
||||
# DLL on windows due to linker issues, otherwise static
|
||||
IF(WIN32)
|
||||
ADD_LIBRARY(qxtweb-standalone SHARED
|
||||
${mocstuff}
|
||||
${headers}
|
||||
${sources}
|
||||
)
|
||||
ELSE()
|
||||
ADD_LIBRARY(qxtweb-standalone STATIC
|
||||
${mocstuff}
|
||||
${headers}
|
||||
${sources}
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
|
||||
target_link_libraries( qxtweb-standalone
|
||||
${QT_LIBRARIES}
|
||||
)
|
||||
|
||||
# Also build small example app from qxt demos:
|
||||
|
||||
#qt4_wrap_cpp( mocex "example/myservice.h" )
|
||||
|
||||
#ADD_EXECUTABLE( example-webserver
|
||||
# ${mocex}
|
||||
# example/main.cpp
|
||||
# example/myservice.h
|
||||
# )
|
||||
|
||||
#TARGET_LINK_LIBRARIES( example-webserver
|
||||
# ${QT_LIBRARIES}
|
||||
# "${CMAKE_CURRENT_SOURCE_DIR}/libqxtweb-standalone.a"
|
||||
# )
|
1
thirdparty/qxt/qxtweb-standalone/README.txt
vendored
Normal file
1
thirdparty/qxt/qxtweb-standalone/README.txt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
QxtWeb from libqxt.org project, standalone and cmakeified. For embeddable webserver
|
22
thirdparty/qxt/qxtweb-standalone/example/main.cpp
vendored
Normal file
22
thirdparty/qxt/qxtweb-standalone/example/main.cpp
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
#include <QCoreApplication>
|
||||
|
||||
#include "myservice.h"
|
||||
|
||||
|
||||
int main(int argc, char ** argv){
|
||||
|
||||
QCoreApplication app(argc,argv);
|
||||
|
||||
QxtHttpServerConnector connector;
|
||||
|
||||
QxtHttpSessionManager session;
|
||||
session.setPort(8080);
|
||||
session.setConnector(&connector);
|
||||
|
||||
MyService s1(&session);
|
||||
session.setStaticContentService ( &s1);
|
||||
|
||||
session.start();
|
||||
return app.exec();
|
||||
}
|
||||
|
23
thirdparty/qxt/qxtweb-standalone/example/myservice.h
vendored
Normal file
23
thirdparty/qxt/qxtweb-standalone/example/myservice.h
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef MYSERVICE
|
||||
#define MYSERVICE
|
||||
|
||||
#include <QxtHttpServerConnector>
|
||||
#include <QxtHttpSessionManager>
|
||||
#include <QxtWebSlotService>
|
||||
#include <QxtWebPageEvent>
|
||||
|
||||
|
||||
class MyService : public QxtWebSlotService{
|
||||
Q_OBJECT;
|
||||
public:
|
||||
MyService(QxtAbstractWebSessionManager * sm, QObject * parent = 0 ): QxtWebSlotService(sm,parent){
|
||||
}
|
||||
public slots:
|
||||
void index(QxtWebRequestEvent* event)
|
||||
{
|
||||
postEvent(new QxtWebPageEvent(event->sessionID, event->requestID, "<h1>It Works!</h1>"));
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
2
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtAbstractHttpConnector
vendored
Normal file
2
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtAbstractHttpConnector
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
#include "qxtabstracthttpconnector.h"
|
||||
|
2
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtAbstractWebService
vendored
Normal file
2
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtAbstractWebService
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
#include "qxtabstractwebservice.h"
|
||||
|
2
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtAbstractWebSessionManager
vendored
Normal file
2
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtAbstractWebSessionManager
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
#include "qxtabstractwebsessionmanager.h"
|
||||
|
2
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtHtmlTemplate
vendored
Normal file
2
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtHtmlTemplate
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
#include "qxthtmltemplate.h"
|
||||
|
1
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtHttpServerConnector
vendored
Normal file
1
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtHttpServerConnector
vendored
Normal file
@@ -0,0 +1 @@
|
||||
#include "qxtabstracthttpconnector.h"
|
2
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtHttpSessionManager
vendored
Normal file
2
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtHttpSessionManager
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
#include "qxthttpsessionmanager.h"
|
||||
|
2
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtMail
vendored
Normal file
2
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtMail
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
#include "qxtmail.h"
|
||||
|
1
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtScgiServerConnector
vendored
Normal file
1
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtScgiServerConnector
vendored
Normal file
@@ -0,0 +1 @@
|
||||
#include "qxtabstracthttpconnector.h"
|
2
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtSendmail
vendored
Normal file
2
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtSendmail
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
#include "qxtsendmail.h"
|
||||
|
1
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtWeb
vendored
Normal file
1
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtWeb
vendored
Normal file
@@ -0,0 +1 @@
|
||||
#include "qxtweb.h"
|
1
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtWebCgiService
vendored
Normal file
1
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtWebCgiService
vendored
Normal file
@@ -0,0 +1 @@
|
||||
#include "qxtwebcgiservice.h"
|
2
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtWebContent
vendored
Normal file
2
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtWebContent
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
#include "qxtwebcontent.h"
|
||||
|
2
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtWebErrorEvent
vendored
Normal file
2
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtWebErrorEvent
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
#include "qxtwebevent.h"
|
||||
|
2
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtWebEvent
vendored
Normal file
2
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtWebEvent
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
#include "qxtwebevent.h"
|
||||
|
1
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtWebFileUploadEvent
vendored
Normal file
1
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtWebFileUploadEvent
vendored
Normal file
@@ -0,0 +1 @@
|
||||
#include "qxtwebevent.h"
|
2
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtWebPageEvent
vendored
Normal file
2
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtWebPageEvent
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
#include "qxtwebevent.h"
|
||||
|
2
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtWebRedirectEvent
vendored
Normal file
2
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtWebRedirectEvent
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
#include "qxtwebevent.h"
|
||||
|
1
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtWebRemoveCookieEvent
vendored
Normal file
1
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtWebRemoveCookieEvent
vendored
Normal file
@@ -0,0 +1 @@
|
||||
#include "qxtwebevent.h"
|
2
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtWebRequestEvent
vendored
Normal file
2
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtWebRequestEvent
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
#include "qxtwebevent.h"
|
||||
|
2
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtWebServiceDirectory
vendored
Normal file
2
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtWebServiceDirectory
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
#include "qxtwebservicedirectory.h"
|
||||
|
2
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtWebSlotService
vendored
Normal file
2
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtWebSlotService
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
#include "qxtwebslotservice.h"
|
||||
|
1
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtWebStoreCookieEvent
vendored
Normal file
1
thirdparty/qxt/qxtweb-standalone/qxtweb/QxtWebStoreCookieEvent
vendored
Normal file
@@ -0,0 +1 @@
|
||||
#include "qxtwebevent.h"
|
249
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtabstracthttpconnector.cpp
vendored
Normal file
249
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtabstracthttpconnector.cpp
vendored
Normal file
@@ -0,0 +1,249 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtWeb module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\class QxtAbstractHttpConnector
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtAbstractHttpConnector class is a base class for defining
|
||||
HTTP-based protocols for use with QxtHttpSessionManager
|
||||
|
||||
QxtHttpSessionManager does the work of managing sessions and state for the
|
||||
otherwise stateless HTTP protocol, but it relies on QxtAbstractHttpConnector
|
||||
subclasses to implement the protocol used to communicate with the web server.
|
||||
|
||||
Subclasses are responsible for accepting new connections (by implementing
|
||||
listen(const QHostAddress&, quint16) and invoking addConnection(QIODevice*)),
|
||||
for informing the session manager when request headers are available (by
|
||||
implementing canParseRequest(const QByteArray&)), for parsing the request
|
||||
headers (by implementing parseRequest(QByteArray&)), and for writing response
|
||||
headers (by implementing writeHeaders(QIODevice*, const QHttpResponseHeader&)).
|
||||
|
||||
\sa QxtHttpSessionManager
|
||||
*/
|
||||
|
||||
#include "qxthttpsessionmanager.h"
|
||||
#include "qxtwebcontent.h"
|
||||
#include <QReadWriteLock>
|
||||
#include <QHash>
|
||||
#include <QIODevice>
|
||||
#include <QByteArray>
|
||||
|
||||
#ifndef QXT_DOXYGEN_RUN
|
||||
class QxtAbstractHttpConnectorPrivate : public QxtPrivate<QxtAbstractHttpConnector>
|
||||
{
|
||||
public:
|
||||
QxtHttpSessionManager* manager;
|
||||
QReadWriteLock bufferLock, requestLock;
|
||||
QHash<QIODevice*, QByteArray> buffers; // connection->buffer
|
||||
QHash<quint32, QIODevice*> requests; // requestID->connection
|
||||
QHash<quint32, QSharedPointer<QIODevice> > dataSources; // iodevices providing result data
|
||||
quint32 nextRequestID;
|
||||
|
||||
inline quint32 getNextRequestID(QIODevice* connection)
|
||||
{
|
||||
QWriteLocker locker(&requestLock);
|
||||
do
|
||||
{
|
||||
nextRequestID++;
|
||||
if (nextRequestID == 0xFFFFFFFF) nextRequestID = 1;
|
||||
}
|
||||
while (requests.contains(nextRequestID)); // yeah, right
|
||||
requests[nextRequestID] = connection;
|
||||
return nextRequestID;
|
||||
}
|
||||
|
||||
inline void doneWithRequest(quint32 requestID)
|
||||
{
|
||||
QWriteLocker locker(&requestLock);
|
||||
requests.remove(requestID);
|
||||
dataSources.remove(requestID);
|
||||
}
|
||||
|
||||
inline QIODevice* getRequestConnection(quint32 requestID)
|
||||
{
|
||||
QReadLocker locker(&requestLock);
|
||||
return requests[requestID];
|
||||
}
|
||||
|
||||
inline void setRequestDataSource( quint32 requestID, QSharedPointer<QIODevice>& dataSource )
|
||||
{
|
||||
QWriteLocker locker(&requestLock);
|
||||
dataSources.insert( requestID, dataSource );
|
||||
}
|
||||
|
||||
inline QSharedPointer<QIODevice>& getRequestDataSource(quint32 requestID)
|
||||
{
|
||||
QReadLocker locker(&requestLock);
|
||||
return dataSources[requestID];
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Creates a QxtAbstractHttpConnector with the specified \a parent.
|
||||
*
|
||||
* Note that this is an abstract class and cannot be instantiated directly.
|
||||
*/
|
||||
QxtAbstractHttpConnector::QxtAbstractHttpConnector(QObject* parent) : QObject(parent)
|
||||
{
|
||||
QXT_INIT_PRIVATE(QxtAbstractHttpConnector);
|
||||
qxt_d().nextRequestID = 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void QxtAbstractHttpConnector::setSessionManager(QxtHttpSessionManager* manager)
|
||||
{
|
||||
qxt_d().manager = manager;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the session manager into which the connector is installed.
|
||||
*
|
||||
* \sa QxtHttpSessionManager::setConnector
|
||||
*/
|
||||
QxtHttpSessionManager* QxtAbstractHttpConnector::sessionManager() const
|
||||
{
|
||||
return qxt_d().manager;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* Returns the QIODevice associated with a \a requestID.
|
||||
*
|
||||
* The request ID is generated internally and used by the session manager.
|
||||
*/
|
||||
QIODevice* QxtAbstractHttpConnector::getRequestConnection(quint32 requestID)
|
||||
{
|
||||
return qxt_d().getRequestConnection(requestID);
|
||||
}
|
||||
|
||||
void QxtAbstractHttpConnector::setRequestDataSource( quint32 requestID, QSharedPointer<QIODevice>& dataSource )
|
||||
{
|
||||
qxt_d().setRequestDataSource( requestID, dataSource );
|
||||
}
|
||||
|
||||
QSharedPointer<QIODevice>& QxtAbstractHttpConnector::getRequestDataSource(quint32 requestID)
|
||||
{
|
||||
return qxt_d().getRequestDataSource( requestID );
|
||||
}
|
||||
|
||||
void QxtAbstractHttpConnector::doneWithRequest(quint32 requestID)
|
||||
{
|
||||
qxt_d().doneWithRequest( requestID );
|
||||
}
|
||||
|
||||
/*!
|
||||
* Starts managing a new connection from \a device.
|
||||
*
|
||||
* This function should be invoked by a subclass to attach incoming connections
|
||||
* to the session manager.
|
||||
*/
|
||||
void QxtAbstractHttpConnector::addConnection(QIODevice* device)
|
||||
{
|
||||
QWriteLocker locker(&qxt_d().bufferLock);
|
||||
qxt_d().buffers[device] = QByteArray();
|
||||
QObject::connect(device, SIGNAL(readyRead()), this, SLOT(incomingData()));
|
||||
QObject::connect(device, SIGNAL(aboutToClose()), this, SLOT(disconnected()));
|
||||
QObject::connect(device, SIGNAL(disconnected()), this, SLOT(disconnected()));
|
||||
QObject::connect(device, SIGNAL(destroyed()), this, SLOT(disconnected()));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void QxtAbstractHttpConnector::incomingData(QIODevice* device)
|
||||
{
|
||||
if (!device)
|
||||
{
|
||||
device = qobject_cast<QIODevice*>(sender());
|
||||
if (!device) return;
|
||||
}
|
||||
QReadLocker locker(&qxt_d().bufferLock);
|
||||
QByteArray& buffer = qxt_d().buffers[device];
|
||||
buffer.append(device->readAll());
|
||||
if (!canParseRequest(buffer)) return;
|
||||
QHttpRequestHeader header = parseRequest(buffer);
|
||||
QxtWebContent* content = 0;
|
||||
QByteArray start;
|
||||
if (header.contentLength() > 0)
|
||||
{
|
||||
start = buffer.left(header.value("content-length").toInt());
|
||||
buffer = buffer.mid(header.value("content-length").toInt());
|
||||
content = new QxtWebContent(header.contentLength(), start, device);
|
||||
}
|
||||
else if (header.hasKey("connection") && header.value("connection").toLower() == "close")
|
||||
{
|
||||
start = buffer;
|
||||
buffer.clear();
|
||||
content = new QxtWebContent(header.contentLength(), start, device);
|
||||
} // else no content
|
||||
quint32 requestID = qxt_d().getNextRequestID(device);
|
||||
sessionManager()->incomingRequest(requestID, header, content);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void QxtAbstractHttpConnector::disconnected()
|
||||
{
|
||||
QIODevice* device = qobject_cast<QIODevice*>(sender());
|
||||
if (!device) return;
|
||||
QWriteLocker locker(&qxt_d().bufferLock);
|
||||
qxt_d().buffers.remove(device);
|
||||
sessionManager()->disconnected(device);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \fn virtual bool QxtAbstractHttpConnector::listen(const QHostAddress& interface, quint16 port)
|
||||
* Invoked by the session manager to indicate that the connector should listen
|
||||
* for incoming connections on the specified \a interface and \a port.
|
||||
*
|
||||
* If the interface is QHostAddress::Any, the server will listen on all network interfaces.
|
||||
*
|
||||
* Returns true on success, or false if the server could not begin listening.
|
||||
*
|
||||
* \sa addConnection(QIODevice*)
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \fn virtual bool QxtAbstractHttpConnector::canParseRequest(const QByteArray& buffer)
|
||||
* Returns true if a complete set of request headers can be extracted from the provided \a buffer.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \fn virtual QHttpRequestHeader QxtAbstractHttpConnector::parseRequest(QByteArray& buffer)
|
||||
* Extracts a set of request headers from the provided \a buffer.
|
||||
*
|
||||
* Subclasses implementing this function must be sure to remove the parsed data from the buffer.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \fn virtual void QxtAbstractHttpConnector::writeHeaders(QIODevice* device, const QHttpResponseHeader& header)
|
||||
* Writes a the response \a header to the specified \a device.
|
||||
*/
|
121
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtabstracthttpconnector.h
vendored
Normal file
121
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtabstracthttpconnector.h
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtWeb module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QXTABSTRACTHTTPCONNECTOR_H
|
||||
#define QXTABSTRACTHTTPCONNECTOR_H
|
||||
|
||||
#include "qxtglobal.h"
|
||||
#include <QObject>
|
||||
#include <QHostAddress>
|
||||
#include <QHttpHeader>
|
||||
#include <QSharedPointer>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QIODevice)
|
||||
class QxtHttpSessionManager;
|
||||
|
||||
class QxtAbstractHttpConnectorPrivate;
|
||||
class QXT_WEB_EXPORT QxtAbstractHttpConnector : public QObject
|
||||
{
|
||||
friend class QxtHttpSessionManager;
|
||||
Q_OBJECT
|
||||
public:
|
||||
QxtAbstractHttpConnector(QObject* parent = 0);
|
||||
virtual bool listen(const QHostAddress& iface, quint16 port) = 0;
|
||||
|
||||
protected:
|
||||
QxtHttpSessionManager* sessionManager() const;
|
||||
|
||||
void addConnection(QIODevice* device);
|
||||
QIODevice* getRequestConnection(quint32 requestID);
|
||||
void setRequestDataSource( quint32 requestID, QSharedPointer<QIODevice>& dataSource );
|
||||
QSharedPointer<QIODevice>& getRequestDataSource(quint32 requestID);
|
||||
void doneWithRequest(quint32 requestID);
|
||||
virtual bool canParseRequest(const QByteArray& buffer) = 0;
|
||||
virtual QHttpRequestHeader parseRequest(QByteArray& buffer) = 0;
|
||||
virtual void writeHeaders(QIODevice* device, const QHttpResponseHeader& header) = 0;
|
||||
|
||||
private Q_SLOTS:
|
||||
void incomingData(QIODevice* device = 0);
|
||||
void disconnected();
|
||||
|
||||
private:
|
||||
void setSessionManager(QxtHttpSessionManager* manager);
|
||||
QXT_DECLARE_PRIVATE(QxtAbstractHttpConnector)
|
||||
};
|
||||
|
||||
class QxtHttpServerConnectorPrivate;
|
||||
class QXT_WEB_EXPORT QxtHttpServerConnector : public QxtAbstractHttpConnector
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QxtHttpServerConnector(QObject* parent = 0);
|
||||
virtual bool listen(const QHostAddress& iface, quint16 port);
|
||||
|
||||
protected:
|
||||
virtual bool canParseRequest(const QByteArray& buffer);
|
||||
virtual QHttpRequestHeader parseRequest(QByteArray& buffer);
|
||||
virtual void writeHeaders(QIODevice* device, const QHttpResponseHeader& header);
|
||||
|
||||
private Q_SLOTS:
|
||||
void acceptConnection();
|
||||
|
||||
private:
|
||||
QXT_DECLARE_PRIVATE(QxtHttpServerConnector)
|
||||
};
|
||||
|
||||
class QxtScgiServerConnectorPrivate;
|
||||
class QXT_WEB_EXPORT QxtScgiServerConnector : public QxtAbstractHttpConnector
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QxtScgiServerConnector(QObject* parent = 0);
|
||||
virtual bool listen(const QHostAddress& iface, quint16 port);
|
||||
|
||||
protected:
|
||||
virtual bool canParseRequest(const QByteArray& buffer);
|
||||
virtual QHttpRequestHeader parseRequest(QByteArray& buffer);
|
||||
virtual void writeHeaders(QIODevice* device, const QHttpResponseHeader& header);
|
||||
|
||||
private Q_SLOTS:
|
||||
void acceptConnection();
|
||||
|
||||
private:
|
||||
QXT_DECLARE_PRIVATE(QxtScgiServerConnector)
|
||||
};
|
||||
/* Commented out pending implementation
|
||||
|
||||
class QxtFcgiConnectorPrivate;
|
||||
class QXT_WEB_EXPORT QxtFcgiConnector : public QxtAbstractHttpConnector {
|
||||
Q_OBJECT
|
||||
public:
|
||||
QxtFcgiConnector(QObject* parent = 0);
|
||||
virtual bool listen(const QHostAddress& iface, quint16 port);
|
||||
|
||||
private:
|
||||
QXT_DECLARE_PRIVATE(QxtFcgiConnector)
|
||||
};
|
||||
*/
|
||||
|
||||
#endif // QXTABSTRACTHTTPCONNECTOR_H
|
121
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtabstractwebservice.cpp
vendored
Normal file
121
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtabstractwebservice.cpp
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtWeb module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\class QxtAbstractWebService
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtAbstractWebService class is a base interface for web services
|
||||
|
||||
QxtAbstractWebService provides a common interface for all web service classes.
|
||||
It uses an event-driven design instead of the more traditional request-response
|
||||
design used by many web scripting languages. When the user requests a web
|
||||
page, the service receives a pageRequestedEvent; after the service assembles
|
||||
the response, it must post a QxtWebPageEvent (or a subclass, such as
|
||||
QxtWebRedirectEvent or QxtWebErrorEvent).
|
||||
|
||||
Usually, an application providing web services will instantiate one
|
||||
QxtAbstractWebService object for each session, but this is not a requirement.
|
||||
For services that do not require session management, such as those that serve
|
||||
only static content, the session factory may return the same pointer for
|
||||
every invocation, or it may use some more exotic scheme.
|
||||
|
||||
When using one service object per session, each service's data members are
|
||||
independent and may be used to track state across requests. A service object
|
||||
shared among multiple sessions will retain state across requests as well but
|
||||
it must implement its own mechanism for separating non-shared data.
|
||||
|
||||
The QxtWeb architecture is not multithreaded; that is, QxtAbstractWebService
|
||||
does not automatically spawn a process for every session. However,
|
||||
QxtAbstractWebSessionManager performs thread-safe event dispatching, so
|
||||
subclasses of QxtAbstractWebService are free to create threads themselves.
|
||||
|
||||
A web service object may delete itself (see QObject::deleteLater()) to end
|
||||
the associated session.
|
||||
|
||||
\sa QxtAbstractWebSessionManager::ServiceFactory
|
||||
*/
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
* The current architecture only allows for two behaviors: creating a new session
|
||||
* for every connection without a session cookie, or not using sessions at all.
|
||||
* This needs to be fixed by adding a function to the session manager to explicitly
|
||||
* create a new session.
|
||||
*/
|
||||
|
||||
#include "qxtabstractwebservice.h"
|
||||
|
||||
#ifndef QXT_DOXYGEN_RUN
|
||||
class QxtAbstractWebServicePrivate : public QxtPrivate<QxtAbstractWebService>
|
||||
{
|
||||
public:
|
||||
QXT_DECLARE_PUBLIC(QxtAbstractWebService)
|
||||
QxtAbstractWebServicePrivate() {}
|
||||
|
||||
QxtAbstractWebSessionManager* manager;
|
||||
};
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Creates a QxtAbstractWebService with the specified \a parent and session \a manager.
|
||||
*
|
||||
* Often, the session manager will also be the parent, but this is not a requirement.
|
||||
*
|
||||
* Note that this is an abstract class and cannot be instantiated directly.
|
||||
*/
|
||||
QxtAbstractWebService::QxtAbstractWebService(QxtAbstractWebSessionManager* manager, QObject* parent) : QObject(parent)
|
||||
{
|
||||
QXT_INIT_PRIVATE(QxtAbstractWebService);
|
||||
qxt_d().manager = manager;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the session manager associated with the web service.
|
||||
*/
|
||||
QxtAbstractWebSessionManager* QxtAbstractWebService::sessionManager() const
|
||||
{
|
||||
return qxt_d().manager;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \fn void QxtAbstractWebService::postEvent(QxtWebEvent* event)
|
||||
* Posts an \a event to a web browser that has made a request to the service.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \fn virtual void QxtAbstractWebService::pageRequestedEvent(QxtWebRequestEvent* event)
|
||||
* This \a event handler must be reimplemented in subclasses to receive page
|
||||
* request events.
|
||||
*
|
||||
* Every page request event received MUST be responded to with a QxtWebPageEvent
|
||||
* or a QxtWebPageEvent subclass. This response does not have to be posted
|
||||
* during the execution of this function, to support asynchronous design, but
|
||||
* failure to post an event will cause the web browser making the request to
|
||||
* wait until it times out.
|
||||
*
|
||||
* \sa QxtWebRequestEvent
|
||||
*/
|
53
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtabstractwebservice.h
vendored
Normal file
53
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtabstractwebservice.h
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtWeb module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QXTABSTRACTWEBSERVICE_H
|
||||
#define QXTABSTRACTWEBSERVICE_H
|
||||
|
||||
#include <QObject>
|
||||
#include "qxtabstractwebsessionmanager.h"
|
||||
class QxtWebEvent;
|
||||
class QxtWebRequestEvent;
|
||||
|
||||
class QxtAbstractWebServicePrivate;
|
||||
class QXT_WEB_EXPORT QxtAbstractWebService : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QxtAbstractWebService(QxtAbstractWebSessionManager* manager, QObject* parent = 0);
|
||||
|
||||
QxtAbstractWebSessionManager* sessionManager() const;
|
||||
inline void postEvent(QxtWebEvent* event)
|
||||
{
|
||||
sessionManager()->postEvent(event);
|
||||
}
|
||||
virtual void pageRequestedEvent(QxtWebRequestEvent* event) = 0;
|
||||
// virtual void functionInvokedEvent(QxtWebRequestEvent* event) = 0; // todo: implement
|
||||
|
||||
private:
|
||||
QXT_DECLARE_PRIVATE(QxtAbstractWebService)
|
||||
};
|
||||
|
||||
#endif // QXTABSTRACTWEBSERVICE_H
|
201
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtabstractwebsessionmanager.cpp
vendored
Normal file
201
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtabstractwebsessionmanager.cpp
vendored
Normal file
@@ -0,0 +1,201 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtWeb module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\class QxtAbstractWebSessionManager
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtAbstractWebSessionManager class is a base class for QxtWeb session managers
|
||||
|
||||
QxtAbstractWebSessionManager is the base class for all QxtWeb session managers.
|
||||
|
||||
Session managers are responsible for managing connections between web browsers
|
||||
and web services, for creating sessions and their corresponding service objects,
|
||||
and for managing and dispatching events between browsers and services.
|
||||
|
||||
Note that the session manager is not responsible for destroying service objects.
|
||||
A service object that wishes to end its corresponding session may destroy itself
|
||||
(see QObject::deleteLater()) and QxtAbstractWebSessionManager will automatically
|
||||
clean up its internal session tracking data.
|
||||
|
||||
\sa QxtAbstractWebService
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \typedef QxtAbstractWebSessionManager::ServiceFactory
|
||||
* \brief Pointer to a function that generates QxtAbstractWebService objects
|
||||
*
|
||||
* \bold TYPEDEF: The ServiceFactory type represents a pointer to a function that takes two
|
||||
* parameters -- a QxtAbstractWebSessionManager* pointer and an int session ID.
|
||||
* The function must return a QxtAbstractWebService* pointer.
|
||||
*
|
||||
* Usually, an application providing web services will instantiate one
|
||||
* QxtAbstractWebService object for each session. For services that do not
|
||||
* require session management, such as those that serve only static pages, a
|
||||
* single service object may be shared for all requests, or it may use some
|
||||
* more exotic scheme. See QxtAbstractWebService for more details.
|
||||
*/
|
||||
|
||||
#include "qxtabstractwebsessionmanager.h"
|
||||
#include "qxtabstractwebsessionmanager_p.h"
|
||||
#include "qxtabstractwebservice.h"
|
||||
#include "qxtmetaobject.h"
|
||||
#include <QtDebug>
|
||||
|
||||
#ifndef QXT_DOXYGEN_RUN
|
||||
QxtAbstractWebSessionManagerPrivate::QxtAbstractWebSessionManagerPrivate() : factory(0), maxID(1)
|
||||
{
|
||||
// initializers only
|
||||
}
|
||||
|
||||
void QxtAbstractWebSessionManagerPrivate::sessionDestroyed(int sessionID)
|
||||
{
|
||||
if (sessions.contains(sessionID))
|
||||
{
|
||||
freeList.enqueue(sessionID);
|
||||
sessions.remove(sessionID);
|
||||
}
|
||||
}
|
||||
|
||||
int QxtAbstractWebSessionManagerPrivate::getNextID()
|
||||
{
|
||||
if (freeList.empty())
|
||||
{
|
||||
int next = maxID;
|
||||
maxID++;
|
||||
return next;
|
||||
}
|
||||
return freeList.dequeue();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Creates a QxtAbstractWebSessionManager with the specified \a parent.
|
||||
*
|
||||
* Note that this is an abstract class and cannot be instantiated directly.
|
||||
*/
|
||||
QxtAbstractWebSessionManager::QxtAbstractWebSessionManager(QObject* parent) : QObject(parent)
|
||||
{
|
||||
QXT_INIT_PRIVATE(QxtAbstractWebSessionManager);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Sets the service \a factory for the session manager.
|
||||
*
|
||||
* The service factory is invoked every time the session manager creates a new
|
||||
* session. Usually, an application providing web services will instantiate one
|
||||
* QxtAbstractWebService object for each session. For services that do not
|
||||
* require separate sessions, such as those that serve only static pages, the
|
||||
* factory may return a pointer to the same object for multiple requests.
|
||||
*
|
||||
* \sa QxtAbstractWebSessionManager::ServiceFactory
|
||||
*/
|
||||
void QxtAbstractWebSessionManager::setServiceFactory(ServiceFactory* factory)
|
||||
{
|
||||
qxt_d().factory = factory;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the service factory in use by the session manager.
|
||||
*
|
||||
* \sa setServiceFactory(ServiceFactory*)
|
||||
*/
|
||||
QxtAbstractWebSessionManager::ServiceFactory* QxtAbstractWebSessionManager::serviceFactory() const
|
||||
{
|
||||
return qxt_d().factory;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the service object corresponding to the provided \a sessionID.
|
||||
*/
|
||||
QxtAbstractWebService* QxtAbstractWebSessionManager::session(int sessionID) const
|
||||
{
|
||||
if (qxt_d().sessions.contains(sessionID))
|
||||
return qxt_d().sessions[sessionID];
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Creates a new session and returns its session ID.
|
||||
*
|
||||
* This function uses the serviceFactory() to request an instance of the web service.
|
||||
* \sa serviceFactory()
|
||||
*/
|
||||
int QxtAbstractWebSessionManager::createService()
|
||||
{
|
||||
int sessionID = qxt_d().getNextID();
|
||||
if (!qxt_d().factory) return sessionID;
|
||||
|
||||
QxtAbstractWebService* service = serviceFactory()(this, sessionID);
|
||||
qxt_d().sessions[sessionID] = service;
|
||||
// Using QxtBoundFunction to bind the sessionID to the slot invocation
|
||||
QxtMetaObject::connect(service, SIGNAL(destroyed()), QxtMetaObject::bind(&qxt_d(), SLOT(sessionDestroyed(int)), Q_ARG(int, sessionID)), Qt::QueuedConnection);
|
||||
return sessionID; // you can always get the service with this
|
||||
}
|
||||
|
||||
/*!
|
||||
* \fn virtual bool QxtAbstractWebSessionManager::start()
|
||||
* Starts the session manager.
|
||||
*
|
||||
* Session managers should not create sessions before start() is invoked.
|
||||
* Subclasses are encouraged to refrain from accepting connections until the
|
||||
* session manager is started.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \fn virtual void QxtAbstractWebSessionManager::postEvent(QxtWebEvent* event)
|
||||
* Adds the event to the event queue for its associated session.
|
||||
*
|
||||
* Since different protocols may require different event processing behavior,
|
||||
* there is no default implementation in QxtAbstractWebSessionManager. Subclasses
|
||||
* are responsible for maintaining event queues and deciding when and where to
|
||||
* dispatch events.
|
||||
*
|
||||
* Depending on the subclass's implementation posted events may not be dispatched
|
||||
* for some time, and is is possible that an event may never be dispatched if
|
||||
* the session is terminated before the event is handled.
|
||||
*
|
||||
* \sa QxtWebEvent
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \fn virtual void QxtAbstractWebSessionManager::processEvents()
|
||||
* Processes pending events for all sessions.
|
||||
*
|
||||
* Since different protocols may require different event processing behavior,
|
||||
* there is no default implementation in QxtAbstractWebSessionManager. Subclasses
|
||||
* are responsible for maintaining event queues and deciding when and where to
|
||||
* dispatch events.
|
||||
*
|
||||
* processEvents() is not required to dispatch all events immediately. In
|
||||
* particular, some events may require certain conditions to be met before
|
||||
* they may be fully processed. (For example, because HTTP cookies are sent
|
||||
* as response headers, QxtHttpServerConnector may not dispatch a
|
||||
* QxtWebStoreCookieEvent until a QxtWebPageEvent for the same session is
|
||||
* available.) Unprocessed events may remain in the event queue.
|
||||
*
|
||||
* \sa QxtWebEvent
|
||||
*/
|
60
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtabstractwebsessionmanager.h
vendored
Normal file
60
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtabstractwebsessionmanager.h
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtWeb module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QXTABSTRACTWEBSESSIONMANAGER_H
|
||||
#define QXTABSTRACTWEBSESSIONMANAGER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <qxtglobal.h>
|
||||
class QxtAbstractWebService;
|
||||
class QxtWebEvent;
|
||||
|
||||
class QxtAbstractWebSessionManagerPrivate;
|
||||
class QXT_WEB_EXPORT QxtAbstractWebSessionManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
typedef QxtAbstractWebService* ServiceFactory(QxtAbstractWebSessionManager*, int);
|
||||
|
||||
QxtAbstractWebSessionManager(QObject* parent = 0);
|
||||
|
||||
virtual bool start() = 0;
|
||||
virtual void postEvent(QxtWebEvent* event) = 0;
|
||||
void setServiceFactory(ServiceFactory* factory);
|
||||
ServiceFactory* serviceFactory() const;
|
||||
|
||||
QxtAbstractWebService* session(int sessionID) const;
|
||||
|
||||
protected:
|
||||
int createService();
|
||||
|
||||
protected Q_SLOTS:
|
||||
virtual void processEvents() = 0;
|
||||
|
||||
private:
|
||||
QXT_DECLARE_PRIVATE(QxtAbstractWebSessionManager)
|
||||
};
|
||||
|
||||
#endif // QXTABSTRACTWEBSESSIONMANAGER_H
|
55
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtabstractwebsessionmanager_p.h
vendored
Normal file
55
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtabstractwebsessionmanager_p.h
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtWeb module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QXTABSTRACTWEBSESSIONMANAGER_P_H
|
||||
#define QXTABSTRACTWEBSESSIONMANAGER_P_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QPointer>
|
||||
#include <QHash>
|
||||
#include <QQueue>
|
||||
#include "qxtabstractwebsessionmanager.h"
|
||||
|
||||
#ifndef QXT_DOXYGEN_RUN
|
||||
class QxtAbstractWebSessionManagerPrivate : public QObject, public QxtPrivate<QxtAbstractWebSessionManager>
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QxtAbstractWebSessionManagerPrivate();
|
||||
QXT_DECLARE_PUBLIC(QxtAbstractWebSessionManager)
|
||||
|
||||
QxtAbstractWebSessionManager::ServiceFactory* factory;
|
||||
QHash<int, QxtAbstractWebService*> sessions;
|
||||
QQueue<int> freeList;
|
||||
int maxID;
|
||||
|
||||
int getNextID();
|
||||
|
||||
public Q_SLOTS:
|
||||
void sessionDestroyed(int sessionID);
|
||||
};
|
||||
#endif // QXT_DOXYGEN_RUN
|
||||
|
||||
#endif // QXTABSTRACTWEBSESSIONMANAGER_P_H
|
633
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtboundcfunction.h
vendored
Normal file
633
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtboundcfunction.h
vendored
Normal file
@@ -0,0 +1,633 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtCore module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QXTBOUNDCFUNCTION_H
|
||||
#define QXTBOUNDCFUNCTION_H
|
||||
|
||||
#include <qxtboundfunctionbase.h>
|
||||
#include <qxtmetatype.h>
|
||||
#include <qxtglobal.h>
|
||||
#include <QtDebug>
|
||||
|
||||
#ifndef QXT_DOXYGEN_RUN
|
||||
|
||||
#define QXT_RETURN(fp) *reinterpret_cast<RETURN*>(returnValue.data()) = (*reinterpret_cast<FUNCTION>(fp))
|
||||
#define QXT_INVOKE(fp) (*reinterpret_cast<FUNCTION>(fp))
|
||||
#define QXT_PARAM(i) *reinterpret_cast<T ## i *>(p ## i .data())
|
||||
|
||||
template < typename RETURN, typename T1 = void, typename T2 = void, typename T3 = void, typename T4 = void, typename T5 = void,
|
||||
typename T6 = void, typename T7 = void, typename T8 = void, typename T9 = void, typename T10 = void >
|
||||
class /*QXT_CORE_EXPORT*/ qxt_cfunction_return : public QxtGenericFunctionPointer
|
||||
{
|
||||
public:
|
||||
typedef RETURN(*FUNCTION)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
|
||||
bool invoke(QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument))
|
||||
{
|
||||
QXT_10_UNUSED;
|
||||
QXT_RETURN(funcPtr)(QXT_PARAM(1), QXT_PARAM(2), QXT_PARAM(3), QXT_PARAM(4), QXT_PARAM(5), QXT_PARAM(6), QXT_PARAM(7), QXT_PARAM(8), QXT_PARAM(9), QXT_PARAM(10));
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
qxt_cfunction_return(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
|
||||
};
|
||||
|
||||
template <typename RETURN>
|
||||
class /*QXT_CORE_EXPORT*/ qxt_cfunction_return<RETURN, void, void, void, void, void, void, void, void, void, void> : public QxtGenericFunctionPointer
|
||||
{
|
||||
public:
|
||||
typedef RETURN(*FUNCTION)();
|
||||
bool invoke(QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument))
|
||||
{
|
||||
QXT_10_UNUSED;
|
||||
QXT_RETURN(funcPtr)();
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
qxt_cfunction_return(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
|
||||
};
|
||||
|
||||
template <typename RETURN, typename T1>
|
||||
class /*QXT_CORE_EXPORT*/ qxt_cfunction_return<RETURN, T1, void, void, void, void, void, void, void, void, void> : public QxtGenericFunctionPointer
|
||||
{
|
||||
public:
|
||||
typedef RETURN(*FUNCTION)(T1);
|
||||
bool invoke(QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument))
|
||||
{
|
||||
QXT_10_UNUSED;
|
||||
QXT_RETURN(funcPtr)(QXT_PARAM(1));
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
qxt_cfunction_return(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
|
||||
};
|
||||
|
||||
template <typename RETURN, typename T1, typename T2>
|
||||
class /*QXT_CORE_EXPORT*/ qxt_cfunction_return<RETURN, T1, T2, void, void, void, void, void, void, void, void> : public QxtGenericFunctionPointer
|
||||
{
|
||||
public:
|
||||
typedef RETURN(*FUNCTION)(T1, T2);
|
||||
bool invoke(QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument))
|
||||
{
|
||||
QXT_10_UNUSED;
|
||||
QXT_RETURN(funcPtr)(QXT_PARAM(1), QXT_PARAM(2));
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
qxt_cfunction_return(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
|
||||
};
|
||||
|
||||
template <typename RETURN, typename T1, typename T2, typename T3>
|
||||
class /*QXT_CORE_EXPORT*/ qxt_cfunction_return<RETURN, T1, T2, T3, void, void, void, void, void, void, void> : public QxtGenericFunctionPointer
|
||||
{
|
||||
public:
|
||||
typedef RETURN(*FUNCTION)(T1, T2, T3);
|
||||
bool invoke(QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument))
|
||||
{
|
||||
QXT_10_UNUSED;
|
||||
QXT_RETURN(funcPtr)(QXT_PARAM(1), QXT_PARAM(2), QXT_PARAM(3));
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
qxt_cfunction_return(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
|
||||
};
|
||||
|
||||
template <typename RETURN, typename T1, typename T2, typename T3, typename T4>
|
||||
class /*QXT_CORE_EXPORT*/ qxt_cfunction_return<RETURN, T1, T2, T3, T4, void, void, void, void, void, void> : public QxtGenericFunctionPointer
|
||||
{
|
||||
public:
|
||||
typedef RETURN(*FUNCTION)(T1, T2, T3, T4);
|
||||
bool invoke(QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument))
|
||||
{
|
||||
QXT_10_UNUSED;
|
||||
QXT_RETURN(funcPtr)(QXT_PARAM(1), QXT_PARAM(2), QXT_PARAM(3), QXT_PARAM(4));
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
qxt_cfunction_return(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
|
||||
};
|
||||
|
||||
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
class /*QXT_CORE_EXPORT*/ qxt_cfunction_return<RETURN, T1, T2, T3, T4, T5, void, void, void, void, void> : public QxtGenericFunctionPointer
|
||||
{
|
||||
public:
|
||||
typedef RETURN(*FUNCTION)(T1, T2, T3, T4, T5);
|
||||
bool invoke(QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument))
|
||||
{
|
||||
QXT_10_UNUSED;
|
||||
QXT_RETURN(funcPtr)(QXT_PARAM(1), QXT_PARAM(2), QXT_PARAM(3), QXT_PARAM(4), QXT_PARAM(5));
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
qxt_cfunction_return(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
|
||||
};
|
||||
|
||||
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
||||
class /*QXT_CORE_EXPORT*/ qxt_cfunction_return<RETURN, T1, T2, T3, T4, T5, T6, void, void, void, void> : public QxtGenericFunctionPointer
|
||||
{
|
||||
public:
|
||||
typedef RETURN(*FUNCTION)(T1, T2, T3, T4, T5, T6);
|
||||
bool invoke(QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument))
|
||||
{
|
||||
QXT_10_UNUSED;
|
||||
QXT_RETURN(funcPtr)(QXT_PARAM(1), QXT_PARAM(2), QXT_PARAM(3), QXT_PARAM(4), QXT_PARAM(5), QXT_PARAM(6));
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
qxt_cfunction_return(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
|
||||
};
|
||||
|
||||
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
|
||||
class /*QXT_CORE_EXPORT*/ qxt_cfunction_return<RETURN, T1, T2, T3, T4, T5, T6, T7, void, void, void> : public QxtGenericFunctionPointer
|
||||
{
|
||||
public:
|
||||
typedef RETURN(*FUNCTION)(T1, T2, T3, T4, T5, T6, T7);
|
||||
bool invoke(QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument))
|
||||
{
|
||||
QXT_10_UNUSED;
|
||||
QXT_RETURN(funcPtr)(QXT_PARAM(1), QXT_PARAM(2), QXT_PARAM(3), QXT_PARAM(4), QXT_PARAM(5), QXT_PARAM(6), QXT_PARAM(7));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
||||
class /*QXT_CORE_EXPORT*/ qxt_cfunction_return<RETURN, T1, T2, T3, T4, T5, T6, T7, T8, void, void> : public QxtGenericFunctionPointer
|
||||
{
|
||||
public:
|
||||
typedef RETURN(*FUNCTION)(T1, T2, T3, T4, T5, T6, T7, T8);
|
||||
bool invoke(QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument))
|
||||
{
|
||||
QXT_10_UNUSED;
|
||||
QXT_RETURN(funcPtr)(QXT_PARAM(1), QXT_PARAM(2), QXT_PARAM(3), QXT_PARAM(4), QXT_PARAM(5), QXT_PARAM(6), QXT_PARAM(7), QXT_PARAM(8));
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
qxt_cfunction_return(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
|
||||
};
|
||||
|
||||
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
|
||||
class /*QXT_CORE_EXPORT*/ qxt_cfunction_return<RETURN, T1, T2, T3, T4, T5, T6, T7, T8, T9, void> : public QxtGenericFunctionPointer
|
||||
{
|
||||
public:
|
||||
typedef RETURN(*FUNCTION)(T1, T2, T3, T4, T5, T6, T7, T8, T9);
|
||||
bool invoke(QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument))
|
||||
{
|
||||
QXT_10_UNUSED;
|
||||
QXT_RETURN(funcPtr)(QXT_PARAM(1), QXT_PARAM(2), QXT_PARAM(3), QXT_PARAM(4), QXT_PARAM(5), QXT_PARAM(6), QXT_PARAM(7), QXT_PARAM(8), QXT_PARAM(9));
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
qxt_cfunction_return(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
|
||||
};
|
||||
|
||||
template < typename T1 = void, typename T2 = void, typename T3 = void, typename T4 = void, typename T5 = void,
|
||||
typename T6 = void, typename T7 = void, typename T8 = void, typename T9 = void, typename T10 = void >
|
||||
class /*QXT_CORE_EXPORT*/ qxt_cfunction : public QxtGenericFunctionPointer
|
||||
{
|
||||
public:
|
||||
typedef void(*FUNCTION)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
|
||||
bool invoke(QXT_PROTO_10ARGS(QGenericArgument))
|
||||
{
|
||||
QXT_10_UNUSED;
|
||||
QXT_INVOKE(funcPtr)(QXT_PARAM(1), QXT_PARAM(2), QXT_PARAM(3), QXT_PARAM(4), QXT_PARAM(5), QXT_PARAM(6), QXT_PARAM(7), QXT_PARAM(8), QXT_PARAM(9), QXT_PARAM(10));
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
qxt_cfunction(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
|
||||
};
|
||||
|
||||
template <>
|
||||
class /*QXT_CORE_EXPORT*/ qxt_cfunction<void, void, void, void, void, void, void, void, void, void> : public QxtGenericFunctionPointer
|
||||
{
|
||||
public:
|
||||
typedef void(*FUNCTION)();
|
||||
bool invoke(QXT_PROTO_10ARGS(QGenericArgument))
|
||||
{
|
||||
QXT_10_UNUSED;
|
||||
QXT_INVOKE(funcPtr)();
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
qxt_cfunction(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
|
||||
};
|
||||
|
||||
template <typename T1>
|
||||
class /*QXT_CORE_EXPORT*/ qxt_cfunction<T1, void, void, void, void, void, void, void, void, void> : public QxtGenericFunctionPointer
|
||||
{
|
||||
public:
|
||||
typedef void(*FUNCTION)(T1);
|
||||
bool invoke(QXT_PROTO_10ARGS(QGenericArgument))
|
||||
{
|
||||
QXT_10_UNUSED;
|
||||
QXT_INVOKE(funcPtr)(QXT_PARAM(1));
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
qxt_cfunction(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
|
||||
};
|
||||
|
||||
template <typename T1, typename T2>
|
||||
class /*QXT_CORE_EXPORT*/ qxt_cfunction<T1, T2, void, void, void, void, void, void, void, void> : public QxtGenericFunctionPointer
|
||||
{
|
||||
public:
|
||||
typedef void(*FUNCTION)(T1, T2);
|
||||
bool invoke(QXT_PROTO_10ARGS(QGenericArgument))
|
||||
{
|
||||
QXT_10_UNUSED;
|
||||
QXT_INVOKE(funcPtr)(QXT_PARAM(1), QXT_PARAM(2));
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
qxt_cfunction(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
|
||||
};
|
||||
|
||||
template <typename T1, typename T2, typename T3>
|
||||
class /*QXT_CORE_EXPORT*/ qxt_cfunction<T1, T2, T3, void, void, void, void, void, void, void> : public QxtGenericFunctionPointer
|
||||
{
|
||||
public:
|
||||
typedef void(*FUNCTION)(T1, T2, T3);
|
||||
bool invoke(QXT_PROTO_10ARGS(QGenericArgument))
|
||||
{
|
||||
QXT_10_UNUSED;
|
||||
QXT_INVOKE(funcPtr)(QXT_PARAM(1), QXT_PARAM(2), QXT_PARAM(3));
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
qxt_cfunction(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
|
||||
};
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4>
|
||||
class /*QXT_CORE_EXPORT*/ qxt_cfunction<T1, T2, T3, T4, void, void, void, void, void, void> : public QxtGenericFunctionPointer
|
||||
{
|
||||
public:
|
||||
typedef void(*FUNCTION)(T1, T2, T3, T4);
|
||||
bool invoke(QXT_PROTO_10ARGS(QGenericArgument))
|
||||
{
|
||||
QXT_10_UNUSED;
|
||||
QXT_INVOKE(funcPtr)(QXT_PARAM(1), QXT_PARAM(2), QXT_PARAM(3), QXT_PARAM(4));
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
qxt_cfunction(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
|
||||
};
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
class /*QXT_CORE_EXPORT*/ qxt_cfunction<T1, T2, T3, T4, T5, void, void, void, void, void> : public QxtGenericFunctionPointer
|
||||
{
|
||||
public:
|
||||
typedef void(*FUNCTION)(T1, T2, T3, T4, T5);
|
||||
bool invoke(QXT_PROTO_10ARGS(QGenericArgument))
|
||||
{
|
||||
QXT_10_UNUSED;
|
||||
QXT_INVOKE(funcPtr)(QXT_PARAM(1), QXT_PARAM(2), QXT_PARAM(3), QXT_PARAM(4), QXT_PARAM(5));
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
qxt_cfunction(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
|
||||
};
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
||||
class /*QXT_CORE_EXPORT*/ qxt_cfunction<T1, T2, T3, T4, T5, T6, void, void, void, void> : public QxtGenericFunctionPointer
|
||||
{
|
||||
public:
|
||||
typedef void(*FUNCTION)(T1, T2, T3, T4, T5, T6);
|
||||
bool invoke(QXT_PROTO_10ARGS(QGenericArgument))
|
||||
{
|
||||
QXT_10_UNUSED;
|
||||
QXT_INVOKE(funcPtr)(QXT_PARAM(1), QXT_PARAM(2), QXT_PARAM(3), QXT_PARAM(4), QXT_PARAM(5), QXT_PARAM(6));
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
qxt_cfunction(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
|
||||
};
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
|
||||
class /*QXT_CORE_EXPORT*/ qxt_cfunction<T1, T2, T3, T4, T5, T6, T7, void, void, void> : public QxtGenericFunctionPointer
|
||||
{
|
||||
public:
|
||||
typedef void(*FUNCTION)(T1, T2, T3, T4, T5, T6, T7);
|
||||
bool invoke(QXT_PROTO_10ARGS(QGenericArgument))
|
||||
{
|
||||
QXT_10_UNUSED;
|
||||
QXT_INVOKE(funcPtr)(QXT_PARAM(1), QXT_PARAM(2), QXT_PARAM(3), QXT_PARAM(4), QXT_PARAM(5), QXT_PARAM(6), QXT_PARAM(7));
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
qxt_cfunction(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
|
||||
};
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
||||
class /*QXT_CORE_EXPORT*/ qxt_cfunction<T1, T2, T3, T4, T5, T6, T7, T8, void, void> : public QxtGenericFunctionPointer
|
||||
{
|
||||
public:
|
||||
typedef void(*FUNCTION)(T1, T2, T3, T4, T5, T6, T7, T8);
|
||||
bool invoke(QXT_PROTO_10ARGS(QGenericArgument))
|
||||
{
|
||||
QXT_10_UNUSED;
|
||||
QXT_INVOKE(funcPtr)(QXT_PARAM(1), QXT_PARAM(2), QXT_PARAM(3), QXT_PARAM(4), QXT_PARAM(5), QXT_PARAM(6), QXT_PARAM(7), QXT_PARAM(8));
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
qxt_cfunction(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
|
||||
};
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
|
||||
class /*QXT_CORE_EXPORT*/ qxt_cfunction<T1, T2, T3, T4, T5, T6, T7, T8, T9, void> : public QxtGenericFunctionPointer
|
||||
{
|
||||
public:
|
||||
typedef void(*FUNCTION)(T1, T2, T3, T4, T5, T6, T7, T8, T9);
|
||||
bool invoke(QXT_PROTO_10ARGS(QGenericArgument))
|
||||
{
|
||||
QXT_10_UNUSED;
|
||||
QXT_INVOKE(funcPtr)(QXT_PARAM(1), QXT_PARAM(2), QXT_PARAM(3), QXT_PARAM(4), QXT_PARAM(5), QXT_PARAM(6), QXT_PARAM(7), QXT_PARAM(8), QXT_PARAM(9));
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
qxt_cfunction(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
|
||||
};
|
||||
|
||||
template < typename RETURN = void, typename T1 = void, typename T2 = void, typename T3 = void, typename T4 = void, typename T5 = void,
|
||||
typename T6 = void, typename T7 = void, typename T8 = void, typename T9 = void, typename T10 = void >
|
||||
class /*QXT_CORE_EXPORT*/ QxtBoundCFunction : public QxtBoundFunctionBase
|
||||
{
|
||||
public:
|
||||
QxtGenericFunctionPointer funcPtr;
|
||||
|
||||
QxtBoundCFunction(QObject* parent, QxtGenericFunctionPointer funcPointer, QGenericArgument* params[10], QByteArray types[10]) : QxtBoundFunctionBase(parent, params, types), funcPtr(funcPointer)
|
||||
{
|
||||
// initializers only, thanks to template magic
|
||||
}
|
||||
|
||||
virtual bool invokeImpl(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_IMPL_10ARGS(QGenericArgument))
|
||||
{
|
||||
if (type != Qt::AutoConnection && type != Qt::DirectConnection)
|
||||
{
|
||||
qWarning() << "QxtBoundCFunction::invoke: Cannot invoke non-Qt functions using a queued connection";
|
||||
return false;
|
||||
}
|
||||
return reinterpret_cast<qxt_cfunction_return<RETURN, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>*>(&funcPtr)->invoke(returnValue, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10>
|
||||
class /*QXT_CORE_EXPORT*/ QxtBoundCFunction<void, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> : public QxtBoundFunctionBase
|
||||
{
|
||||
public:
|
||||
QxtGenericFunctionPointer funcPtr;
|
||||
|
||||
QxtBoundCFunction(QObject* parent, QxtGenericFunctionPointer funcPointer, QGenericArgument* params[10], QByteArray types[10]) : QxtBoundFunctionBase(parent, params, types), funcPtr(funcPointer)
|
||||
{
|
||||
// initializers only, thanks to template magic
|
||||
}
|
||||
|
||||
virtual bool invokeImpl(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_IMPL_10ARGS(QGenericArgument))
|
||||
{
|
||||
Q_UNUSED(returnValue);
|
||||
if (type != Qt::AutoConnection && type != Qt::DirectConnection)
|
||||
{
|
||||
qWarning() << "QxtBoundCFunction::invoke: Cannot invoke non-Qt functions using a queued connection";
|
||||
return false;
|
||||
}
|
||||
return reinterpret_cast<qxt_cfunction<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>*>(&funcPtr)->invoke(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
|
||||
}
|
||||
};
|
||||
|
||||
#undef QXT_RETURN
|
||||
#undef QXT_INVOKE
|
||||
#undef QXT_PARAM
|
||||
#endif
|
||||
|
||||
namespace QxtMetaObject
|
||||
{
|
||||
/*!
|
||||
* \relates QxtMetaObject
|
||||
* \sa QxtMetaObject::connect
|
||||
* \sa qxtFuncPtr
|
||||
* \sa QxtBoundFunction
|
||||
* \sa QXT_BIND
|
||||
*
|
||||
* Creates a binding to the provided C/C++ function using the provided parameter list.
|
||||
* Use the qxtFuncPtr function to wrap a bare function pointer for use in this function.
|
||||
* Use the Q_ARG macro to specify constant parameters, or use the QXT_BIND macro to
|
||||
* relay a parameter from a connected signal or passed via the QxtBoundFunction::invoke()
|
||||
* method.
|
||||
*
|
||||
* The first template parameter must match the return type of the function, or
|
||||
* void if the function does not return a value. The remaining template parameters must
|
||||
* match the types of the function's parameters. If any type does not match, this
|
||||
* function returns NULL.
|
||||
*
|
||||
* The returned QxtBoundFunction will not have a parent. Assigning a parent using
|
||||
* QObject::setParent() is strongly recommended to avoid memory leaks.
|
||||
*/
|
||||
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10>
|
||||
QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QXT_IMPL_10ARGS(QGenericArgument))
|
||||
{
|
||||
// Make sure the template parameters make a function pointer equivalent to the one passed in
|
||||
if (funcPointer.typeName != typeid(typename qxt_cfunction_return<RETURN, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>::FUNCTION).name())
|
||||
{
|
||||
qWarning() << "QxtMetaObject::bind: parameter list mismatch, check template arguments";
|
||||
return 0;
|
||||
}
|
||||
|
||||
QGenericArgument* args[10] = { &p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9, &p10 };
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
if (args[i]->name() == 0) break; // done
|
||||
if (QByteArray(args[i]->name()) == "QxtBoundArgument")
|
||||
{
|
||||
Q_ASSERT_X((quintptr)(args[i]->data()) > 0 && (quintptr)(args[i]->data()) <= 10, "QXT_BIND", "invalid argument number");
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray types[10];
|
||||
types[0] = QxtMetaType<T1>::name();
|
||||
types[1] = QxtMetaType<T2>::name();
|
||||
types[2] = QxtMetaType<T3>::name();
|
||||
types[3] = QxtMetaType<T4>::name();
|
||||
types[4] = QxtMetaType<T5>::name();
|
||||
types[5] = QxtMetaType<T6>::name();
|
||||
types[6] = QxtMetaType<T7>::name();
|
||||
types[7] = QxtMetaType<T8>::name();
|
||||
types[8] = QxtMetaType<T9>::name();
|
||||
types[9] = QxtMetaType<T10>::name();
|
||||
|
||||
return new QxtBoundCFunction<RETURN, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(0, funcPointer, args, types);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \relates QxtMetaObject
|
||||
* \sa QxtMetaObject::connect
|
||||
* \sa qxtFuncPtr
|
||||
* \sa QxtBoundFunction
|
||||
*
|
||||
* Creates a binding to the provided C/C++ function using the provided parameter list.
|
||||
* Use the qxtFuncPtr function to wrap a bare function pointer for use in this function.
|
||||
* The type of each argument is deduced from the type of the QVariant. This function
|
||||
* cannot bind positional arguments; see the overload using QGenericArgument.
|
||||
*
|
||||
* The first template parameter must match the return type of the function, or
|
||||
* void if the function does not return a value. The remaining template parameters must
|
||||
* match the types of the function's parameters. If any type does not match, this
|
||||
* function returns NULL.
|
||||
*
|
||||
* The returned QxtBoundFunction will not have a parent. Assigning a parent using
|
||||
* QObject::setParent() is strongly recommended to avoid memory leaks.
|
||||
*/
|
||||
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10>
|
||||
QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QXT_IMPL_10ARGS(QVariant))
|
||||
{
|
||||
QVariant* args[10] = { &p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9, &p10 };
|
||||
return QxtMetaObject::bind<RETURN, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(funcPointer, QXT_VAR_ARG(1), QXT_VAR_ARG(2), QXT_VAR_ARG(3), QXT_VAR_ARG(4),
|
||||
QXT_VAR_ARG(5), QXT_VAR_ARG(6), QXT_VAR_ARG(7), QXT_VAR_ARG(8), QXT_VAR_ARG(9), QXT_VAR_ARG(10));
|
||||
}
|
||||
|
||||
// The following overloads exist because C++ doesn't support default parameters in function templates
|
||||
#ifndef QXT_DOXYGEN_RUN
|
||||
template <typename RETURN>
|
||||
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer)
|
||||
{
|
||||
return bind<RETURN, void, void, void, void, void, void, void, void, void, void>(funcPointer,
|
||||
QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument());
|
||||
}
|
||||
|
||||
template <typename RETURN, typename T1>
|
||||
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QGenericArgument p1)
|
||||
{
|
||||
return bind<RETURN, T1, void, void, void, void, void, void, void, void, void>(funcPointer,
|
||||
p1, QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument());
|
||||
}
|
||||
|
||||
template <typename RETURN, typename T1, typename T2>
|
||||
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QGenericArgument p1, QGenericArgument p2)
|
||||
{
|
||||
return bind<RETURN, T1, T2, void, void, void, void, void, void, void, void>(funcPointer,
|
||||
p1, p2, QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument());
|
||||
}
|
||||
|
||||
template <typename RETURN, typename T1, typename T2, typename T3>
|
||||
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QGenericArgument p1, QGenericArgument p2, QGenericArgument p3)
|
||||
{
|
||||
return bind<RETURN, T1, T2, T3, void, void, void, void, void, void, void>(funcPointer,
|
||||
p1, p2, p3, QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument());
|
||||
}
|
||||
|
||||
template <typename RETURN, typename T1, typename T2, typename T3, typename T4>
|
||||
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QGenericArgument p1, QGenericArgument p2, QGenericArgument p3, QGenericArgument p4)
|
||||
{
|
||||
return bind<RETURN, T1, T2, T3, T4, void, void, void, void, void, void>(funcPointer,
|
||||
p1, p2, p3, p4, QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument());
|
||||
}
|
||||
|
||||
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QGenericArgument p1, QGenericArgument p2, QGenericArgument p3, QGenericArgument p4, QGenericArgument p5)
|
||||
{
|
||||
return bind<RETURN, T1, T2, T3, T4, T5, void, void, void, void, void>(funcPointer,
|
||||
p1, p2, p3, p4, p5, QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument());
|
||||
}
|
||||
|
||||
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
||||
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QGenericArgument p1, QGenericArgument p2, QGenericArgument p3, QGenericArgument p4, QGenericArgument p5, QGenericArgument p6)
|
||||
{
|
||||
return bind<RETURN, T1, T2, T3, T4, T5, T6, void, void, void, void>(funcPointer,
|
||||
p1, p2, p3, p4, p5, p6, QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument());
|
||||
}
|
||||
|
||||
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
|
||||
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QGenericArgument p1, QGenericArgument p2, QGenericArgument p3, QGenericArgument p4, QGenericArgument p5, QGenericArgument p6, QGenericArgument p7)
|
||||
{
|
||||
return bind<RETURN, T1, T2, T3, T4, T5, T6, T7, void, void, void>(funcPointer,
|
||||
p1, p2, p3, p4, p5, p6, p7, QGenericArgument(), QGenericArgument(), QGenericArgument());
|
||||
}
|
||||
|
||||
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
||||
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QGenericArgument p1, QGenericArgument p2, QGenericArgument p3, QGenericArgument p4, QGenericArgument p5,
|
||||
QGenericArgument p6, QGenericArgument p7, QGenericArgument p8)
|
||||
{
|
||||
return bind<RETURN, T1, T2, T3, T4, T5, T6, T7, T8, void, void>(funcPointer, p1, p2, p3, p4, p5, p6, p7, p8, QGenericArgument(), QGenericArgument());
|
||||
}
|
||||
|
||||
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
|
||||
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QGenericArgument p1, QGenericArgument p2, QGenericArgument p3, QGenericArgument p4, QGenericArgument p5,
|
||||
QGenericArgument p6, QGenericArgument p7, QGenericArgument p8, QGenericArgument p9)
|
||||
{
|
||||
return bind<RETURN, T1, T2, T3, T4, T5, T6, T7, T8, T9, void>(funcPointer, p1, p2, p3, p4, p5, p6, p7, p8, p9, QGenericArgument());
|
||||
}
|
||||
|
||||
template <typename RETURN, typename T1>
|
||||
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QVariant p1)
|
||||
{
|
||||
return bind<RETURN, T1, void, void, void, void, void, void, void, void, void>(funcPointer, p1, QVariant(), QVariant(), QVariant(), QVariant(), QVariant(), QVariant(), QVariant(), QVariant(), QVariant());
|
||||
}
|
||||
|
||||
template <typename RETURN, typename T1, typename T2>
|
||||
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QVariant p1, QVariant p2)
|
||||
{
|
||||
return bind<RETURN, T1, T2, void, void, void, void, void, void, void, void>(funcPointer, p1, p2, QVariant(), QVariant(), QVariant(), QVariant(), QVariant(), QVariant(), QVariant(), QVariant());
|
||||
}
|
||||
|
||||
template <typename RETURN, typename T1, typename T2, typename T3>
|
||||
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QVariant p1, QVariant p2, QVariant p3)
|
||||
{
|
||||
return bind<RETURN, T1, T2, T3, void, void, void, void, void, void, void>(funcPointer, p1, p2, p3, QVariant(), QVariant(), QVariant(), QVariant(), QVariant(), QVariant(), QVariant());
|
||||
}
|
||||
|
||||
template <typename RETURN, typename T1, typename T2, typename T3, typename T4>
|
||||
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QVariant p1, QVariant p2, QVariant p3, QVariant p4)
|
||||
{
|
||||
return bind<RETURN, T1, T2, T3, T4, void, void, void, void, void, void>(funcPointer, p1, p2, p3, p4, QVariant(), QVariant(), QVariant(), QVariant(), QVariant(), QVariant());
|
||||
}
|
||||
|
||||
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QVariant p1, QVariant p2, QVariant p3, QVariant p4, QVariant p5)
|
||||
{
|
||||
return bind<RETURN, T1, T2, T3, T4, T5, void, void, void, void, void>(funcPointer, p1, p2, p3, p4, p5, QVariant(), QVariant(), QVariant(), QVariant(), QVariant());
|
||||
}
|
||||
|
||||
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
||||
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QVariant p1, QVariant p2, QVariant p3, QVariant p4, QVariant p5, QVariant p6)
|
||||
{
|
||||
return bind<RETURN, T1, T2, T3, T4, T5, T6, void, void, void, void>(funcPointer, p1, p2, p3, p4, p5, p6, QVariant(), QVariant(), QVariant(), QVariant());
|
||||
}
|
||||
|
||||
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
|
||||
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QVariant p1, QVariant p2, QVariant p3, QVariant p4, QVariant p5, QVariant p6, QVariant p7)
|
||||
{
|
||||
return bind<RETURN, T1, T2, T3, T4, T5, T6, T7, void, void, void>(funcPointer, p1, p2, p3, p4, p5, p6, p7, QVariant(), QVariant(), QVariant());
|
||||
}
|
||||
|
||||
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
||||
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QVariant p1, QVariant p2, QVariant p3, QVariant p4, QVariant p5, QVariant p6, QVariant p7, QVariant p8)
|
||||
{
|
||||
return bind<RETURN, T1, T2, T3, T4, T5, T6, T7, T8, void, void>(funcPointer, p1, p2, p3, p4, p5, p6, p7, p8, QVariant(), QVariant());
|
||||
}
|
||||
|
||||
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
|
||||
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QVariant p1, QVariant p2, QVariant p3, QVariant p4, QVariant p5, QVariant p6, QVariant p7, QVariant p8, QVariant p9)
|
||||
{
|
||||
return bind<RETURN, T1, T2, T3, T4, T5, T6, T7, T8, T9, void>(funcPointer, p1, p2, p3, p4, p5, p6, p7, p8, p9, QVariant());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
264
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtboundfunction.h
vendored
Normal file
264
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtboundfunction.h
vendored
Normal file
@@ -0,0 +1,264 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtCore module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QXTBOUNDFUNCTION_H
|
||||
#define QXTBOUNDFUNCTION_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QMetaObject>
|
||||
#include <QGenericArgument>
|
||||
#include <qxtmetaobject.h>
|
||||
#include <qxtnull.h>
|
||||
#include <QThread>
|
||||
#include <QtDebug>
|
||||
|
||||
/*!
|
||||
\class QxtBoundFunction
|
||||
|
||||
\inmodule QxtCore
|
||||
|
||||
\brief Binds parameters to a function call
|
||||
|
||||
* A bound function is very similar to what the C++ FAQ Lite refers to as "functionoids."
|
||||
* (http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.10)
|
||||
* It is similar in use to a function pointer, but allows any or all parameters to be
|
||||
* pre-filled with constant values. The remaining parameters are specified when the
|
||||
* function is invoked, for instance, by a Qt signal connection.
|
||||
*
|
||||
* By far, the most common expected use is to provide a parameter to a slot when the
|
||||
* signal doesn't have offer one. Many developers new to Qt try to write code like this:
|
||||
* \code
|
||||
* connect(button, SIGNAL(clicked()), lineEdit, SLOT(setText("Hello, world")));
|
||||
* \endcode
|
||||
* Experienced Qt developers will immediately spot the flaw here. The typical solution
|
||||
* is to create a short, one-line wrapper slot that invokes the desired function. Some
|
||||
* clever developers may even use QSignalMapper to handle slots that only need one
|
||||
* int or QString parameter.
|
||||
*
|
||||
* QxtBoundFunction enables the previous connect statement to be written like this:
|
||||
* \code
|
||||
* connect(button, SIGNAL(clicked()), QxtMetaObject::bind(lineEdit, SLOT(setText(QString)), Q_ARG(QString, "Hello, world!")));
|
||||
* \code
|
||||
* This accomplishes the same result without having to create a new slot, or worse,
|
||||
* an entire object, just to pass a constant value.
|
||||
*
|
||||
* Additionally, through the use of the QXT_BIND macro, parameters from the signal
|
||||
* can be rearranged, skipped, or passed alongside constant arguments provided
|
||||
* with the Q_ARG macro. This can be used to provide stateful callbacks to a
|
||||
* generic function, for example.
|
||||
*
|
||||
* Many kinds of functions can be bound. The most common binding applies to
|
||||
* Qt signals and slots, but standard C/C++ functions can be bound as well.
|
||||
* Future development may add the ability to bind to C++ member functions,
|
||||
* and developers can make custom QxtBoundFunction subclasses for even more
|
||||
* flexibility if necessary.
|
||||
*
|
||||
*
|
||||
*/
|
||||
class QXT_CORE_EXPORT QxtBoundFunction : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/*!
|
||||
* Invokes the bound function and returns a value.
|
||||
*
|
||||
* The template parameter should be the return type of the invoked function. This overload accepts
|
||||
* QVariant parameters and will guess the data type of each parameter based on the type of the QVariant.
|
||||
*/
|
||||
template <class T>
|
||||
inline QxtNullable<T> invoke(QXT_PROTO_10ARGS(QVariant))
|
||||
{
|
||||
if (!parent() || QThread::currentThread() == parent()->thread())
|
||||
return invoke<T>(Qt::DirectConnection, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
|
||||
#if QT_VERSION >= 0x040300
|
||||
return invoke<T>(Qt::BlockingQueuedConnection, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
|
||||
#else
|
||||
qWarning() << "QxtBoundFunction::invoke: Cannot return a value using a queued connection";
|
||||
return QxtNull();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* Invokes the bound function and returns a value.
|
||||
*
|
||||
* The template parameter should be the return type of the invoked function. This overload accepts
|
||||
* QGenericArgument parameters, expressed using the Q_ARG() macro.
|
||||
*/
|
||||
template <class T>
|
||||
QxtNullable<T> invoke(Qt::ConnectionType type, QVariant p1, QXT_PROTO_9ARGS(QVariant))
|
||||
{
|
||||
if (type == Qt::QueuedConnection)
|
||||
{
|
||||
qWarning() << "QxtBoundFunction::invoke: Cannot return a value using a queued connection";
|
||||
return QxtNull();
|
||||
}
|
||||
T retval;
|
||||
// I know this is a totally ugly function call
|
||||
if (invoke(type, QGenericReturnArgument(qVariantFromValue<T>(*reinterpret_cast<T*>(0)).typeName(), reinterpret_cast<void*>(&retval)),
|
||||
p1, p2, p3, p4, p5, p6, p7, p8, p9, p10))
|
||||
{
|
||||
return retval;
|
||||
}
|
||||
else
|
||||
{
|
||||
return QxtNull();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Invokes the bound function, discarding the return value.
|
||||
*
|
||||
* This overload accepts QVariant parameters and will guess the data type of each
|
||||
* parameter based on the type of the QVariant.
|
||||
*
|
||||
* This function returns true if the invocation was successful, otherwise it
|
||||
* returns false.
|
||||
*/
|
||||
inline bool invoke(QVariant p1, QXT_PROTO_9ARGS(QVariant))
|
||||
{
|
||||
return invoke(Qt::AutoConnection, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
|
||||
}
|
||||
/*!
|
||||
* Invokes the bound function, discarding the return value.
|
||||
*
|
||||
* This overload accepts QVariant parameters and will guess the data type of each
|
||||
* parameter based on the type of the QVariant. It also allows you to specify the
|
||||
* connection type, allowing the bound function to be invoked across threads using
|
||||
* the Qt event loop.
|
||||
*
|
||||
* This function returns true if the invocation was successful, otherwise it
|
||||
* returns false.
|
||||
*/
|
||||
bool invoke(Qt::ConnectionType, QVariant p1, QXT_PROTO_9ARGS(QVariant));
|
||||
|
||||
/*!
|
||||
* Invokes the bound function, discarding the return value.
|
||||
*
|
||||
* This overload accepts QGenericArgument parameters, expressed using the Q_ARG()
|
||||
* macro.
|
||||
*
|
||||
* This function returns true if the invocation was successful, otherwise it
|
||||
* returns false.
|
||||
*/
|
||||
inline bool invoke(QXT_PROTO_10ARGS(QGenericArgument))
|
||||
{
|
||||
return invoke(Qt::AutoConnection, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
|
||||
}
|
||||
/*!
|
||||
* Invokes the bound function, discarding the return value.
|
||||
*
|
||||
* This overload accepts QGenericArgument parameters, expressed using the Q_ARG()
|
||||
* macro. It also allows you to specify the connection type, allowing the bound
|
||||
* function to be invoked across threads using the Qt event loop.
|
||||
*
|
||||
* This function returns true if the invocation was successful, otherwise it
|
||||
* returns false.
|
||||
*/
|
||||
inline bool invoke(Qt::ConnectionType type, QXT_PROTO_10ARGS(QGenericArgument))
|
||||
{
|
||||
return invoke(type, QGenericReturnArgument(), p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Invokes the bound function and assigns the return value to a parameter passed by reference.
|
||||
*
|
||||
* Use the Q_RETURN_ARG() macro to pass a reference to an assignable object of the function's
|
||||
* return type. When the function completes, its return value will be stored in that object.
|
||||
*
|
||||
* This overload accepts QVariant parameters and will guess the data type of each
|
||||
* parameter based on the type of the QVariant.
|
||||
*
|
||||
* This function returns true if the invocation was successful, otherwise it
|
||||
* returns false.
|
||||
*/
|
||||
inline bool invoke(QGenericReturnArgument returnValue, QVariant p1, QXT_PROTO_9ARGS(QVariant))
|
||||
{
|
||||
return invoke(Qt::AutoConnection, returnValue, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
|
||||
}
|
||||
/*!
|
||||
* Invokes the bound function and assigns the return value to a parameter passed by reference.
|
||||
*
|
||||
* Use the Q_RETURN_ARG() macro to pass a reference to an assignable object of the function's
|
||||
* return type. When the function completes, its return value will be stored in that object.
|
||||
*
|
||||
* This overload accepts QVariant parameters and will guess the data type of each
|
||||
* parameter based on the type of the QVariant. It also allows you to specify the
|
||||
* connection type, allowing the bound function to be invoked across threads using
|
||||
* the Qt event loop.
|
||||
*
|
||||
* This function returns true if the invocation was successful, otherwise it
|
||||
* returns false.
|
||||
*/
|
||||
bool invoke(Qt::ConnectionType type, QGenericReturnArgument returnValue, QVariant p1, QXT_PROTO_9ARGS(QVariant));
|
||||
|
||||
/*!
|
||||
* Invokes the bound function and assigns the return value to a parameter passed by reference.
|
||||
*
|
||||
* Use the Q_RETURN_ARG() macro to pass a reference to an assignable object of the function's
|
||||
* return type. When the function completes, its return value will be stored in that object.
|
||||
*
|
||||
* This overload accepts QGenericArgument parameters, expressed using the Q_ARG()
|
||||
* macro.
|
||||
*
|
||||
* This function returns true if the invocation was successful, otherwise it
|
||||
* returns false.
|
||||
*/
|
||||
inline bool invoke(QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument))
|
||||
{
|
||||
return invoke(Qt::AutoConnection, returnValue, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
|
||||
}
|
||||
/*!
|
||||
* Invokes the bound function and assigns the return value to a parameter passed by reference.
|
||||
*
|
||||
* Use the Q_RETURN_ARG() macro to pass a reference to an assignable object of the function's
|
||||
* return type. When the function completes, its return value will be stored in that object.
|
||||
*
|
||||
* This overload accepts QGenericArgument parameters, expressed using the Q_ARG()
|
||||
* macro. It also allows you to specify the connection type, allowing the bound
|
||||
* function to be invoked across threads using the Qt event loop.
|
||||
*
|
||||
* This function returns true if the invocation was successful, otherwise it
|
||||
* returns false.
|
||||
*/
|
||||
bool invoke(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument));
|
||||
|
||||
protected:
|
||||
#ifndef QXT_DOXYGEN_RUN
|
||||
QxtBoundFunction(QObject* parent = 0);
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Performs the work of invoking the bound function.
|
||||
*
|
||||
* This function is pure virtual. The various QxtMetaObject::bind() functions return opaque subclasses
|
||||
* of QxtBoundFunction. If you wish to create a new kind of bound function, reimplement this function to
|
||||
* perform the invocation and assign the function's return value, if any, to the returnValue parameter.
|
||||
*
|
||||
* This function should return true if the invocation is successful and false if an error occurs.
|
||||
*/
|
||||
virtual bool invokeImpl(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument)) = 0;
|
||||
};
|
||||
|
||||
#endif
|
61
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtboundfunctionbase.h
vendored
Normal file
61
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtboundfunctionbase.h
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtCore module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
// This file exists for the convenience of QxtBoundCFunction.
|
||||
// It is not part of the public API and is subject to change.
|
||||
//
|
||||
// We mean it.
|
||||
|
||||
#ifndef QXTBOUNDFUNCTIONBASE_H
|
||||
#define QXTBOUNDFUNCTIONBASE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QMetaObject>
|
||||
#include <QGenericArgument>
|
||||
#include <qxtmetaobject.h>
|
||||
#include <qxtboundfunction.h>
|
||||
|
||||
#ifndef QXT_DOXYGEN_RUN
|
||||
|
||||
#define QXT_10_UNUSED Q_UNUSED(p1) Q_UNUSED(p2) Q_UNUSED(p3) Q_UNUSED(p4) Q_UNUSED(p5) Q_UNUSED(p6) Q_UNUSED(p7) Q_UNUSED(p8) Q_UNUSED(p9) Q_UNUSED(p10)
|
||||
|
||||
class QXT_CORE_EXPORT QxtBoundFunctionBase : public QxtBoundFunction
|
||||
{
|
||||
public:
|
||||
QByteArray bindTypes[10];
|
||||
QGenericArgument arg[10], p[10];
|
||||
void* data[10];
|
||||
|
||||
QxtBoundFunctionBase(QObject* parent, QGenericArgument* params[10], QByteArray types[10]);
|
||||
virtual ~QxtBoundFunctionBase();
|
||||
|
||||
int qt_metacall(QMetaObject::Call _c, int _id, void **_a);
|
||||
bool invokeBase(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument));
|
||||
};
|
||||
|
||||
#define QXT_ARG(i) ((argCount>i)?QGenericArgument(p ## i .typeName(), p ## i .constData()):QGenericArgument())
|
||||
#define QXT_VAR_ARG(i) (p ## i .isValid())?QGenericArgument(p ## i .typeName(), p ## i .constData()):QGenericArgument()
|
||||
#endif
|
||||
#endif
|
241
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtglobal.cpp
vendored
Normal file
241
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtglobal.cpp
vendored
Normal file
@@ -0,0 +1,241 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtCore module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qxtglobal.h"
|
||||
|
||||
/*!
|
||||
\headerfile <QxtGlobal>
|
||||
\title Global Qxt Declarations
|
||||
\inmodule QxtCore
|
||||
|
||||
\brief The <QxtGlobal> header provides basic declarations and
|
||||
is included by all other Qxt headers.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\macro QXT_VERSION
|
||||
\relates <QxtGlobal>
|
||||
|
||||
This macro expands a numeric value of the form 0xMMNNPP (MM =
|
||||
major, NN = minor, PP = patch) that specifies Qxt's version
|
||||
number. For example, if you compile your application against Qxt
|
||||
0.4.0, the QXT_VERSION macro will expand to 0x000400.
|
||||
|
||||
You can use QXT_VERSION to use the latest Qt features where
|
||||
available. For example:
|
||||
\code
|
||||
#if QXT_VERSION >= 0x000400
|
||||
qxtTabWidget->setTabMovementMode(QxtTabWidget::InPlaceMovement);
|
||||
#endif
|
||||
\endcode
|
||||
|
||||
\sa QXT_VERSION_STR, qxtVersion()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\macro QXT_VERSION_STR
|
||||
\relates <QxtGlobal>
|
||||
|
||||
This macro expands to a string that specifies Qxt's version number
|
||||
(for example, "0.4.0"). This is the version against which the
|
||||
application is compiled.
|
||||
|
||||
\sa qxtVersion(), QXT_VERSION
|
||||
*/
|
||||
|
||||
/*!
|
||||
\relates <QxtGlobal>
|
||||
|
||||
Returns the version number of Qxt at run-time as a string (for
|
||||
example, "0.4.0"). This may be a different version than the
|
||||
version the application was compiled against.
|
||||
|
||||
\sa QXT_VERSION_STR
|
||||
*/
|
||||
const char* qxtVersion()
|
||||
{
|
||||
return QXT_VERSION_STR;
|
||||
}
|
||||
|
||||
/*!
|
||||
\headerfile <QxtPimpl>
|
||||
\title The Qxt private implementation
|
||||
\inmodule QxtCore
|
||||
|
||||
\brief The <QxtPimpl> header provides tools for hiding
|
||||
details of a class.
|
||||
|
||||
Application code generally doesn't have to be concerned about hiding its
|
||||
implementation details, but when writing library code it is important to
|
||||
maintain a constant interface, both source and binary. Maintaining a constant
|
||||
source interface is easy enough, but keeping the binary interface constant
|
||||
means moving implementation details into a private class. The PIMPL, or
|
||||
d-pointer, idiom is a common method of implementing this separation. QxtPimpl
|
||||
offers a convenient way to connect the public and private sides of your class.
|
||||
|
||||
\section1 Getting Started
|
||||
Before you declare the public class, you need to make a forward declaration
|
||||
of the private class. The private class must have the same name as the public
|
||||
class, followed by the word Private. For example, a class named MyTest would
|
||||
declare the private class with:
|
||||
\code
|
||||
class MyTestPrivate;
|
||||
\endcode
|
||||
|
||||
\section1 The Public Class
|
||||
Generally, you shouldn't keep any data members in the public class without a
|
||||
good reason. Functions that are part of the public interface should be declared
|
||||
in the public class, and functions that need to be available to subclasses (for
|
||||
calling or overriding) should be in the protected section of the public class.
|
||||
To connect the private class to the public class, include the
|
||||
QXT_DECLARE_PRIVATE macro in the private section of the public class. In the
|
||||
example above, the private class is connected as follows:
|
||||
\code
|
||||
private:
|
||||
QXT_DECLARE_PRIVATE(MyTest)
|
||||
\endcode
|
||||
|
||||
Additionally, you must include the QXT_INIT_PRIVATE macro in the public class's
|
||||
constructor. Continuing with the MyTest example, your constructor might look
|
||||
like this:
|
||||
\code
|
||||
MyTest::MyTest() {
|
||||
// initialization
|
||||
QXT_INIT_PRIVATE(MyTest);
|
||||
}
|
||||
\endcode
|
||||
|
||||
\section1 The Private Class
|
||||
As mentioned above, data members should usually be kept in the private class.
|
||||
This allows the memory layout of the private class to change without breaking
|
||||
binary compatibility for the public class. Functions that exist only as
|
||||
implementation details, or functions that need access to private data members,
|
||||
should be implemented here.
|
||||
|
||||
To define the private class, inherit from the template QxtPrivate class, and
|
||||
include the QXT_DECLARE_PUBLIC macro in its public section. The template
|
||||
parameter should be the name of the public class. For example:
|
||||
\code
|
||||
class MyTestPrivate : public QxtPrivate<MyTest> {
|
||||
public:
|
||||
MyTestPrivate();
|
||||
QXT_DECLARE_PUBLIC(MyTest)
|
||||
};
|
||||
\endcode
|
||||
|
||||
\section1 Accessing Private Members
|
||||
Use the qxt_d() function (actually a function-like object) from functions in
|
||||
the public class to access the private class. Similarly, functions in the
|
||||
private class can invoke functions in the public class by using the qxt_p()
|
||||
function (this one's actually a function).
|
||||
|
||||
For example, assume that MyTest has methods named getFoobar and doBaz(),
|
||||
and MyTestPrivate has a member named foobar and a method named doQuux().
|
||||
The code might resemble this example:
|
||||
\code
|
||||
int MyTest::getFoobar() {
|
||||
return qxt_d().foobar;
|
||||
}
|
||||
|
||||
void MyTestPrivate::doQuux() {
|
||||
qxt_p().doBaz(foobar);
|
||||
}
|
||||
\endcode
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \macro QXT_DECLARE_PRIVATE(PUB)
|
||||
* \relates <QxtPimpl>
|
||||
* Declares that a public class has a related private class.
|
||||
*
|
||||
* This shuold be put in the private section of the public class. The parameter is the name of the public class.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \macro QXT_DECLARE_PUBLIC(PUB)
|
||||
* \relates <QxtPimpl>
|
||||
* Declares that a private class has a related public class.
|
||||
*
|
||||
* This may be put anywhere in the declaration of the private class. The parameter is the name of the public class.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \macro QXT_INIT_PRIVATE(PUB)
|
||||
* \relates <QxtPimpl>
|
||||
* Initializes resources owned by the private class.
|
||||
*
|
||||
* This should be called from the public class's constructor,
|
||||
* before qxt_d() is used for the first time. The parameter is the name of the public class.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \macro QXT_D(PUB)
|
||||
* \relates <QxtPimpl>
|
||||
* Returns a reference in the current scope named "d" to the private class.
|
||||
*
|
||||
* This function is only available in a class using \a QXT_DECLARE_PRIVATE.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \macro QXT_P(PUB)
|
||||
* \relates <QxtPimpl>
|
||||
* Creates a reference in the current scope named "q" to the public class.
|
||||
*
|
||||
* This macro only works in a class using \a QXT_DECLARE_PUBLIC.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \fn QxtPrivate<PUB>& PUB::qxt_d()
|
||||
* \relates <QxtPimpl>
|
||||
* Returns a reference to the private class.
|
||||
*
|
||||
* This function is only available in a class using \a QXT_DECLARE_PRIVATE.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \fn const QxtPrivate<PUB>& PUB::qxt_d() const
|
||||
* \relates <QxtPimpl>
|
||||
* Returns a const reference to the private class.
|
||||
*
|
||||
* This function is only available in a class using \a QXT_DECLARE_PRIVATE.
|
||||
* This overload will be automatically used in const functions.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \fn PUB& QxtPrivate::qxt_p()
|
||||
* \relates <QxtPimpl>
|
||||
* Returns a reference to the public class.
|
||||
*
|
||||
* This function is only available in a class using \a QXT_DECLARE_PUBLIC.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \fn const PUB& QxtPrivate::qxt_p() const
|
||||
* \relates <QxtPimpl>
|
||||
* Returns a const reference to the public class.
|
||||
*
|
||||
* This function is only available in a class using \a QXT_DECLARE_PUBLIC.
|
||||
* This overload will be automatically used in const functions.
|
||||
*/
|
207
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtglobal.h
vendored
Normal file
207
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtglobal.h
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtCore module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QXTGLOBAL_H
|
||||
#define QXTGLOBAL_H
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
#define QXT_VERSION 0x000600
|
||||
#define QXT_VERSION_STR "0.6.0"
|
||||
|
||||
//--------------------------global macros------------------------------
|
||||
|
||||
#ifndef QXT_NO_MACROS
|
||||
|
||||
#endif // QXT_NO_MACROS
|
||||
|
||||
//--------------------------export macros------------------------------
|
||||
|
||||
#define QXT_DLLEXPORT DO_NOT_USE_THIS_ANYMORE
|
||||
|
||||
#if !defined(QXT_STATIC)
|
||||
# if defined(BUILD_QXT_CORE)
|
||||
# define QXT_CORE_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define QXT_CORE_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
#else
|
||||
# define QXT_CORE_EXPORT
|
||||
#endif // BUILD_QXT_CORE
|
||||
|
||||
#if !defined(QXT_STATIC)
|
||||
# if defined(BUILD_QXT_GUI)
|
||||
# define QXT_GUI_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define QXT_GUI_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
#else
|
||||
# define QXT_GUI_EXPORT
|
||||
#endif // BUILD_QXT_GUI
|
||||
|
||||
#if !defined(QXT_STATIC)
|
||||
# if defined(BUILD_QXT_NETWORK)
|
||||
# define QXT_NETWORK_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define QXT_NETWORK_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
#else
|
||||
# define QXT_NETWORK_EXPORT
|
||||
#endif // BUILD_QXT_NETWORK
|
||||
|
||||
#if !defined(QXT_STATIC)
|
||||
# if defined(BUILD_QXT_SQL)
|
||||
# define QXT_SQL_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define QXT_SQL_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
#else
|
||||
# define QXT_SQL_EXPORT
|
||||
#endif // BUILD_QXT_SQL
|
||||
|
||||
#if !defined(QXT_STATIC)
|
||||
# if defined(BUILD_QXT_WEB)
|
||||
# define QXT_WEB_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define QXT_WEB_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
#else
|
||||
# define QXT_WEB_EXPORT
|
||||
#endif // BUILD_QXT_WEB
|
||||
|
||||
#if !defined(QXT_STATIC)
|
||||
# if defined(BUILD_QXT_BERKELEY)
|
||||
# define QXT_BERKELEY_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define QXT_BERKELEY_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
#else
|
||||
# define QXT_BERKELEY_EXPORT
|
||||
#endif // BUILD_QXT_BERKELEY
|
||||
|
||||
#if !defined(QXT_STATIC)
|
||||
# if defined(BUILD_QXT_ZEROCONF)
|
||||
# define QXT_ZEROCONF_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define QXT_ZEROCONF_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
#else
|
||||
# define QXT_ZEROCONF_EXPORT
|
||||
#endif // QXT_ZEROCONF_EXPORT
|
||||
|
||||
#if defined BUILD_QXT_CORE || defined BUILD_QXT_GUI || defined BUILD_QXT_SQL || defined BUILD_QXT_NETWORK || defined BUILD_QXT_WEB || defined BUILD_QXT_BERKELEY || defined BUILD_QXT_ZEROCONF
|
||||
# define BUILD_QXT
|
||||
#endif
|
||||
|
||||
QXT_CORE_EXPORT const char* qxtVersion();
|
||||
|
||||
#ifndef QT_BEGIN_NAMESPACE
|
||||
#define QT_BEGIN_NAMESPACE
|
||||
#endif
|
||||
|
||||
#ifndef QT_END_NAMESPACE
|
||||
#define QT_END_NAMESPACE
|
||||
#endif
|
||||
|
||||
#ifndef QT_FORWARD_DECLARE_CLASS
|
||||
#define QT_FORWARD_DECLARE_CLASS(Class) class Class;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
** This file is derived from code bearing the following notice:
|
||||
** The sole author of this file, Adam Higerd, has explicitly disclaimed all
|
||||
** copyright interest and protection for the content within. This file has
|
||||
** been placed in the public domain according to United States copyright
|
||||
** statute and case law. In jurisdictions where this public domain dedication
|
||||
** is not legally recognized, anyone who receives a copy of this file is
|
||||
** permitted to use, modify, duplicate, and redistribute this file, in whole
|
||||
** or in part, with no restrictions or conditions. In these jurisdictions,
|
||||
** this file shall be copyright (C) 2006-2008 by Adam Higerd.
|
||||
****************************************************************************/
|
||||
|
||||
#define QXT_DECLARE_PRIVATE(PUB) friend class PUB##Private; QxtPrivateInterface<PUB, PUB##Private> qxt_d;
|
||||
#define QXT_DECLARE_PUBLIC(PUB) friend class PUB;
|
||||
#define QXT_INIT_PRIVATE(PUB) qxt_d.setPublic(this);
|
||||
#define QXT_D(PUB) PUB##Private& d = qxt_d()
|
||||
#define QXT_P(PUB) PUB& p = qxt_p()
|
||||
|
||||
template <typename PUB>
|
||||
class QxtPrivate
|
||||
{
|
||||
public:
|
||||
virtual ~QxtPrivate()
|
||||
{}
|
||||
inline void QXT_setPublic(PUB* pub)
|
||||
{
|
||||
qxt_p_ptr = pub;
|
||||
}
|
||||
|
||||
protected:
|
||||
inline PUB& qxt_p()
|
||||
{
|
||||
return *qxt_p_ptr;
|
||||
}
|
||||
inline const PUB& qxt_p() const
|
||||
{
|
||||
return *qxt_p_ptr;
|
||||
}
|
||||
|
||||
private:
|
||||
PUB* qxt_p_ptr;
|
||||
};
|
||||
|
||||
template <typename PUB, typename PVT>
|
||||
class QxtPrivateInterface
|
||||
{
|
||||
friend class QxtPrivate<PUB>;
|
||||
public:
|
||||
QxtPrivateInterface()
|
||||
{
|
||||
pvt = new PVT;
|
||||
}
|
||||
~QxtPrivateInterface()
|
||||
{
|
||||
delete pvt;
|
||||
}
|
||||
|
||||
inline void setPublic(PUB* pub)
|
||||
{
|
||||
pvt->QXT_setPublic(pub);
|
||||
}
|
||||
inline PVT& operator()()
|
||||
{
|
||||
return *static_cast<PVT*>(pvt);
|
||||
}
|
||||
inline const PVT& operator()() const
|
||||
{
|
||||
return *static_cast<PVT*>(pvt);
|
||||
}
|
||||
private:
|
||||
QxtPrivateInterface(const QxtPrivateInterface&) { }
|
||||
QxtPrivateInterface& operator=(const QxtPrivateInterface&) { }
|
||||
QxtPrivate<PUB>* pvt;
|
||||
};
|
||||
|
||||
#endif // QXT_GLOBAL
|
156
thirdparty/qxt/qxtweb-standalone/qxtweb/qxthtmltemplate.cpp
vendored
Normal file
156
thirdparty/qxt/qxtweb-standalone/qxtweb/qxthtmltemplate.cpp
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtWeb module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\class QxtHtmlTemplate
|
||||
\inmodule QxtWeb
|
||||
\brief The QxtHtmlTemplate class provides a basic HTML template engine
|
||||
|
||||
open a file containing html code and php style variables.
|
||||
use the square bracket operators to assign content for a variable
|
||||
|
||||
\code
|
||||
QxtHtmlTemplate index;
|
||||
if(!index.open)
|
||||
return 404;
|
||||
index["content"]="hello world";
|
||||
echo()<<index.render();
|
||||
\endcode
|
||||
the realatet html code would look like:
|
||||
\code
|
||||
<html>
|
||||
<head>
|
||||
<title>Test Page</title>
|
||||
</head>
|
||||
<?=content?>
|
||||
</html>
|
||||
\endcode
|
||||
|
||||
funny storry: whe are using this class to make our documentation (eat your own dogfood, you know ;).
|
||||
but when we where parsing exactly this file you read right now the first time, QxtHtmlTemplate got stuck in an infinite loop. guess why. becouse of that example above :D
|
||||
So be warned: when you assign content to a variable that contains the variable name itself, render() will never return.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QxtHtmlTemplate::open(const QString& filename)
|
||||
Opens \a filename. Returns \c true on success and \c false on failure.
|
||||
Note that it will also return false for an empty html file.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QString QxtHtmlTemplate::render() const
|
||||
Uses the variables you set and renders the opened file.
|
||||
returns an empty string on failure.
|
||||
Does NOT take care of not assigned variables, they will remain in the returned string
|
||||
*/
|
||||
|
||||
#include "qxthtmltemplate.h"
|
||||
#include <QFile>
|
||||
#include <QStringList>
|
||||
|
||||
/*!
|
||||
Constructs a new QxtHtmlTemplate.
|
||||
*/
|
||||
QxtHtmlTemplate::QxtHtmlTemplate() : QMap<QString, QString>()
|
||||
{}
|
||||
|
||||
/*!
|
||||
Loads data \a d.
|
||||
*/
|
||||
void QxtHtmlTemplate::load(const QString& d)
|
||||
{
|
||||
data = d;
|
||||
}
|
||||
|
||||
bool QxtHtmlTemplate::open(const QString& filename)
|
||||
{
|
||||
QFile f(filename);
|
||||
f.open(QIODevice::ReadOnly);
|
||||
data = QString::fromLocal8Bit(f.readAll());
|
||||
f.close();
|
||||
if (data.isEmpty())
|
||||
{
|
||||
qWarning("QxtHtmlTemplate::open(\"%s\") empty or nonexistent", qPrintable(filename));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QString QxtHtmlTemplate::render() const
|
||||
{
|
||||
///try to preserve indention by parsing char by char and saving the last non-space character
|
||||
|
||||
|
||||
QString output = data;
|
||||
int lastnewline = 0;
|
||||
|
||||
|
||||
for (int i = 0;i < output.count();i++)
|
||||
{
|
||||
if (output.at(i) == '\n')
|
||||
{
|
||||
lastnewline = i;
|
||||
}
|
||||
|
||||
if (output.at(i) == '<' && output.at(i + 1) == '?' && output.at(i + 2) == '=')
|
||||
{
|
||||
int j = i + 3;
|
||||
QString var;
|
||||
|
||||
for (int jj = j;jj < output.count();jj++)
|
||||
{
|
||||
if (output.at(jj) == '?' && output.at(jj + 1) == '>')
|
||||
{
|
||||
j = jj;
|
||||
break;
|
||||
}
|
||||
var += output.at(jj);
|
||||
}
|
||||
|
||||
|
||||
if (j == i)
|
||||
{
|
||||
qWarning("QxtHtmlTemplate::render() unterminated <?= ");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (!contains(var))
|
||||
{
|
||||
qWarning("QxtHtmlTemplate::render() unused variable \"%s\"", qPrintable(var));
|
||||
continue;
|
||||
}
|
||||
output.replace(i, j - i + 2, QString(value(var)).replace('\n', '\n' + QString(i - lastnewline - 1, QChar(' '))));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
48
thirdparty/qxt/qxtweb-standalone/qxtweb/qxthtmltemplate.h
vendored
Normal file
48
thirdparty/qxt/qxtweb-standalone/qxtweb/qxthtmltemplate.h
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtWeb module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QXTHTMLTEMPLATE_H
|
||||
#define QXTHTMLTEMPLATE_H
|
||||
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
#include <QHash>
|
||||
#include <qxtglobal.h>
|
||||
|
||||
class QXT_WEB_EXPORT QxtHtmlTemplate : public QMap<QString, QString>
|
||||
{
|
||||
public:
|
||||
QxtHtmlTemplate();
|
||||
bool open(const QString& filename);
|
||||
void load(const QString& data);
|
||||
|
||||
QString render() const;
|
||||
|
||||
private:
|
||||
QString data;
|
||||
};
|
||||
|
||||
#endif // QXTHTMLTEMPLATE_H
|
||||
|
125
thirdparty/qxt/qxtweb-standalone/qxtweb/qxthttpserverconnector.cpp
vendored
Normal file
125
thirdparty/qxt/qxtweb-standalone/qxtweb/qxthttpserverconnector.cpp
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtWeb module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\class QxtHttpServerConnector
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtHttpServerConnector class provides a built-in HTTP server for QxtHttpSessionManager
|
||||
|
||||
QxtHttpSessionManager does the work of managing sessions and state for the
|
||||
otherwise stateless HTTP protocol, but it relies on QxtAbstractHttpConnector
|
||||
subclasses to implement the protocol used to communicate with the web server.
|
||||
|
||||
QxtHttpServerConnector implements a complete HTTP server internally and does
|
||||
not require an external web server to function. However, it provides very
|
||||
little control over the behavior of the web server and may not suitable for
|
||||
high traffic scenarios or virtual hosting configurations.
|
||||
|
||||
\sa QxtHttpSessionManager
|
||||
*/
|
||||
#include "qxthttpsessionmanager.h"
|
||||
#include "qxtwebevent.h"
|
||||
#include <QTcpServer>
|
||||
#include <QHash>
|
||||
#include <QTcpSocket>
|
||||
#include <QString>
|
||||
|
||||
#ifndef QXT_DOXYGEN_RUN
|
||||
class QxtHttpServerConnectorPrivate : public QxtPrivate<QxtHttpServerConnector>
|
||||
{
|
||||
public:
|
||||
QTcpServer* server;
|
||||
};
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Creates a QxtHttpServerConnector with the given \a parent.
|
||||
*/
|
||||
QxtHttpServerConnector::QxtHttpServerConnector(QObject* parent) : QxtAbstractHttpConnector(parent)
|
||||
{
|
||||
QXT_INIT_PRIVATE(QxtHttpServerConnector);
|
||||
qxt_d().server = new QTcpServer(this);
|
||||
QObject::connect(qxt_d().server, SIGNAL(newConnection()), this, SLOT(acceptConnection()));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
bool QxtHttpServerConnector::listen(const QHostAddress& iface, quint16 port)
|
||||
{
|
||||
return qxt_d().server->listen(iface, port);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void QxtHttpServerConnector::acceptConnection()
|
||||
{
|
||||
QTcpSocket* socket = qxt_d().server->nextPendingConnection();
|
||||
addConnection(socket);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
bool QxtHttpServerConnector::canParseRequest(const QByteArray& buffer)
|
||||
{
|
||||
if (buffer.indexOf("\r\n\r\n") >= 0) return true; // 1.0+
|
||||
if (buffer.indexOf("\r\n") >= 0 && buffer.indexOf("HTTP/") == -1) return true; // 0.9
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
QHttpRequestHeader QxtHttpServerConnector::parseRequest(QByteArray& buffer)
|
||||
{
|
||||
int pos = buffer.indexOf("\r\n\r\n"), endpos = pos + 3;
|
||||
if (pos == -1)
|
||||
{
|
||||
pos = buffer.indexOf("\r\n"); // 0.9
|
||||
endpos = pos + 1;
|
||||
}
|
||||
|
||||
QHttpRequestHeader header(QString::fromUtf8(buffer.left(endpos)));
|
||||
QByteArray firstLine = buffer.left(buffer.indexOf('\r'));
|
||||
if (firstLine.indexOf("HTTP/") == -1)
|
||||
{
|
||||
header.setRequest(header.method(), header.path(), 0, 9);
|
||||
}
|
||||
buffer.remove(0, endpos + 1);
|
||||
return header;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
void QxtHttpServerConnector::writeHeaders(QIODevice* device, const QHttpResponseHeader& header)
|
||||
{
|
||||
if (header.majorVersion() == 0) return; // 0.9 doesn't have headers
|
||||
device->write(header.toString().toUtf8());
|
||||
}
|
700
thirdparty/qxt/qxtweb-standalone/qxtweb/qxthttpsessionmanager.cpp
vendored
Normal file
700
thirdparty/qxt/qxtweb-standalone/qxtweb/qxthttpsessionmanager.cpp
vendored
Normal file
@@ -0,0 +1,700 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtWeb module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\class QxtHttpSessionManager
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtHttpSessionManager class provides a session manager for HTTP-based protocols
|
||||
|
||||
QxtHttpSessionManager is a QxtWeb session manager that adds session management
|
||||
support to the normally stateless HTTP model.
|
||||
|
||||
In addition to session management, QxtHttpSessionManager also supports a
|
||||
static service, which can serve content that does not require session management,
|
||||
such as static web pages. The static service is also used to respond to HTTP/0.9
|
||||
clients that do not support cookies and HTTP/1.0 and HTTP/1.1 clients that are
|
||||
rejecting cookies. If no static service is provided, these clients will only
|
||||
see an "Internal Configuration Error", so it is recommended to supply a static
|
||||
service, even one that only returns a more useful error message.
|
||||
|
||||
QxtHttpSessionManager attempts to be thread-safe in accepting connections and
|
||||
posting events. It is reentrant for all other functionality.
|
||||
|
||||
\sa QxtAbstractWebService
|
||||
*/
|
||||
|
||||
#include "qxthttpsessionmanager.h"
|
||||
#include "qxtwebevent.h"
|
||||
#include "qxtwebcontent.h"
|
||||
#include "qxtabstractwebservice.h"
|
||||
#include <qxtboundfunction.h>
|
||||
#include <QMutex>
|
||||
#include <QList>
|
||||
#include <QUuid>
|
||||
#include <QIODevice>
|
||||
#include <QByteArray>
|
||||
#include <QPair>
|
||||
#include <QMetaObject>
|
||||
#include <QThread>
|
||||
#include <qxtmetaobject.h>
|
||||
#include <QTcpSocket>
|
||||
|
||||
#ifndef QXT_DOXYGEN_RUN
|
||||
class QxtHttpSessionManagerPrivate : public QxtPrivate<QxtHttpSessionManager>
|
||||
{
|
||||
public:
|
||||
struct ConnectionState
|
||||
{
|
||||
QxtBoundFunction* onBytesWritten;
|
||||
bool readyRead;
|
||||
bool finishedTransfer;
|
||||
bool keepAlive;
|
||||
bool streaming;
|
||||
int httpMajorVersion;
|
||||
int httpMinorVersion;
|
||||
int sessionID;
|
||||
};
|
||||
|
||||
QxtHttpSessionManagerPrivate() : iface(QHostAddress::Any), port(80), sessionCookieName("sessionID"), connector(0), staticService(0), autoCreateSession(true),
|
||||
eventLock(QMutex::Recursive), sessionLock(QMutex::Recursive) {}
|
||||
QXT_DECLARE_PUBLIC(QxtHttpSessionManager)
|
||||
|
||||
QHostAddress iface;
|
||||
quint16 port;
|
||||
QByteArray sessionCookieName;
|
||||
QxtAbstractHttpConnector* connector;
|
||||
QxtAbstractWebService* staticService;
|
||||
bool autoCreateSession;
|
||||
|
||||
QMutex eventLock;
|
||||
QList<QxtWebEvent*> eventQueue;
|
||||
|
||||
QMutex sessionLock;
|
||||
QHash<QUuid, int> sessionKeys; // sessionKey->sessionID
|
||||
QHash<QIODevice*, ConnectionState> connectionState; // connection->state
|
||||
|
||||
Qt::HANDLE mainThread;
|
||||
};
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Constructs a new QxtHttpSessionManager with the specified \a parent.
|
||||
*/
|
||||
QxtHttpSessionManager::QxtHttpSessionManager(QObject* parent) : QxtAbstractWebSessionManager(parent)
|
||||
{
|
||||
QXT_INIT_PRIVATE(QxtHttpSessionManager);
|
||||
qxt_d().mainThread = QThread::currentThreadId();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the interface on which the session manager will listen for incoming connections.
|
||||
* \sa setInterface
|
||||
*/
|
||||
QHostAddress QxtHttpSessionManager::listenInterface() const
|
||||
{
|
||||
return qxt_d().iface;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Sets the interface \a iface on which the session manager will listen for incoming
|
||||
* connections.
|
||||
*
|
||||
* The default value is QHostAddress::Any, which will cause the session manager
|
||||
* to listen on all network interfaces.
|
||||
*
|
||||
* \sa QxtAbstractHttpConnector::listen
|
||||
*/
|
||||
void QxtHttpSessionManager::setListenInterface(const QHostAddress& iface)
|
||||
{
|
||||
qxt_d().iface = iface;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the port on which the session manager will listen for incoming connections.
|
||||
* \sa setInterface
|
||||
*/
|
||||
quint16 QxtHttpSessionManager::port() const
|
||||
{
|
||||
return qxt_d().port;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Sets the \a port on which the session manager will listen for incoming connections.
|
||||
*
|
||||
* The default value is to listen on port 80. This is an acceptable value when
|
||||
* using QxtHttpServerConnector, but it is not likely to be desirable for other
|
||||
* connectors.
|
||||
*
|
||||
* \sa port
|
||||
*/
|
||||
void QxtHttpSessionManager::setPort(quint16 port)
|
||||
{
|
||||
qxt_d().port = port;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
bool QxtHttpSessionManager::start()
|
||||
{
|
||||
Q_ASSERT(qxt_d().connector);
|
||||
return connector()->listen(listenInterface(), port());
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the name of the HTTP cookie used to track sessions in the web browser.
|
||||
* \sa setSessionCookieName
|
||||
*/
|
||||
QByteArray QxtHttpSessionManager::sessionCookieName() const
|
||||
{
|
||||
return qxt_d().sessionCookieName;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Sets the \a name of the HTTP cookie used to track sessions in the web browser.
|
||||
*
|
||||
* The default value is "sessionID".
|
||||
*
|
||||
* \sa sessionCookieName
|
||||
*/
|
||||
void QxtHttpSessionManager::setSessionCookieName(const QByteArray& name)
|
||||
{
|
||||
qxt_d().sessionCookieName = name;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Sets the \a connector used to manage connections to web browsers.
|
||||
*
|
||||
* \sa connector
|
||||
*/
|
||||
void QxtHttpSessionManager::setConnector(QxtAbstractHttpConnector* connector)
|
||||
{
|
||||
connector->setSessionManager(this);
|
||||
qxt_d().connector = connector;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Sets the \a connector used to manage connections to web browsers.
|
||||
*
|
||||
* This overload is provided for convenience and can construct the predefined
|
||||
* connectors provided with Qxt.
|
||||
*
|
||||
* \sa connector
|
||||
*/
|
||||
void QxtHttpSessionManager::setConnector(Connector connector)
|
||||
{
|
||||
if (connector == HttpServer)
|
||||
setConnector(new QxtHttpServerConnector(this));
|
||||
else if (connector == Scgi)
|
||||
setConnector(new QxtScgiServerConnector(this));
|
||||
/* commented out pending implementation
|
||||
|
||||
else if(connector == Fcgi)
|
||||
setConnector(new QxtFcgiConnector(this));
|
||||
*/
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the connector used to manage connections to web browsers.
|
||||
* \sa setConnector
|
||||
*/
|
||||
QxtAbstractHttpConnector* QxtHttpSessionManager::connector() const
|
||||
{
|
||||
return qxt_d().connector;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns \c true if sessions are automatically created for every connection
|
||||
* that does not already have a session cookie associated with it; otherwise
|
||||
* returns \c false.
|
||||
* \sa setAutoCreateSession
|
||||
*/
|
||||
bool QxtHttpSessionManager::autoCreateSession() const
|
||||
{
|
||||
return qxt_d().autoCreateSession;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Sets \a enabled whether sessions are automatically created for every connection
|
||||
* that does not already have a session cookie associated with it.
|
||||
*
|
||||
* Sessions are only created for clients that support HTTP cookies. HTTP/0.9
|
||||
* clients will never generate a session.
|
||||
*
|
||||
* \sa autoCreateSession
|
||||
*/
|
||||
void QxtHttpSessionManager::setAutoCreateSession(bool enable)
|
||||
{
|
||||
qxt_d().autoCreateSession = enable;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the QxtAbstractWebService that is used to respond to requests from
|
||||
* connections that are not associated with a session.
|
||||
*
|
||||
* \sa setStaticContentService
|
||||
*/
|
||||
QxtAbstractWebService* QxtHttpSessionManager::staticContentService() const
|
||||
{
|
||||
return qxt_d().staticService;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Sets the \a service that is used to respond to requests from
|
||||
* connections that are not associated with a session.
|
||||
*
|
||||
* If no static content service is set, connections that are not associated
|
||||
* with a session will receive an "Internal Configuration Error".
|
||||
*
|
||||
* \sa staticContentService
|
||||
*/
|
||||
void QxtHttpSessionManager::setStaticContentService(QxtAbstractWebService* service)
|
||||
{
|
||||
qxt_d().staticService = service;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
void QxtHttpSessionManager::postEvent(QxtWebEvent* h)
|
||||
{
|
||||
qxt_d().eventLock.lock();
|
||||
qxt_d().eventQueue.append(h);
|
||||
qxt_d().eventLock.unlock();
|
||||
// if(h->type() == QxtWebEvent::Page)
|
||||
QMetaObject::invokeMethod(this, "processEvents", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Creates a new session and sends the session key to the web browser.
|
||||
*
|
||||
* Subclasses may override this function to perform custom session initialization,
|
||||
* but they must call the base class implementation in order to update the internal
|
||||
* session database and fetch a new session ID.
|
||||
*/
|
||||
int QxtHttpSessionManager::newSession()
|
||||
{
|
||||
QMutexLocker locker(&qxt_d().sessionLock);
|
||||
int sessionID = createService();
|
||||
QUuid key;
|
||||
do
|
||||
{
|
||||
key = QUuid::createUuid();
|
||||
}
|
||||
while (qxt_d().sessionKeys.contains(key));
|
||||
qxt_d().sessionKeys[key] = sessionID;
|
||||
postEvent(new QxtWebStoreCookieEvent(sessionID, qxt_d().sessionCookieName, key));
|
||||
return sessionID;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Handles incoming HTTP requests and dispatches them to the appropriate service.
|
||||
*
|
||||
* The \a requestID is an opaque value generated by the connector.
|
||||
*
|
||||
* Subclasses may override this function to perform preprocessing on each
|
||||
* request, but they must call the base class implementation in order to
|
||||
* generate and dispatch the appropriate events.
|
||||
*/
|
||||
void QxtHttpSessionManager::incomingRequest(quint32 requestID, const QHttpRequestHeader& header, QxtWebContent* content)
|
||||
{
|
||||
QMultiHash<QString, QString> cookies;
|
||||
foreach(const QString& cookie, header.allValues("cookie")) // QHttpHeader is case-insensitive, thankfully
|
||||
{
|
||||
foreach(const QString& kv, cookie.split("; "))
|
||||
{
|
||||
int pos = kv.indexOf('=');
|
||||
if (pos == -1) continue;
|
||||
cookies.insert(kv.left(pos), kv.mid(pos + 1));
|
||||
}
|
||||
}
|
||||
|
||||
int sessionID;
|
||||
QString sessionCookie = cookies.value(qxt_d().sessionCookieName);
|
||||
|
||||
qxt_d().sessionLock.lock();
|
||||
if (qxt_d().sessionKeys.contains(sessionCookie))
|
||||
{
|
||||
sessionID = qxt_d().sessionKeys[sessionCookie];
|
||||
}
|
||||
else if (header.majorVersion() > 0 && qxt_d().autoCreateSession)
|
||||
{
|
||||
sessionID = newSession();
|
||||
}
|
||||
else
|
||||
{
|
||||
sessionID = 0;
|
||||
}
|
||||
|
||||
QIODevice* device = connector()->getRequestConnection(requestID);
|
||||
QxtHttpSessionManagerPrivate::ConnectionState& state = qxt_d().connectionState[device];
|
||||
state.sessionID = sessionID;
|
||||
state.httpMajorVersion = header.majorVersion();
|
||||
state.httpMinorVersion = header.minorVersion();
|
||||
if (state.httpMajorVersion == 0 || (state.httpMajorVersion == 1 && state.httpMinorVersion == 0) || header.value("connection").toLower() == "close")
|
||||
state.keepAlive = false;
|
||||
else
|
||||
state.keepAlive = true;
|
||||
qxt_d().sessionLock.unlock();
|
||||
|
||||
QxtWebRequestEvent* event = new QxtWebRequestEvent(sessionID, requestID, QUrl(header.path()));
|
||||
QTcpSocket* socket = qobject_cast<QTcpSocket*>(device);
|
||||
if (socket)
|
||||
{
|
||||
event->remoteAddress = socket->peerAddress().toString();
|
||||
}
|
||||
event->method = header.method();
|
||||
event->cookies = cookies;
|
||||
event->url.setScheme("http");
|
||||
if (event->url.host().isEmpty())
|
||||
event->url.setHost(header.value("host"));
|
||||
if (event->url.port() == -1)
|
||||
event->url.setPort(port());
|
||||
event->contentType = header.contentType();
|
||||
event->content = content;
|
||||
typedef QPair<QString, QString> StringPair;
|
||||
foreach(const StringPair& line, header.values())
|
||||
{
|
||||
if (line.first.toLower() == "cookie") continue;
|
||||
event->headers.insert(line.first, line.second);
|
||||
}
|
||||
event->headers.insert("X-Request-Protocol", "HTTP/" + QString::number(state.httpMajorVersion) + '.' + QString::number(state.httpMinorVersion));
|
||||
if (sessionID && session(sessionID))
|
||||
{
|
||||
session(sessionID)->pageRequestedEvent(event);
|
||||
}
|
||||
else if (qxt_d().staticService)
|
||||
{
|
||||
qxt_d().staticService->pageRequestedEvent(event);
|
||||
}
|
||||
else
|
||||
{
|
||||
postEvent(new QxtWebErrorEvent(0, requestID, 500, "Internal Configuration Error"));
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void QxtHttpSessionManager::disconnected(QIODevice* device)
|
||||
{
|
||||
QMutexLocker locker(&qxt_d().sessionLock);
|
||||
if (qxt_d().connectionState.contains(device))
|
||||
delete qxt_d().connectionState[device].onBytesWritten;
|
||||
qxt_d().connectionState.remove(device);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
void QxtHttpSessionManager::processEvents()
|
||||
{
|
||||
if (QThread::currentThreadId() != qxt_d().mainThread)
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "processEvents", Qt::QueuedConnection);
|
||||
return;
|
||||
}
|
||||
QxtHttpSessionManagerPrivate& d = qxt_d();
|
||||
QMutexLocker locker(&d.eventLock);
|
||||
if (!d.eventQueue.count()) return;
|
||||
|
||||
int ct = d.eventQueue.count(), sessionID = 0, requestID = 0, pagePos = -1;
|
||||
QxtWebRedirectEvent* re = 0;
|
||||
QxtWebPageEvent* pe = 0;
|
||||
for (int i = 0; i < ct; i++)
|
||||
{
|
||||
if (d.eventQueue[i]->type() != QxtWebEvent::Page && d.eventQueue[i]->type() != QxtWebEvent::Redirect) continue;
|
||||
pagePos = i;
|
||||
sessionID = d.eventQueue[i]->sessionID;
|
||||
if (d.eventQueue[pagePos]->type() == QxtWebEvent::Redirect)
|
||||
{
|
||||
re = static_cast<QxtWebRedirectEvent*>(d.eventQueue[pagePos]);
|
||||
}
|
||||
pe = static_cast<QxtWebPageEvent*>(d.eventQueue[pagePos]);
|
||||
requestID = pe->requestID;
|
||||
break;
|
||||
}
|
||||
if (pagePos == -1) return; // no pages to send yet
|
||||
|
||||
QHttpResponseHeader header;
|
||||
QList<int> removeIDs;
|
||||
QxtWebEvent* e = 0;
|
||||
for (int i = 0; i < pagePos; i++)
|
||||
{
|
||||
if (d.eventQueue[i]->sessionID != sessionID) continue;
|
||||
e = d.eventQueue[i];
|
||||
if (e->type() == QxtWebEvent::StoreCookie)
|
||||
{
|
||||
QxtWebStoreCookieEvent* ce = static_cast<QxtWebStoreCookieEvent*>(e);
|
||||
QString cookie = ce->name + '=' + ce->data;
|
||||
if (ce->expiration.isValid())
|
||||
{
|
||||
cookie += "; max-age=" + QString::number(QDateTime::currentDateTime().secsTo(ce->expiration))
|
||||
+ "; expires=" + ce->expiration.toUTC().toString("ddd, dd-MMM-YYYY hh:mm:ss GMT");
|
||||
}
|
||||
header.addValue("set-cookie", cookie);
|
||||
removeIDs.push_front(i);
|
||||
}
|
||||
else if (e->type() == QxtWebEvent::RemoveCookie)
|
||||
{
|
||||
QxtWebRemoveCookieEvent* ce = static_cast<QxtWebRemoveCookieEvent*>(e);
|
||||
header.addValue("set-cookie", ce->name + "=; max-age=0; expires=" + QDateTime(QDate(1970, 1, 1)).toString("ddd, dd-MMM-YYYY hh:mm:ss GMT"));
|
||||
removeIDs.push_front(i);
|
||||
}
|
||||
}
|
||||
removeIDs.push_front(pagePos);
|
||||
|
||||
QIODevice* device = connector()->getRequestConnection(requestID);
|
||||
QxtWebContent* content = qobject_cast<QxtWebContent*>(device);
|
||||
// TODO: This should only be invoked when pipelining occurs
|
||||
// In theory it shouldn't cause any problems as POST is specced to not be pipelined
|
||||
if (content) content->ignoreRemainingContent();
|
||||
|
||||
QxtHttpSessionManagerPrivate::ConnectionState& state = qxt_d().connectionState[connector()->getRequestConnection(requestID)];
|
||||
|
||||
header.setStatusLine(pe->status, pe->statusMessage, state.httpMajorVersion, state.httpMinorVersion);
|
||||
|
||||
if (re)
|
||||
{
|
||||
header.setValue("location", re->destination);
|
||||
}
|
||||
|
||||
// Set custom header values
|
||||
for (QMultiHash<QString, QString>::iterator it = pe->headers.begin(); it != pe->headers.end(); ++it)
|
||||
{
|
||||
header.setValue(it.key(), it.value());
|
||||
}
|
||||
|
||||
header.setContentType(pe->contentType);
|
||||
if (state.httpMajorVersion == 0 || (state.httpMajorVersion == 1 && state.httpMinorVersion == 0))
|
||||
pe->chunked = false;
|
||||
|
||||
connector()->setRequestDataSource( pe->requestID, pe->dataSource );
|
||||
QSharedPointer<QIODevice> source( pe->dataSource );
|
||||
state.finishedTransfer = false;
|
||||
bool emptyContent = !source->bytesAvailable() && !pe->streaming;
|
||||
state.readyRead = source->bytesAvailable();
|
||||
state.streaming = pe->streaming;
|
||||
|
||||
if (emptyContent)
|
||||
{
|
||||
header.setValue("connection", "close");
|
||||
connector()->writeHeaders(device, header);
|
||||
closeConnection(requestID);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (state.onBytesWritten) delete state.onBytesWritten; // disconnect old handler
|
||||
if (!pe->chunked)
|
||||
{
|
||||
state.keepAlive = false;
|
||||
state.onBytesWritten = QxtMetaObject::bind(this, SLOT(sendNextBlock(int)),
|
||||
Q_ARG(int, requestID));
|
||||
|
||||
QxtMetaObject::connect(source.data(), SIGNAL(readyRead()),
|
||||
QxtMetaObject::bind(this, SLOT(blockReadyRead(int)),
|
||||
Q_ARG(int, requestID)),
|
||||
Qt::QueuedConnection);
|
||||
|
||||
QxtMetaObject::connect(source.data(), SIGNAL(aboutToClose()),
|
||||
QxtMetaObject::bind(this, SLOT(closeConnection(int)),
|
||||
Q_ARG(int, requestID)),
|
||||
Qt::QueuedConnection);
|
||||
}
|
||||
else
|
||||
{
|
||||
header.setValue("transfer-encoding", "chunked");
|
||||
state.onBytesWritten = QxtMetaObject::bind(this, SLOT(sendNextChunk(int)),
|
||||
Q_ARG(int, requestID));
|
||||
|
||||
QxtMetaObject::connect(source.data(), SIGNAL(readyRead()),
|
||||
QxtMetaObject::bind(this, SLOT(chunkReadyRead(int)),
|
||||
Q_ARG(int, requestID)),
|
||||
Qt::QueuedConnection);
|
||||
|
||||
QxtMetaObject::connect(source.data(), SIGNAL(aboutToClose()),
|
||||
QxtMetaObject::bind(this, SLOT(sendEmptyChunk(int)),
|
||||
Q_ARG(int, requestID)),
|
||||
Qt::QueuedConnection);
|
||||
}
|
||||
QxtMetaObject::connect(device, SIGNAL(bytesWritten(qint64)), state.onBytesWritten, Qt::QueuedConnection);
|
||||
|
||||
if (state.keepAlive)
|
||||
{
|
||||
header.setValue("connection", "keep-alive");
|
||||
}
|
||||
else
|
||||
{
|
||||
header.setValue("connection", "close");
|
||||
}
|
||||
connector()->writeHeaders(device, header);
|
||||
if (state.readyRead)
|
||||
{
|
||||
if (pe->chunked)
|
||||
sendNextChunk(requestID);
|
||||
else
|
||||
sendNextBlock(requestID);
|
||||
}
|
||||
}
|
||||
|
||||
foreach(int id, removeIDs)
|
||||
{
|
||||
delete d.eventQueue.takeAt(id);
|
||||
}
|
||||
|
||||
if (d.eventQueue.count())
|
||||
QMetaObject::invokeMethod(this, "processEvents", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void QxtHttpSessionManager::chunkReadyRead(int requestID)
|
||||
{
|
||||
const QSharedPointer<QIODevice>& dataSource = connector()->getRequestDataSource( requestID );
|
||||
if (!dataSource->bytesAvailable()) return;
|
||||
QIODevice* device = connector()->getRequestConnection(requestID);
|
||||
if (!device->bytesToWrite() || qxt_d().connectionState[device].readyRead == false)
|
||||
{
|
||||
qxt_d().connectionState[device].readyRead = true;
|
||||
sendNextChunk(requestID);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void QxtHttpSessionManager::sendNextChunk(int requestID)
|
||||
{
|
||||
const QSharedPointer<QIODevice>& dataSource = connector()->getRequestDataSource( requestID );
|
||||
QIODevice* device = connector()->getRequestConnection(requestID);
|
||||
QxtHttpSessionManagerPrivate::ConnectionState& state = qxt_d().connectionState[device];
|
||||
if (state.finishedTransfer)
|
||||
{
|
||||
// This is just the last block written; we're done with it
|
||||
return;
|
||||
}
|
||||
if (!dataSource->bytesAvailable())
|
||||
{
|
||||
state.readyRead = false;
|
||||
return;
|
||||
}
|
||||
QByteArray chunk = dataSource->read(32768); // this is a good chunk size
|
||||
if (chunk.size())
|
||||
{
|
||||
QByteArray data = QString::number(chunk.size(), 16).toUtf8() + "\r\n" + chunk + "\r\n";
|
||||
device->write(data);
|
||||
}
|
||||
state.readyRead = false;
|
||||
if (!state.streaming && !dataSource->bytesAvailable())
|
||||
QMetaObject::invokeMethod(this, "sendEmptyChunk", Q_ARG(int, requestID));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void QxtHttpSessionManager::sendEmptyChunk(int requestID)
|
||||
{
|
||||
QIODevice* device = connector()->getRequestConnection(requestID);
|
||||
if (!qxt_d().connectionState.contains(device)) return; // in case a disconnect signal and a bytesWritten signal get fired in the wrong order
|
||||
QxtHttpSessionManagerPrivate::ConnectionState& state = qxt_d().connectionState[device];
|
||||
if (state.finishedTransfer) return;
|
||||
state.finishedTransfer = true;
|
||||
device->write("0\r\n\r\n");
|
||||
|
||||
if (state.keepAlive)
|
||||
{
|
||||
delete state.onBytesWritten;
|
||||
state.onBytesWritten = 0;
|
||||
QSharedPointer<QIODevice>& dataSource = connector()->getRequestDataSource( requestID );
|
||||
dataSource.clear();
|
||||
connector()->incomingData(device);
|
||||
}
|
||||
else
|
||||
{
|
||||
closeConnection(requestID);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void QxtHttpSessionManager::closeConnection(int requestID)
|
||||
{
|
||||
QIODevice* device = connector()->getRequestConnection(requestID);
|
||||
if( !device ) return; // already closing/closed
|
||||
QxtHttpSessionManagerPrivate::ConnectionState& state = qxt_d().connectionState[device];
|
||||
state.finishedTransfer = true;
|
||||
state.onBytesWritten = NULL;
|
||||
QTcpSocket* socket = qobject_cast<QTcpSocket*>(device);
|
||||
if (socket)
|
||||
socket->disconnectFromHost();
|
||||
else
|
||||
device->close();
|
||||
|
||||
connector()->doneWithRequest( requestID );
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void QxtHttpSessionManager::blockReadyRead(int requestID)
|
||||
{
|
||||
const QSharedPointer<QIODevice>& dataSource = connector()->getRequestDataSource( requestID );
|
||||
if (!dataSource->bytesAvailable()) return;
|
||||
|
||||
QIODevice* device = connector()->getRequestConnection(requestID);
|
||||
if (!device->bytesToWrite() || qxt_d().connectionState[device].readyRead == false)
|
||||
{
|
||||
qxt_d().connectionState[device].readyRead = true;
|
||||
sendNextBlock(requestID);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void QxtHttpSessionManager::sendNextBlock(int requestID)
|
||||
{
|
||||
QSharedPointer<QIODevice>& dataSource = connector()->getRequestDataSource( requestID );
|
||||
QIODevice* device = connector()->getRequestConnection(requestID);
|
||||
if (!qxt_d().connectionState.contains(device)) return; // in case a disconnect signal and a bytesWritten signal get fired in the wrong order
|
||||
QxtHttpSessionManagerPrivate::ConnectionState& state = qxt_d().connectionState[device];
|
||||
if (state.finishedTransfer) return;
|
||||
if (!dataSource->bytesAvailable())
|
||||
{
|
||||
state.readyRead = false;
|
||||
return;
|
||||
}
|
||||
QByteArray chunk = dataSource->read(32768); // this is a good chunk size
|
||||
device->write(chunk);
|
||||
state.readyRead = false;
|
||||
if (!state.streaming && !dataSource->bytesAvailable())
|
||||
{
|
||||
closeConnection(requestID);
|
||||
}
|
||||
}
|
91
thirdparty/qxt/qxtweb-standalone/qxtweb/qxthttpsessionmanager.h
vendored
Normal file
91
thirdparty/qxt/qxtweb-standalone/qxtweb/qxthttpsessionmanager.h
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtWeb module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QXTHTTPSESSIONMANAGER_H
|
||||
#define QXTHTTPSESSIONMANAGER_H
|
||||
|
||||
#include "qxtabstractwebsessionmanager.h"
|
||||
#include "qxtabstracthttpconnector.h"
|
||||
#include <QHostAddress>
|
||||
#include <QHttpHeader>
|
||||
#include <QSharedPointer>
|
||||
|
||||
class QxtWebEvent;
|
||||
class QxtWebContent;
|
||||
|
||||
class QxtHttpSessionManagerPrivate;
|
||||
class QXT_WEB_EXPORT QxtHttpSessionManager : public QxtAbstractWebSessionManager
|
||||
{
|
||||
friend class QxtAbstractHttpConnector;
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Connector { HttpServer, Scgi, Fcgi };
|
||||
|
||||
QxtHttpSessionManager(QObject* parent = 0);
|
||||
|
||||
virtual void postEvent(QxtWebEvent*);
|
||||
|
||||
QHostAddress listenInterface() const;
|
||||
void setListenInterface(const QHostAddress& iface);
|
||||
|
||||
quint16 port() const;
|
||||
void setPort(quint16 port);
|
||||
|
||||
QByteArray sessionCookieName() const;
|
||||
void setSessionCookieName(const QByteArray& name);
|
||||
|
||||
bool autoCreateSession() const;
|
||||
void setAutoCreateSession(bool enable);
|
||||
|
||||
QxtAbstractWebService* staticContentService() const;
|
||||
void setStaticContentService(QxtAbstractWebService* service);
|
||||
|
||||
void setConnector(QxtAbstractHttpConnector* connector);
|
||||
void setConnector(Connector connector);
|
||||
QxtAbstractHttpConnector* connector() const;
|
||||
|
||||
virtual bool start();
|
||||
|
||||
protected:
|
||||
virtual int newSession();
|
||||
virtual void incomingRequest(quint32 requestID, const QHttpRequestHeader& header, QxtWebContent* device);
|
||||
|
||||
protected Q_SLOTS:
|
||||
virtual void processEvents();
|
||||
|
||||
private Q_SLOTS:
|
||||
void closeConnection(int requestID);
|
||||
void chunkReadyRead(int requestID);
|
||||
void sendNextChunk(int requestID);
|
||||
void sendEmptyChunk(int requestID);
|
||||
void blockReadyRead(int requestID);
|
||||
void sendNextBlock(int requestID);
|
||||
|
||||
private:
|
||||
void disconnected(QIODevice* device);
|
||||
QXT_DECLARE_PRIVATE(QxtHttpSessionManager)
|
||||
};
|
||||
|
||||
#endif
|
371
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtmetaobject.cpp
vendored
Normal file
371
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtmetaobject.cpp
vendored
Normal file
@@ -0,0 +1,371 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtCore module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\namespace QxtMetaObject
|
||||
|
||||
\inmodule QxtCore
|
||||
|
||||
\brief The QxtMetaObject namespace provides extensions to QMetaObject
|
||||
|
||||
including QxtMetaObject::bind
|
||||
|
||||
*/
|
||||
|
||||
#include "qxtmetaobject.h"
|
||||
#include "qxtboundfunction.h"
|
||||
#include "qxtboundcfunction.h"
|
||||
#include "qxtmetatype.h"
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QMetaObject>
|
||||
#include <QMetaMethod>
|
||||
#include <QtDebug>
|
||||
|
||||
#ifndef QXT_DOXYGEN_RUN
|
||||
class QxtBoundArgument
|
||||
{
|
||||
// This class intentionally left blank
|
||||
};
|
||||
Q_DECLARE_METATYPE(QxtBoundArgument)
|
||||
|
||||
class QxtBoundFunctionBase;
|
||||
|
||||
QxtBoundFunction::QxtBoundFunction(QObject* parent) : QObject(parent)
|
||||
{
|
||||
// initializer only
|
||||
}
|
||||
#endif
|
||||
|
||||
bool QxtBoundFunction::invoke(Qt::ConnectionType type, QXT_IMPL_10ARGS(QVariant))
|
||||
{
|
||||
return invoke(type, QXT_VAR_ARG(1), QXT_VAR_ARG(2), QXT_VAR_ARG(3), QXT_VAR_ARG(4), QXT_VAR_ARG(5), QXT_VAR_ARG(6), QXT_VAR_ARG(7), QXT_VAR_ARG(8), QXT_VAR_ARG(9), QXT_VAR_ARG(10));
|
||||
}
|
||||
|
||||
bool QxtBoundFunction::invoke(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_IMPL_10ARGS(QVariant))
|
||||
{
|
||||
return invoke(type, returnValue, QXT_VAR_ARG(1), QXT_VAR_ARG(2), QXT_VAR_ARG(3), QXT_VAR_ARG(4), QXT_VAR_ARG(5), QXT_VAR_ARG(6), QXT_VAR_ARG(7), QXT_VAR_ARG(8), QXT_VAR_ARG(9), QXT_VAR_ARG(10));
|
||||
}
|
||||
|
||||
QxtBoundFunctionBase::QxtBoundFunctionBase(QObject* parent, QGenericArgument* params[10], QByteArray types[10]) : QxtBoundFunction(parent)
|
||||
{
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
if (!params[i]) break;
|
||||
if (QByteArray(params[i]->name()) == "QxtBoundArgument")
|
||||
{
|
||||
arg[i] = QGenericArgument("QxtBoundArgument", params[i]->data());
|
||||
}
|
||||
else
|
||||
{
|
||||
data[i] = qxtConstructFromGenericArgument(*params[i]);
|
||||
arg[i] = p[i] = QGenericArgument(params[i]->name(), data[i]);
|
||||
}
|
||||
bindTypes[i] = types[i];
|
||||
}
|
||||
}
|
||||
|
||||
QxtBoundFunctionBase::~QxtBoundFunctionBase()
|
||||
{
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
if (arg[i].name() == 0) return;
|
||||
if (QByteArray(arg[i].name()) != "QxtBoundArgument") qxtDestroyFromGenericArgument(arg[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int QxtBoundFunctionBase::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
|
||||
{
|
||||
_id = QObject::qt_metacall(_c, _id, _a);
|
||||
if (_id < 0)
|
||||
return _id;
|
||||
if (_c == QMetaObject::InvokeMetaMethod)
|
||||
{
|
||||
if (_id == 0)
|
||||
{
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
if (QByteArray(arg[i].name()) == "QxtBoundArgument")
|
||||
{
|
||||
p[i] = QGenericArgument(bindTypes[i].constData(), _a[(quintptr)(arg[i].data())]);
|
||||
}
|
||||
}
|
||||
invokeImpl(Qt::DirectConnection, QGenericReturnArgument(), p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9]);
|
||||
}
|
||||
_id = -1;
|
||||
}
|
||||
return _id;
|
||||
}
|
||||
|
||||
bool QxtBoundFunctionBase::invokeBase(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_IMPL_10ARGS(QGenericArgument))
|
||||
{
|
||||
QGenericArgument* args[10] = { &p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9, &p10 };
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
if (QByteArray(arg[i].name()) == "QxtBoundArgument")
|
||||
{
|
||||
p[i] = *args[(quintptr)(arg[i].data()) - 1];
|
||||
}
|
||||
}
|
||||
return invokeImpl(type, returnValue, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9]);
|
||||
}
|
||||
|
||||
bool QxtBoundFunction::invoke(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_IMPL_10ARGS(QGenericArgument))
|
||||
{
|
||||
return reinterpret_cast<QxtBoundFunctionBase*>(this)->invokeBase(type, returnValue, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
|
||||
}
|
||||
|
||||
#ifndef QXT_DOXYGEN_RUN
|
||||
class QxtBoundSlot : public QxtBoundFunctionBase
|
||||
{
|
||||
public:
|
||||
QByteArray sig;
|
||||
|
||||
QxtBoundSlot(QObject* receiver, const char* invokable, QGenericArgument* params[10], QByteArray types[10]) : QxtBoundFunctionBase(receiver, params, types), sig(invokable)
|
||||
{
|
||||
// initializers only
|
||||
}
|
||||
|
||||
virtual bool invokeImpl(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_IMPL_10ARGS(QGenericArgument))
|
||||
{
|
||||
if (!QMetaObject::invokeMethod(parent(), QxtMetaObject::methodName(sig.constData()), type, returnValue, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10))
|
||||
{
|
||||
qWarning() << "QxtBoundFunction: call to" << sig << "failed";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
namespace QxtMetaObject
|
||||
{
|
||||
|
||||
/*!
|
||||
Returns the name of the given method.
|
||||
|
||||
Example usage:
|
||||
\code
|
||||
QByteArray method = QxtMetaObject::methodName(" int foo ( int bar, double baz )");
|
||||
// method is now "foo"
|
||||
\endcode
|
||||
*/
|
||||
QByteArray methodName(const char* method)
|
||||
{
|
||||
QByteArray name = methodSignature(method);
|
||||
const int idx = name.indexOf("(");
|
||||
if (idx != -1)
|
||||
name.truncate(idx);
|
||||
return name;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the signature of the given method.
|
||||
*/
|
||||
QByteArray methodSignature(const char* method)
|
||||
{
|
||||
QByteArray name = QMetaObject::normalizedSignature(method);
|
||||
if(name[0] >= '0' && name[0] <= '9')
|
||||
return name.mid(1);
|
||||
return name;
|
||||
}
|
||||
|
||||
/*!
|
||||
Checks if \a method contains parentheses and begins with 1 or 2.
|
||||
*/
|
||||
bool isSignalOrSlot(const char* method)
|
||||
{
|
||||
QByteArray m(method);
|
||||
return (m.count() && (m[0] >= '0' && m[0] <= '9') && m.contains('(') && m.contains(')'));
|
||||
}
|
||||
|
||||
/*!
|
||||
* Creates a binding to the provided signal, slot, or Q_INVOKABLE method using the
|
||||
* provided parameter list. The type of each argument is deduced from the type of
|
||||
* the QVariant. This function cannot bind positional arguments; see the
|
||||
* overload using QGenericArgument.
|
||||
*
|
||||
* If the provided QObject does not implement the requested method, or if the
|
||||
* argument list is incompatible with the method's function signature, this
|
||||
* function returns NULL.
|
||||
*
|
||||
* The returned QxtBoundFunction is created as a child of the receiver.
|
||||
* Changing the parent will result in undefined behavior.
|
||||
*
|
||||
* \sa QxtMetaObject::connect, QxtBoundFunction
|
||||
*/
|
||||
QxtBoundFunction* bind(QObject* recv, const char* invokable, QXT_IMPL_10ARGS(QVariant))
|
||||
{
|
||||
if (!recv)
|
||||
{
|
||||
qWarning() << "QxtMetaObject::bind: cannot connect to null QObject";
|
||||
return 0;
|
||||
}
|
||||
|
||||
QVariant* args[10] = { &p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9, &p10 };
|
||||
QByteArray connSlot("2"), recvSlot(QMetaObject::normalizedSignature(invokable));
|
||||
const QMetaObject* meta = recv->metaObject();
|
||||
int methodID = meta->indexOfMethod(QxtMetaObject::methodSignature(recvSlot.constData()));
|
||||
if (methodID == -1)
|
||||
{
|
||||
qWarning() << "QxtMetaObject::bind: no such method " << recvSlot;
|
||||
return 0;
|
||||
}
|
||||
QMetaMethod method = meta->method(methodID);
|
||||
int argCount = method.parameterTypes().count();
|
||||
const QList<QByteArray> paramTypes = method.parameterTypes();
|
||||
|
||||
for (int i = 0; i < argCount; i++)
|
||||
{
|
||||
if (paramTypes[i] == "QxtBoundArgument") continue;
|
||||
int type = QMetaType::type(paramTypes[i].constData());
|
||||
if (!args[i]->canConvert((QVariant::Type)type))
|
||||
{
|
||||
qWarning() << "QxtMetaObject::bind: incompatible parameter list for " << recvSlot;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return QxtMetaObject::bind(recv, invokable, QXT_ARG(1), QXT_ARG(2), QXT_ARG(3), QXT_ARG(4), QXT_ARG(5), QXT_ARG(6), QXT_ARG(7), QXT_ARG(8), QXT_ARG(9), QXT_ARG(10));
|
||||
}
|
||||
|
||||
/*!
|
||||
* Creates a binding to the provided signal, slot, or Q_INVOKABLE method using the
|
||||
* provided parameter list. Use the Q_ARG macro to specify constant parameters, or
|
||||
* use the QXT_BIND macro to relay a parameter from a connected signal or passed
|
||||
* via the QxtBoundFunction::invoke() method.
|
||||
*
|
||||
* If the provided QObject does not implement the requested method, or if the
|
||||
* argument list is incompatible with the method's function signature, this
|
||||
* function returns NULL.
|
||||
*
|
||||
* The returned QxtBoundFunction is created as a child of the receiver.
|
||||
* Changing the parent will result in undefined behavior.
|
||||
*
|
||||
* \sa QxtMetaObject::connect, QxtBoundFunction, QXT_BIND
|
||||
*/
|
||||
QxtBoundFunction* bind(QObject* recv, const char* invokable, QXT_IMPL_10ARGS(QGenericArgument))
|
||||
{
|
||||
if (!recv)
|
||||
{
|
||||
qWarning() << "QxtMetaObject::bind: cannot connect to null QObject";
|
||||
return 0;
|
||||
}
|
||||
|
||||
QGenericArgument* args[10] = { &p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9, &p10 };
|
||||
QByteArray connSlot("2"), recvSlot(QMetaObject::normalizedSignature(invokable)), bindTypes[10];
|
||||
const QMetaObject* meta = recv->metaObject();
|
||||
int methodID = meta->indexOfMethod(QxtMetaObject::methodSignature(recvSlot.constData()).constData());
|
||||
if (methodID == -1)
|
||||
{
|
||||
qWarning() << "QxtMetaObject::bind: no such method " << recvSlot;
|
||||
return 0;
|
||||
}
|
||||
QMetaMethod method = meta->method(methodID);
|
||||
int argCount = method.parameterTypes().count();
|
||||
|
||||
connSlot += QxtMetaObject::methodName(invokable) + '(';
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
if (args[i]->name() == 0) break; // done
|
||||
if (i >= argCount)
|
||||
{
|
||||
qWarning() << "QxtMetaObject::bind: too many arguments passed to " << invokable;
|
||||
return 0;
|
||||
}
|
||||
if (i > 0) connSlot += ','; // argument separator
|
||||
if (QByteArray(args[i]->name()) == "QxtBoundArgument")
|
||||
{
|
||||
Q_ASSERT_X((quintptr)(args[i]->data()) > 0 && (quintptr)(args[i]->data()) <= 10, "QXT_BIND", "invalid argument number");
|
||||
connSlot += method.parameterTypes()[i];
|
||||
bindTypes[i] = method.parameterTypes()[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
connSlot += args[i]->name(); // type name
|
||||
}
|
||||
}
|
||||
connSlot = QMetaObject::normalizedSignature(connSlot += ')');
|
||||
|
||||
if (!QMetaObject::checkConnectArgs(recvSlot.constData(), connSlot.constData()))
|
||||
{
|
||||
qWarning() << "QxtMetaObject::bind: provided parameters " << connSlot.mid(connSlot.indexOf('(')) << " is incompatible with " << invokable;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return new QxtBoundSlot(recv, invokable, args, bindTypes);
|
||||
}
|
||||
|
||||
/*!
|
||||
Connects a signal to a QxtBoundFunction.
|
||||
*/
|
||||
bool connect(QObject* sender, const char* signal, QxtBoundFunction* slot, Qt::ConnectionType type)
|
||||
{
|
||||
const QMetaObject* meta = sender->metaObject();
|
||||
int methodID = meta->indexOfMethod(meta->normalizedSignature(signal).mid(1).constData());
|
||||
if (methodID < 0)
|
||||
{
|
||||
qWarning() << "QxtMetaObject::connect: no such signal: " << QByteArray(signal).mid(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
return QMetaObject::connect(sender, methodID, slot, QObject::staticMetaObject.methodCount(), (int)(type));
|
||||
}
|
||||
|
||||
/*!
|
||||
\relates QxtMetaObject
|
||||
This overload always invokes the member using the connection type Qt::AutoConnection.
|
||||
|
||||
\sa QMetaObject::invokeMethod()
|
||||
*/
|
||||
bool invokeMethod(QObject* object, const char* member, const QVariant& arg0,
|
||||
const QVariant& arg1, const QVariant& arg2, const QVariant& arg3,
|
||||
const QVariant& arg4, const QVariant& arg5, const QVariant& arg6,
|
||||
const QVariant& arg7, const QVariant& arg8, const QVariant& arg9)
|
||||
{
|
||||
return invokeMethod(object, member, Qt::AutoConnection,
|
||||
arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
|
||||
}
|
||||
|
||||
/*!
|
||||
\relates QxtMetaObject
|
||||
|
||||
Invokes the \a member (a signal or a slot name) on the \a object.
|
||||
Returns \c true if the member could be invoked. Returns \c false
|
||||
if there is no such member or the parameters did not match.
|
||||
|
||||
\sa QMetaObject::invokeMethod()
|
||||
*/
|
||||
bool invokeMethod(QObject* object, const char* member, Qt::ConnectionType type,
|
||||
const QVariant& arg0, const QVariant& arg1, const QVariant& arg2,
|
||||
const QVariant& arg3, const QVariant& arg4, const QVariant& arg5,
|
||||
const QVariant& arg6, const QVariant& arg7, const QVariant& arg8, const QVariant& arg9)
|
||||
{
|
||||
#define QXT_MO_ARG(i) QGenericArgument(arg ## i.typeName(), arg ## i.constData())
|
||||
return QMetaObject::invokeMethod(object, methodName(member), type,
|
||||
QXT_MO_ARG(0), QXT_MO_ARG(1), QXT_MO_ARG(2), QXT_MO_ARG(3), QXT_MO_ARG(4),
|
||||
QXT_MO_ARG(5), QXT_MO_ARG(6), QXT_MO_ARG(7), QXT_MO_ARG(8), QXT_MO_ARG(9));
|
||||
}
|
||||
}
|
106
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtmetaobject.h
vendored
Normal file
106
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtmetaobject.h
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtCore module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
#ifndef QXTMETAOBJECT_H
|
||||
#define QXTMETAOBJECT_H
|
||||
|
||||
#include <QMetaObject>
|
||||
#include <QVariant>
|
||||
#include <QGenericArgument>
|
||||
#include <typeinfo>
|
||||
#include "qxtnullable.h"
|
||||
#include "qxtglobal.h"
|
||||
QT_FORWARD_DECLARE_CLASS(QByteArray)
|
||||
class QxtBoundArgument;
|
||||
class QxtBoundFunction;
|
||||
|
||||
#define QXT_PROTO_10ARGS(T) T p1 = T(), T p2 = T(), T p3 = T(), T p4 = T(), T p5 = T(), T p6 = T(), T p7 = T(), T p8 = T(), T p9 = T(), T p10 = T()
|
||||
#define QXT_PROTO_9ARGS(T) T p2 = T(), T p3 = T(), T p4 = T(), T p5 = T(), T p6 = T(), T p7 = T(), T p8 = T(), T p9 = T(), T p10 = T()
|
||||
#define QXT_IMPL_10ARGS(T) T p1, T p2, T p3, T p4, T p5, T p6, T p7, T p8, T p9, T p10
|
||||
|
||||
class QXT_CORE_EXPORT QxtGenericFunctionPointer
|
||||
{
|
||||
template<typename FUNCTION>
|
||||
friend QxtGenericFunctionPointer qxtFuncPtr(FUNCTION funcPtr);
|
||||
public:
|
||||
QxtGenericFunctionPointer(const QxtGenericFunctionPointer& other)
|
||||
{
|
||||
funcPtr = other.funcPtr;
|
||||
typeName = other.typeName;
|
||||
}
|
||||
|
||||
typedef void(voidFunc)();
|
||||
voidFunc* funcPtr;
|
||||
QByteArray typeName;
|
||||
|
||||
protected:
|
||||
QxtGenericFunctionPointer(voidFunc* ptr, const QByteArray& typeIdName)
|
||||
{
|
||||
funcPtr = ptr;
|
||||
typeName = typeIdName;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename FUNCTION>
|
||||
QxtGenericFunctionPointer qxtFuncPtr(FUNCTION funcPtr)
|
||||
{
|
||||
return QxtGenericFunctionPointer(reinterpret_cast<QxtGenericFunctionPointer::voidFunc*>(funcPtr), typeid(funcPtr).name());
|
||||
}
|
||||
|
||||
namespace QxtMetaObject
|
||||
{
|
||||
QXT_CORE_EXPORT QByteArray methodName(const char* method);
|
||||
QXT_CORE_EXPORT QByteArray methodSignature(const char* method);
|
||||
|
||||
QXT_CORE_EXPORT bool isSignalOrSlot(const char* method);
|
||||
|
||||
QXT_CORE_EXPORT QxtBoundFunction* bind(QObject* recv, const char* invokable, QXT_PROTO_10ARGS(QGenericArgument));
|
||||
QXT_CORE_EXPORT QxtBoundFunction* bind(QObject* recv, const char* invokable, QVariant p1, QXT_PROTO_9ARGS(QVariant));
|
||||
QXT_CORE_EXPORT bool connect(QObject* sender, const char* signal, QxtBoundFunction* slot,
|
||||
Qt::ConnectionType type = Qt::AutoConnection);
|
||||
|
||||
QXT_CORE_EXPORT bool invokeMethod(QObject* object, const char* member,
|
||||
const QVariant& arg0 = QVariant(), const QVariant& arg1 = QVariant(),
|
||||
const QVariant& arg2 = QVariant(), const QVariant& arg3 = QVariant(),
|
||||
const QVariant& arg4 = QVariant(), const QVariant& arg5 = QVariant(),
|
||||
const QVariant& arg6 = QVariant(), const QVariant& arg7 = QVariant(),
|
||||
const QVariant& arg8 = QVariant(), const QVariant& arg9 = QVariant());
|
||||
|
||||
QXT_CORE_EXPORT bool invokeMethod(QObject* object, const char* member, Qt::ConnectionType type,
|
||||
const QVariant& arg0 = QVariant(), const QVariant& arg1 = QVariant(),
|
||||
const QVariant& arg2 = QVariant(), const QVariant& arg3 = QVariant(),
|
||||
const QVariant& arg4 = QVariant(), const QVariant& arg5 = QVariant(),
|
||||
const QVariant& arg6 = QVariant(), const QVariant& arg7 = QVariant(),
|
||||
const QVariant& arg8 = QVariant(), const QVariant& arg9 = QVariant());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \relates QxtMetaObject
|
||||
* Refers to the n'th parameter of QxtBoundFunction::invoke() or of a signal connected to
|
||||
* a QxtBoundFunction.
|
||||
* \sa QxtMetaObject::bind
|
||||
*/
|
||||
#define QXT_BIND(n) QGenericArgument("QxtBoundArgument", reinterpret_cast<void*>(n))
|
||||
|
||||
#endif // QXTMETAOBJECT_H
|
132
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtmetatype.h
vendored
Normal file
132
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtmetatype.h
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtCore module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QXTMETATYPE_H
|
||||
#define QXTMETATYPE_H
|
||||
|
||||
#include <QMetaType>
|
||||
#include <QDataStream>
|
||||
#include <QGenericArgument>
|
||||
#include <QtDebug>
|
||||
#include <qxtglobal.h>
|
||||
|
||||
template <typename T>
|
||||
class /*QXT_CORE_EXPORT*/ QxtMetaType
|
||||
{
|
||||
public:
|
||||
static inline T* construct(const T* copy = 0)
|
||||
{
|
||||
return QMetaType::construct(qMetaTypeId<T>(), reinterpret_cast<const void*>(copy));
|
||||
}
|
||||
|
||||
static inline void destroy(T* data)
|
||||
{
|
||||
QMetaType::destroy(qMetaTypeId<T>(), data);
|
||||
}
|
||||
|
||||
// no need to reimplement isRegistered since this class will fail at compile time if it isn't
|
||||
|
||||
static inline bool load(QDataStream& stream, T* data)
|
||||
{
|
||||
return QMetaType::load(stream, qMetaTypeId<T>(), reinterpret_cast<void*>(data));
|
||||
}
|
||||
|
||||
static inline bool save(QDataStream& stream, const T* data)
|
||||
{
|
||||
return QMetaType::save(stream, qMetaTypeId<T>(), reinterpret_cast<const void*>(data));
|
||||
}
|
||||
|
||||
static inline int type()
|
||||
{
|
||||
return qMetaTypeId<T>();
|
||||
}
|
||||
|
||||
static inline const char* name()
|
||||
{
|
||||
return QMetaType::typeName(qMetaTypeId<T>());
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class /*QXT_CORE_EXPORT*/ QxtMetaType<void>
|
||||
{
|
||||
public:
|
||||
static inline void* construct(const void* copy = 0)
|
||||
{
|
||||
Q_UNUSED(copy);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void destroy(void* data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
}
|
||||
|
||||
static inline bool load(QDataStream& stream, void* data)
|
||||
{
|
||||
Q_UNUSED(stream);
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool save(QDataStream& stream, const void* data)
|
||||
{
|
||||
Q_UNUSED(stream);
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline int type()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline const char* name()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
inline void* qxtConstructByName(const char* typeName, const void* copy = 0)
|
||||
{
|
||||
return QMetaType::construct(QMetaType::type(typeName), copy);
|
||||
}
|
||||
|
||||
inline void qxtDestroyByName(const char* typeName, void* data)
|
||||
{
|
||||
QMetaType::destroy(QMetaType::type(typeName), data);
|
||||
}
|
||||
|
||||
inline void* qxtConstructFromGenericArgument(QGenericArgument arg)
|
||||
{
|
||||
return qxtConstructByName(arg.name(), arg.data());
|
||||
}
|
||||
|
||||
inline void qxtDestroyFromGenericArgument(QGenericArgument arg)
|
||||
{
|
||||
qxtDestroyByName(arg.name(), arg.data());
|
||||
}
|
||||
|
||||
#endif
|
27
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtnull.cpp
vendored
Normal file
27
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtnull.cpp
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtCore module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "qxtnull.h"
|
||||
|
||||
// nothing here
|
62
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtnull.h
vendored
Normal file
62
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtnull.h
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtCore module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QXTNULL_H
|
||||
#define QXTNULL_H
|
||||
|
||||
#include <qxtglobal.h>
|
||||
|
||||
/*!
|
||||
\class QxtNull QxtNull
|
||||
|
||||
\inmodule QxtCore
|
||||
|
||||
\brief An object representing the "null" value for QxtNullable.
|
||||
|
||||
\sa QxtNullable
|
||||
*/
|
||||
|
||||
struct QXT_CORE_EXPORT QxtNull
|
||||
{
|
||||
/*! integer cast operator
|
||||
* In expressions, QxtNull behaves as an integer zero for compatibility with generic functions.
|
||||
*/
|
||||
operator int() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
enum { isNull = true };
|
||||
};
|
||||
|
||||
#ifndef QXT_NO_MACROS
|
||||
|
||||
/*! \relates QxtNull
|
||||
* A convenience alias for QxtNull().
|
||||
*/
|
||||
#define QXT_NULL QxtNull()
|
||||
|
||||
#endif // QXT_NO_MACROS
|
||||
|
||||
#endif // QXTNULL_H
|
146
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtnullable.h
vendored
Normal file
146
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtnullable.h
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtCore module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\class QxtNullable QxtNullable
|
||||
\inmodule QxtCore
|
||||
\brief distinct null value compatible with any data type.
|
||||
|
||||
in general it's a templated abstraction to allow any data type to be
|
||||
expressed with a null value distinct from any real value. An example
|
||||
of such a use is for optional arguments.
|
||||
\n
|
||||
prepare a function for argument skipping:
|
||||
|
||||
\code
|
||||
void somefunction( qxtNull(int,a) , qxtNull(int,b) )
|
||||
{
|
||||
|
||||
if (!a.isNull())
|
||||
{
|
||||
int i = a.value();
|
||||
//do something with i
|
||||
}
|
||||
if (!b.isNull())
|
||||
{
|
||||
int x = b.value();
|
||||
//do something with x
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
|
||||
usage:
|
||||
\code
|
||||
|
||||
somefunction(SKIP,1,2);
|
||||
somefunction(3,4);
|
||||
somefunction(3,SKIP,6);
|
||||
somefunction(1);
|
||||
\endcode
|
||||
|
||||
*/
|
||||
|
||||
#ifndef QXTNULLABLE_H
|
||||
#define QXTNULLABLE_H
|
||||
#include <qxtglobal.h>
|
||||
|
||||
/*! \relates QxtNullable
|
||||
* defines a skipable argument with type \a t and variable name \a n
|
||||
*/
|
||||
#define qxtNull(t,n) QxtNullable<t> n = QxtNullable<t>()
|
||||
|
||||
#include <qxtnull.h>
|
||||
|
||||
template<typename T>
|
||||
class /*QXT_CORE_EXPORT*/ QxtNullable
|
||||
{
|
||||
public:
|
||||
QxtNullable(QxtNull);
|
||||
QxtNullable(const T& p);
|
||||
QxtNullable();
|
||||
|
||||
///determinates if the Value is set to something meaningfull
|
||||
bool isNull() const;
|
||||
|
||||
///delete Value
|
||||
void nullify();
|
||||
|
||||
T& value() const;
|
||||
operator T() const;
|
||||
void operator=(const T& p);
|
||||
|
||||
private:
|
||||
T* val;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
QxtNullable<T>::QxtNullable(QxtNull)
|
||||
{
|
||||
val = 0;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
QxtNullable<T>::QxtNullable(const T& p)
|
||||
{
|
||||
val = const_cast<T*>(&p);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
QxtNullable<T>::QxtNullable()
|
||||
{
|
||||
val = 0;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
QxtNullable<T>::operator T() const
|
||||
{
|
||||
return *val;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T& QxtNullable<T>::value() const
|
||||
{
|
||||
return *val;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool QxtNullable<T>::isNull() const
|
||||
{
|
||||
return (val == 0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void QxtNullable<T>::nullify()
|
||||
{
|
||||
val = 0;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void QxtNullable<T>::operator=(const T & p)
|
||||
{
|
||||
val = const_cast<T*>(&p);
|
||||
}
|
||||
|
||||
#endif
|
191
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtscgiserverconnector.cpp
vendored
Normal file
191
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtscgiserverconnector.cpp
vendored
Normal file
@@ -0,0 +1,191 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtWeb module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\class QxtScgiServerConnector
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtScgiServerConnector class provides an SCGI connector for QxtHttpSessionManager
|
||||
|
||||
|
||||
QxtScgiServerConnector implements the SCGI protocoll supported by almost all modern web servers.
|
||||
|
||||
|
||||
|
||||
\sa QxtHttpSessionManager
|
||||
*/
|
||||
#include "qxthttpsessionmanager.h"
|
||||
#include "qxtwebevent.h"
|
||||
#include <QTcpServer>
|
||||
#include <QHash>
|
||||
#include <QTcpSocket>
|
||||
#include <QString>
|
||||
|
||||
#ifndef QXT_DOXYGEN_RUN
|
||||
class QxtScgiServerConnectorPrivate : public QxtPrivate<QxtScgiServerConnector>
|
||||
{
|
||||
public:
|
||||
QTcpServer* server;
|
||||
};
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Creates a QxtHttpServerConnector with the given \a parent.
|
||||
*/
|
||||
QxtScgiServerConnector::QxtScgiServerConnector(QObject* parent) : QxtAbstractHttpConnector(parent)
|
||||
{
|
||||
QXT_INIT_PRIVATE(QxtScgiServerConnector);
|
||||
qxt_d().server = new QTcpServer(this);
|
||||
QObject::connect(qxt_d().server, SIGNAL(newConnection()), this, SLOT(acceptConnection()));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
bool QxtScgiServerConnector::listen(const QHostAddress& iface, quint16 port)
|
||||
{
|
||||
return qxt_d().server->listen(iface, port);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void QxtScgiServerConnector::acceptConnection()
|
||||
{
|
||||
QTcpSocket* socket = qxt_d().server->nextPendingConnection();
|
||||
addConnection(socket);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
bool QxtScgiServerConnector::canParseRequest(const QByteArray& buffer)
|
||||
{
|
||||
if (buffer.size() < 10)
|
||||
return false;
|
||||
QString expectedsize;
|
||||
for (int i = 0;i < 10;i++)
|
||||
{
|
||||
if (buffer.at(i) == ':')
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
expectedsize += buffer.at(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (expectedsize.isEmpty())
|
||||
{
|
||||
//protocoll error
|
||||
return false;
|
||||
}
|
||||
|
||||
return (buffer.size() > expectedsize.toInt());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
QHttpRequestHeader QxtScgiServerConnector::parseRequest(QByteArray& buffer)
|
||||
{
|
||||
QString expectedsize_s;
|
||||
for (int i = 0;i < 20;i++)
|
||||
{
|
||||
if (buffer.at(i) == ':')
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
expectedsize_s += buffer.at(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (expectedsize_s.isEmpty())
|
||||
{
|
||||
//protocoll error
|
||||
return QHttpRequestHeader();
|
||||
}
|
||||
|
||||
|
||||
buffer = buffer.right(buffer.size() - (expectedsize_s.count() + 1));
|
||||
|
||||
|
||||
QHttpRequestHeader request_m;
|
||||
|
||||
QByteArray name;
|
||||
int i = 0;
|
||||
while ((i = buffer.indexOf('\0')) > -1)
|
||||
{
|
||||
if (name.isEmpty())
|
||||
{
|
||||
name = buffer.left(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
request_m.setValue(QString::fromAscii(name).toLower(), QString::fromAscii(buffer.left(i)));
|
||||
name = "";
|
||||
}
|
||||
buffer = buffer.mid(i + 1);
|
||||
}
|
||||
|
||||
|
||||
request_m.setRequest(request_m.value("request_method"), request_m.value("request_uri"), 1, 0);
|
||||
|
||||
|
||||
foreach(const QString& key, request_m.keys())
|
||||
{
|
||||
if (key.startsWith(QString("http_")))
|
||||
{
|
||||
request_m.setValue(key.right(key.size() - 5), request_m.value(key));
|
||||
}
|
||||
}
|
||||
|
||||
request_m.setValue("Connection", "close");
|
||||
|
||||
|
||||
buffer.chop(1);
|
||||
|
||||
|
||||
return request_m;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
void QxtScgiServerConnector::writeHeaders(QIODevice* device, const QHttpResponseHeader& response_m)
|
||||
{
|
||||
|
||||
device->write(("Status:" + QString::number(response_m.statusCode()) + ' ' + response_m.reasonPhrase() + "\r\n").toAscii());
|
||||
|
||||
foreach(const QString& key, response_m.keys())
|
||||
{
|
||||
device->write((key + ':' + response_m.value(key) + "\r\n").toAscii());
|
||||
}
|
||||
device->write("\r\n");
|
||||
}
|
39
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtweb.h
vendored
Normal file
39
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtweb.h
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtWeb module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
#ifndef QXTWEB_H_INCLUDED
|
||||
#define QXTWEB_H_INCLUDED
|
||||
|
||||
#include "qxtabstracthttpconnector.h"
|
||||
#include "qxtabstractwebservice.h"
|
||||
#include "qxtabstractwebsessionmanager.h"
|
||||
#include "qxtwebcgiservice.h"
|
||||
#include "qxthtmltemplate.h"
|
||||
#include "qxthttpsessionmanager.h"
|
||||
#include "qxtwebcontent.h"
|
||||
#include "qxtwebevent.h"
|
||||
#include "qxtwebservicedirectory.h"
|
||||
#include "qxtwebslotservice.h"
|
||||
|
||||
#endif // QXTWEB_H_INCLUDED
|
427
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtwebcgiservice.cpp
vendored
Normal file
427
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtwebcgiservice.cpp
vendored
Normal file
@@ -0,0 +1,427 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtWeb module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\class QxtWebCgiService
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtWebCgiService class provides a CGI/1.1 gateway for QxtWeb
|
||||
|
||||
TODO: write docs
|
||||
TODO: implement timeout
|
||||
*/
|
||||
|
||||
#include "qxtwebcgiservice.h"
|
||||
#include "qxtwebcgiservice_p.h"
|
||||
#include "qxtwebevent.h"
|
||||
#include "qxtwebcontent.h"
|
||||
#include <QMap>
|
||||
#include <QFile>
|
||||
#include <QProcess>
|
||||
#include <QtDebug>
|
||||
|
||||
QxtCgiRequestInfo::QxtCgiRequestInfo() : sessionID(0), requestID(0), eventSent(false), terminateSent(false) {}
|
||||
QxtCgiRequestInfo::QxtCgiRequestInfo(QxtWebRequestEvent* req) : sessionID(req->sessionID), requestID(req->requestID), eventSent(false), terminateSent(false) {}
|
||||
|
||||
/*!
|
||||
* Constructs a QxtWebCgiService object with the specified session \a manager and \a parent.
|
||||
* This service will invoke the specified \a binary to handle incoming requests.
|
||||
*
|
||||
* Often, the session manager will also be the parent, but this is not a requirement.
|
||||
*/
|
||||
QxtWebCgiService::QxtWebCgiService(const QString& binary, QxtAbstractWebSessionManager* manager, QObject* parent) : QxtAbstractWebService(manager, parent)
|
||||
{
|
||||
QXT_INIT_PRIVATE(QxtWebCgiService);
|
||||
qxt_d().binary = binary;
|
||||
QObject::connect(&qxt_d().timeoutMapper, SIGNAL(mapped(QObject*)), &qxt_d(), SLOT(terminateProcess(QObject*)));
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the path to the CGI script that will be executed to handle requests.
|
||||
*
|
||||
* \sa setBinary()
|
||||
*/
|
||||
QString QxtWebCgiService::binary() const
|
||||
{
|
||||
return qxt_d().binary;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Sets the path to the CGI script \a bin that will be executed to handle requests.
|
||||
*
|
||||
* \sa binary()
|
||||
*/
|
||||
void QxtWebCgiService::setBinary(const QString& bin)
|
||||
{
|
||||
if (!QFile::exists(bin) || !(QFile::permissions(bin) & (QFile::ExeUser | QFile::ExeGroup | QFile::ExeOther)))
|
||||
{
|
||||
qWarning() << "QxtWebCgiService::setBinary: " + bin + " does not appear to be executable.";
|
||||
}
|
||||
qxt_d().binary = bin;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the maximum time a CGI script may execute, in milliseconds.
|
||||
*
|
||||
* The default value is 0, which indicates that CGI scripts will not be terminated
|
||||
* due to long running times.
|
||||
*
|
||||
* \sa setTimeout()
|
||||
*/
|
||||
int QxtWebCgiService::timeout() const
|
||||
{
|
||||
return qxt_d().timeout;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Sets the maximum \a time a CGI script may execute, in milliseconds.
|
||||
*
|
||||
* The timer is started when the script is launched. After the timeout elapses once,
|
||||
* the script will be asked to stop, as QProcess::terminate(). (That is, the script
|
||||
* will receive WM_CLOSE on Windows or SIGTERM on UNIX.) If the process has still
|
||||
* failed to terminate after another timeout, it will be forcibly terminated, as
|
||||
* QProcess::kill(). (That is, the script will receive TerminateProcess on Windows
|
||||
* or SIGKILL on UNIX.)
|
||||
*
|
||||
* Set the timeout to 0 to disable this behavior; scripts will not be terminated
|
||||
* due to excessive run time. This is the default behavior.
|
||||
*
|
||||
* CAUTION: Keep in mind that the timeout applies to the real running time of the
|
||||
* script, not processor time used. A script that initiates a lengthy download
|
||||
* may be interrupted while transferring data to the web browser. To avoid this
|
||||
* behavior, see the timeoutOverride property to allow the script to request
|
||||
* an extended timeout, or use a different QxtAbstractWebService object for
|
||||
* serving streaming content or large files.
|
||||
*
|
||||
*
|
||||
* \sa timeout(), timeoutOverride(), setTimeoutOverride(), QProcess::terminate(), QProcess::kill()
|
||||
*/
|
||||
void QxtWebCgiService::setTimeout(int time)
|
||||
{
|
||||
qxt_d().timeout = time;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns whether or not to allow scripts to override the timeout.
|
||||
*
|
||||
* \sa setTimeoutOverride(), setTimeout()
|
||||
*/
|
||||
bool QxtWebCgiService::timeoutOverride() const
|
||||
{
|
||||
return qxt_d().timeoutOverride;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Sets whether or not to allow scripts to override the timeout.
|
||||
* Scripts are allowed to override if \a enable is \c true.
|
||||
*
|
||||
* As an extension to the CGI/1.1 gateway specification, a CGI script may
|
||||
* output a "X-QxtWeb-Timeout" header to change the termination timeout
|
||||
* on a per-script basis. Only enable this option if you trust the scripts
|
||||
* being executed.
|
||||
*
|
||||
* \sa timeoutOverride(), setTimeout()
|
||||
*/
|
||||
void QxtWebCgiService::setTimeoutOverride(bool enable)
|
||||
{
|
||||
qxt_d().timeoutOverride = enable;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
void QxtWebCgiService::pageRequestedEvent(QxtWebRequestEvent* event)
|
||||
{
|
||||
// Create the process object and initialize connections
|
||||
QProcess* process = new QProcess(this);
|
||||
qxt_d().requests[process] = QxtCgiRequestInfo(event);
|
||||
qxt_d().processes[event->content] = process;
|
||||
QxtCgiRequestInfo& requestInfo = qxt_d().requests[process];
|
||||
QObject::connect(process, SIGNAL(readyRead()), &qxt_d(), SLOT(processReadyRead()));
|
||||
QObject::connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), &qxt_d(), SLOT(processFinished()));
|
||||
QObject::connect(process, SIGNAL(error(QProcess::ProcessError)), &qxt_d(), SLOT(processFinished()));
|
||||
requestInfo.timeout = new QTimer(process);
|
||||
qxt_d().timeoutMapper.setMapping(requestInfo.timeout, process);
|
||||
QObject::connect(requestInfo.timeout, SIGNAL(timeout()), &qxt_d().timeoutMapper, SLOT(map()));
|
||||
|
||||
// Initialize the system environment
|
||||
QStringList s_env = process->systemEnvironment();
|
||||
QMap<QString, QString> env;
|
||||
foreach(const QString& entry, s_env)
|
||||
{
|
||||
int pos = entry.indexOf('=');
|
||||
env[entry.left(pos)] = entry.mid(pos + 1);
|
||||
}
|
||||
|
||||
// Populate CGI/1.1 environment variables
|
||||
env["SERVER_SOFTWARE"] = QString("QxtWeb/" QXT_VERSION_STR);
|
||||
env["SERVER_NAME"] = event->url.host();
|
||||
env["GATEWAY_INTERFACE"] = "CGI/1.1";
|
||||
if (event->headers.contains("X-Request-Protocol"))
|
||||
env["SERVER_PROTOCOL"] = event->headers.value("X-Request-Protocol");
|
||||
else
|
||||
env.remove("SERVER_PROTOCOL");
|
||||
if (event->url.port() != -1)
|
||||
env["SERVER_PORT"] = QString::number(event->url.port());
|
||||
else
|
||||
env.remove("SERVER_PORT");
|
||||
env["REQUEST_METHOD"] = event->method;
|
||||
env["PATH_INFO"] = event->url.path();
|
||||
env["PATH_TRANSLATED"] = event->url.path(); // CGI/1.1 says we should resolve this, but we have no logical interpretation
|
||||
env["SCRIPT_NAME"] = event->originalUrl.path().remove(QRegExp(QRegExp::escape(event->url.path()) + '$'));
|
||||
env["SCRIPT_FILENAME"] = qxt_d().binary; // CGI/1.1 doesn't define this but PHP demands it
|
||||
env.remove("REMOTE_HOST");
|
||||
env["REMOTE_ADDR"] = event->remoteAddress;
|
||||
// TODO: If we ever support HTTP authentication, we should use these
|
||||
env.remove("AUTH_TYPE");
|
||||
env.remove("REMOTE_USER");
|
||||
env.remove("REMOTE_IDENT");
|
||||
if (event->contentType.isEmpty())
|
||||
{
|
||||
env.remove("CONTENT_TYPE");
|
||||
env.remove("CONTENT_LENGTH");
|
||||
}
|
||||
else
|
||||
{
|
||||
env["CONTENT_TYPE"] = event->contentType;
|
||||
env["CONTENT_LENGTH"] = QString::number(event->content->unreadBytes());
|
||||
}
|
||||
env["QUERY_STRING"] = event->url.encodedQuery();
|
||||
|
||||
// Populate HTTP header environment variables
|
||||
QMultiHash<QString, QString>::const_iterator iter = event->headers.begin();
|
||||
while (iter != event->headers.end())
|
||||
{
|
||||
QString key = "HTTP_" + iter.key().toUpper().replace('-', '_');
|
||||
if (key != "HTTP_CONTENT_TYPE" && key != "HTTP_CONTENT_LENGTH")
|
||||
env[key] = iter.value();
|
||||
iter++;
|
||||
}
|
||||
|
||||
// Populate HTTP_COOKIE parameter
|
||||
iter = event->cookies.begin();
|
||||
QString cookies;
|
||||
while (iter != event->cookies.end())
|
||||
{
|
||||
if (!cookies.isEmpty())
|
||||
cookies += "; ";
|
||||
cookies += iter.key() + '=' + iter.value();
|
||||
iter++;
|
||||
}
|
||||
if (!cookies.isEmpty())
|
||||
env["HTTP_COOKIE"] = cookies;
|
||||
|
||||
// Load environment into process space
|
||||
QStringList p_env;
|
||||
QMap<QString, QString>::iterator env_iter = env.begin();
|
||||
while (env_iter != env.end())
|
||||
{
|
||||
p_env << env_iter.key() + '=' + env_iter.value();
|
||||
env_iter++;
|
||||
}
|
||||
process->setEnvironment(p_env);
|
||||
|
||||
// Launch process
|
||||
if (event->url.hasQuery() && event->url.encodedQuery().contains('='))
|
||||
{
|
||||
// CGI/1.1 spec says to pass the query on the command line if there's no embedded = sign
|
||||
process->start(qxt_d().binary + ' ' + QUrl::fromPercentEncoding(event->url.encodedQuery()), QIODevice::ReadWrite);
|
||||
}
|
||||
else
|
||||
{
|
||||
process->start(qxt_d().binary, QIODevice::ReadWrite);
|
||||
}
|
||||
|
||||
// Start the timeout
|
||||
if(qxt_d().timeout > 0)
|
||||
{
|
||||
requestInfo.timeout->start(qxt_d().timeout);
|
||||
}
|
||||
|
||||
// Transmit POST data
|
||||
if (event->content)
|
||||
{
|
||||
QObject::connect(event->content, SIGNAL(readyRead()), &qxt_d(), SLOT(browserReadyRead()));
|
||||
qxt_d().browserReadyRead(event->content);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void QxtWebCgiServicePrivate::browserReadyRead(QObject* o_content)
|
||||
{
|
||||
if (!o_content) o_content = sender();
|
||||
QxtWebContent* content = static_cast<QxtWebContent*>(o_content); // this is a private class, no worries about type safety
|
||||
|
||||
// Read POST data and copy it to the process
|
||||
QByteArray data = content->readAll();
|
||||
if (!data.isEmpty())
|
||||
processes[content]->write(data);
|
||||
|
||||
// If no POST data remains unsent, clean up
|
||||
if (!content->unreadBytes() && processes.contains(content))
|
||||
{
|
||||
processes[content]->closeWriteChannel();
|
||||
processes.remove(content);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void QxtWebCgiServicePrivate::processReadyRead()
|
||||
{
|
||||
QProcess* process = static_cast<QProcess*>(sender());
|
||||
QxtCgiRequestInfo& request = requests[process];
|
||||
|
||||
QByteArray line;
|
||||
while (process->canReadLine())
|
||||
{
|
||||
// Read in a CGI/1.1 header line
|
||||
line = process->readLine().replace(QByteArray("\r"), ""); //krazy:exclude=doublequote_chars
|
||||
if (line == "\n")
|
||||
{
|
||||
// An otherwise-empty line indicates the end of CGI/1.1 headers and the start of content
|
||||
QObject::disconnect(process, SIGNAL(readyRead()), this, 0);
|
||||
QxtWebPageEvent* event = 0;
|
||||
int code = 200;
|
||||
if (request.headers.contains("status"))
|
||||
{
|
||||
// CGI/1.1 defines a "Status:" header that dictates the HTTP response code
|
||||
code = request.headers["status"].left(3).toInt();
|
||||
if (code >= 300 && code < 400) // redirect
|
||||
{
|
||||
event = new QxtWebRedirectEvent(request.sessionID, request.requestID, request.headers["location"], code);
|
||||
}
|
||||
}
|
||||
// If a previous header (currently just status) hasn't created an event, create a normal page event here
|
||||
if (!event)
|
||||
{
|
||||
event = new QxtWebPageEvent(request.sessionID, request.requestID, QSharedPointer<QIODevice>(process) );
|
||||
event->status = code;
|
||||
}
|
||||
// Add other response headers passed from CGI (currently only Content-Type is supported)
|
||||
if (request.headers.contains("content-type"))
|
||||
event->contentType = request.headers["content-type"].toUtf8();
|
||||
// TODO: QxtWeb doesn't support transmitting arbitrary HTTP headers right now, but it may be desirable
|
||||
// for applications that know what kind of server frontend they're using to allow scripts to send
|
||||
// protocol-specific headers.
|
||||
|
||||
// Post the event
|
||||
qxt_p().postEvent(event);
|
||||
request.eventSent = true;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Since we haven't reached the end of headers yet, parse a header
|
||||
int pos = line.indexOf(": ");
|
||||
QByteArray hdrName = line.left(pos).toLower();
|
||||
QByteArray hdrValue = line.mid(pos + 2).replace(QByteArray("\n"), ""); //krazy:exclude=doublequote_chars
|
||||
if (hdrName == "set-cookie")
|
||||
{
|
||||
// Parse a new cookie and post an event to send it to the client
|
||||
QList<QByteArray> cookies = hdrValue.split(',');
|
||||
foreach(const QByteArray& cookie, cookies)
|
||||
{
|
||||
int equals = cookie.indexOf("=");
|
||||
int semi = cookie.indexOf(";");
|
||||
QByteArray cookieName = cookie.left(equals);
|
||||
int age = cookie.toLower().indexOf("max-age=", semi);
|
||||
int secs = -1;
|
||||
if (age >= 0)
|
||||
secs = cookie.mid(age + 8, cookie.indexOf(";", age) - age - 8).toInt();
|
||||
if (secs == 0)
|
||||
{
|
||||
qxt_p().postEvent(new QxtWebRemoveCookieEvent(request.sessionID, cookieName));
|
||||
}
|
||||
else
|
||||
{
|
||||
QByteArray cookieValue = cookie.mid(equals + 1, semi - equals - 1);
|
||||
QDateTime cookieExpires;
|
||||
if (secs != -1)
|
||||
cookieExpires = QDateTime::currentDateTime().addSecs(secs);
|
||||
qxt_p().postEvent(new QxtWebStoreCookieEvent(request.sessionID, cookieName, cookieValue, cookieExpires));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(hdrName == "x-qxtweb-timeout")
|
||||
{
|
||||
if(timeoutOverride)
|
||||
request.timeout->setInterval(hdrValue.toInt());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Store other headers for later inspection
|
||||
request.headers[hdrName] = hdrValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void QxtWebCgiServicePrivate::processFinished()
|
||||
{
|
||||
QProcess* process = static_cast<QProcess*>(sender());
|
||||
QxtCgiRequestInfo& request = requests[process];
|
||||
|
||||
if (!request.eventSent)
|
||||
{
|
||||
// If no event was posted, issue an internal error
|
||||
qxt_p().postEvent(new QxtWebErrorEvent(request.sessionID, request.requestID, 500, "Internal Server Error"));
|
||||
}
|
||||
|
||||
// Clean up data structures
|
||||
process->close();
|
||||
QxtWebContent* key = processes.key(process);
|
||||
if (key) processes.remove(key);
|
||||
timeoutMapper.removeMappings(request.timeout);
|
||||
requests.remove(process);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void QxtWebCgiServicePrivate::terminateProcess(QObject* o_process)
|
||||
{
|
||||
QProcess* process = static_cast<QProcess*>(o_process);
|
||||
QxtCgiRequestInfo& request = requests[process];
|
||||
|
||||
if(request.terminateSent)
|
||||
{
|
||||
// kill with fire
|
||||
process->kill();
|
||||
}
|
||||
else
|
||||
{
|
||||
// kill nicely
|
||||
process->terminate();
|
||||
request.terminateSent = true;
|
||||
}
|
||||
}
|
58
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtwebcgiservice.h
vendored
Normal file
58
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtwebcgiservice.h
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtWeb module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QXTWEBCGISERVICE_H
|
||||
#define QXTWEBCGISERVICE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <qxtglobal.h>
|
||||
#include "qxtabstractwebsessionmanager.h"
|
||||
#include "qxtabstractwebservice.h"
|
||||
class QxtWebEvent;
|
||||
class QxtWebRequestEvent;
|
||||
|
||||
class QxtWebCgiServicePrivate;
|
||||
class QXT_WEB_EXPORT QxtWebCgiService : public QxtAbstractWebService
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QxtWebCgiService(const QString& binary, QxtAbstractWebSessionManager* manager, QObject* parent = 0);
|
||||
|
||||
QString binary() const;
|
||||
void setBinary(const QString& bin);
|
||||
|
||||
int timeout() const;
|
||||
void setTimeout(int time);
|
||||
|
||||
bool timeoutOverride() const;
|
||||
void setTimeoutOverride(bool enable);
|
||||
|
||||
virtual void pageRequestedEvent(QxtWebRequestEvent* event);
|
||||
|
||||
private:
|
||||
QXT_DECLARE_PRIVATE(QxtWebCgiService)
|
||||
};
|
||||
|
||||
#endif // QXTWEBCGISERVICE_H
|
71
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtwebcgiservice_p.h
vendored
Normal file
71
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtwebcgiservice_p.h
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtWeb module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QXTWEBCGISERVICE_P_H
|
||||
#define QXTWEBCGISERVICE_P_H
|
||||
|
||||
#include "qxtwebcgiservice.h"
|
||||
#include <QString>
|
||||
#include <QHash>
|
||||
#include <QPair>
|
||||
#include <QTimer>
|
||||
#include <QSignalMapper>
|
||||
|
||||
#ifndef QXT_DOXYGEN_RUN
|
||||
QT_FORWARD_DECLARE_CLASS(QProcess)
|
||||
class QxtWebContent;
|
||||
|
||||
struct QxtCgiRequestInfo
|
||||
{
|
||||
QxtCgiRequestInfo();
|
||||
QxtCgiRequestInfo(QxtWebRequestEvent* req);
|
||||
int sessionID, requestID;
|
||||
QHash<QString, QString> headers;
|
||||
bool eventSent, terminateSent;
|
||||
QTimer* timeout;
|
||||
};
|
||||
|
||||
class QxtWebCgiServicePrivate : public QObject, public QxtPrivate<QxtWebCgiService>
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QXT_DECLARE_PUBLIC(QxtWebCgiService)
|
||||
|
||||
QHash<QProcess*, QxtCgiRequestInfo> requests;
|
||||
QHash<QxtWebContent*, QProcess*> processes;
|
||||
QString binary;
|
||||
int timeout;
|
||||
bool timeoutOverride;
|
||||
QSignalMapper timeoutMapper;
|
||||
|
||||
public Q_SLOTS:
|
||||
void browserReadyRead(QObject* o_content = 0);
|
||||
void processReadyRead();
|
||||
void processFinished();
|
||||
void terminateProcess(QObject* o_process);
|
||||
};
|
||||
#endif // QXT_DOXYGEN_RUN
|
||||
|
||||
#endif // QXTWEBSERVICEDIRECTORY_P_H
|
259
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtwebcontent.cpp
vendored
Normal file
259
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtwebcontent.cpp
vendored
Normal file
@@ -0,0 +1,259 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtWeb module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\class QxtWebContent
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtWebContent class provides and I/O device for data sent by the web browser
|
||||
|
||||
QxtWebContent is a read-only QIODevice subclass that encapsulates data sent
|
||||
from the web browser, for instance in a POST or PUT request.
|
||||
|
||||
In order to avoid delays while reading content sent from the client, and to
|
||||
insulate multiple pipelined requests on the same connection from each other,
|
||||
QxtWeb uses QxtWebContent as an abstraction for streaming data.
|
||||
|
||||
\sa QxtAbstractWebService
|
||||
*/
|
||||
|
||||
#include "qxtwebcontent.h"
|
||||
#include <string.h>
|
||||
#include <QUrl>
|
||||
|
||||
#ifndef QXT_DOXYGEN_RUN
|
||||
class QxtWebContentPrivate : public QxtPrivate<QxtWebContent>
|
||||
{
|
||||
public:
|
||||
QxtWebContentPrivate() : ignoreRemaining(false) {}
|
||||
QXT_DECLARE_PUBLIC(QxtWebContent)
|
||||
|
||||
void init(int contentLength, const QByteArray& start, QIODevice* device)
|
||||
{
|
||||
this->start = start;
|
||||
this->device = device;
|
||||
if (contentLength <= 0)
|
||||
bytesRemaining = -1;
|
||||
else
|
||||
bytesRemaining = contentLength - start.length();
|
||||
if (device)
|
||||
{
|
||||
QObject::connect(device, SIGNAL(readyRead()), &qxt_p(), SIGNAL(readyRead()));
|
||||
// QObject::connect(device, SIGNAL(aboutToClose()), this, SIGNAL(aboutToClose()));
|
||||
// QObject::connect(device, SIGNAL(destroyed()), this, SIGNAL(aboutToClose()));
|
||||
// ask the object if it has an error signal
|
||||
if (device->metaObject()->indexOfSignal(QMetaObject::normalizedSignature(SIGNAL(error(QAbstractSocket::SocketError)))) >= 0)
|
||||
{
|
||||
QObject::connect(device, SIGNAL(error(QAbstractSocket::SocketError)), &qxt_p(), SLOT(errorReceived(QAbstractSocket::SocketError)));
|
||||
}
|
||||
}
|
||||
qxt_p().setOpenMode(QIODevice::ReadOnly);
|
||||
}
|
||||
|
||||
qint64 bytesRemaining;
|
||||
QByteArray start;
|
||||
QIODevice* device;
|
||||
bool ignoreRemaining;
|
||||
};
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Constructs a QxtWebContent object.
|
||||
*
|
||||
* The content provided by this constructor is the first \a contentLength bytes
|
||||
* read from the provided \a device.
|
||||
*
|
||||
* The QxtWebContent object is parented to the \a device.
|
||||
*/
|
||||
QxtWebContent::QxtWebContent(int contentLength, QIODevice* device) : QIODevice(device)
|
||||
{
|
||||
QXT_INIT_PRIVATE(QxtWebContent);
|
||||
qxt_d().init(contentLength, QByteArray(), device);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Constructs a QxtWebContent object.
|
||||
*
|
||||
* The content provided by this constructor is the data contained in \a start,
|
||||
* followed by enough data read from the provided \a device to fill the desired
|
||||
* \a contentLength.
|
||||
*
|
||||
* The QxtWebContent object is parented to the \a device.
|
||||
*/
|
||||
QxtWebContent::QxtWebContent(int contentLength, const QByteArray& start, QIODevice* device) : QIODevice(device)
|
||||
{
|
||||
QXT_INIT_PRIVATE(QxtWebContent);
|
||||
qxt_d().init(contentLength, start, device);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Constructs a QxtWebContent object with the specified \a parent.
|
||||
*
|
||||
* The content provided by this constructor is exactly the data contained in
|
||||
* \a content.
|
||||
*/
|
||||
QxtWebContent::QxtWebContent(const QByteArray& content, QObject* parent) : QIODevice(parent)
|
||||
{
|
||||
QXT_INIT_PRIVATE(QxtWebContent);
|
||||
qxt_d().init(content.size(), content, 0);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
qint64 QxtWebContent::bytesAvailable() const
|
||||
{
|
||||
qint64 available = QIODevice::bytesAvailable() + (qxt_d().device ? qxt_d().device->bytesAvailable() : 0) + qxt_d().start.count();
|
||||
if (available > qxt_d().bytesRemaining)
|
||||
return qxt_d().bytesRemaining;
|
||||
return available;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
qint64 QxtWebContent::readData(char* data, qint64 maxSize)
|
||||
{
|
||||
char* writePtr = data;
|
||||
// read more than 32k; TCP ideally handles 48k blocks but we need wiggle room
|
||||
if (maxSize > 32768) maxSize = 32768;
|
||||
|
||||
// don't read more than the content-length
|
||||
int sz = qxt_d().start.count();
|
||||
if (sz > 0 && maxSize > sz)
|
||||
{
|
||||
memcpy(writePtr, qxt_d().start.constData(), sz);
|
||||
writePtr += sz;
|
||||
maxSize -= sz;
|
||||
qxt_d().start.clear();
|
||||
}
|
||||
else if (sz > 0 && sz > maxSize)
|
||||
{
|
||||
memcpy(writePtr, qxt_d().start.constData(), maxSize);
|
||||
qxt_d().start = qxt_d().start.mid(maxSize);
|
||||
return maxSize;
|
||||
}
|
||||
|
||||
if (qxt_d().device == 0)
|
||||
{
|
||||
return sz;
|
||||
}
|
||||
else if (qxt_d().bytesRemaining >= 0)
|
||||
{
|
||||
qint64 readBytes = qxt_d().device->read(writePtr, (maxSize > qxt_d().bytesRemaining) ? qxt_d().bytesRemaining : maxSize);
|
||||
qxt_d().bytesRemaining -= readBytes;
|
||||
if (qxt_d().bytesRemaining == 0) QMetaObject::invokeMethod(this, "aboutToClose", Qt::QueuedConnection);
|
||||
return sz + readBytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
return sz + qxt_d().device->read(writePtr, maxSize);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the number of bytes of content that have not yet been read.
|
||||
*
|
||||
* Note that not all of the remaining content may be immediately available for
|
||||
* reading. This function returns the content length, minus the number of
|
||||
* bytes that have already been read.
|
||||
*/
|
||||
qint64 QxtWebContent::unreadBytes() const
|
||||
{
|
||||
return qxt_d().start.size() + qxt_d().bytesRemaining;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
qint64 QxtWebContent::writeData(const char*, qint64)
|
||||
{
|
||||
// always an error to write
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void QxtWebContent::errorReceived(QAbstractSocket::SocketError)
|
||||
{
|
||||
setErrorString(qxt_d().device->errorString());
|
||||
}
|
||||
|
||||
/*!
|
||||
* Blocks until all of the streaming data has been read from the browser.
|
||||
*
|
||||
* Note that this function will block events for the thread on which it is called.
|
||||
* If the main thread is blocked, QxtWeb will be unable to process additional
|
||||
* requests until the content has been received.
|
||||
*/
|
||||
void QxtWebContent::waitForAllContent()
|
||||
{
|
||||
if (!qxt_d().device) return;
|
||||
QByteArray buffer;
|
||||
while (qxt_d().device && qxt_d().bytesRemaining > 0)
|
||||
{
|
||||
buffer = qxt_d().device->readAll();
|
||||
qxt_d().start += buffer;
|
||||
qxt_d().bytesRemaining -= buffer.size();
|
||||
if (qxt_d().bytesRemaining > 0) qxt_d().device->waitForReadyRead(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Discards any data not yet read.
|
||||
*
|
||||
* After invoking this function, any further data received from the browser
|
||||
* is silently discarded.
|
||||
*/
|
||||
void QxtWebContent::ignoreRemainingContent()
|
||||
{
|
||||
if (qxt_d().bytesRemaining <= 0 || !qxt_d().device) return;
|
||||
if (!qxt_d().ignoreRemaining)
|
||||
{
|
||||
qxt_d().ignoreRemaining = true;
|
||||
QObject::connect(qxt_d().device, SIGNAL(readyRead()), this, SLOT(ignoreRemainingContent()));
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef QXT_DOXYGEN_RUN
|
||||
typedef QPair<QString, QString> QxtQueryItem;
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Extracts the key/value pairs from application/x-www-form-urlencoded \a data,
|
||||
* such as the query string from the URL or the form data from a POST request.
|
||||
*/
|
||||
QHash<QString, QString> QxtWebContent::parseUrlEncodedQuery(const QString& data)
|
||||
{
|
||||
QUrl post("/?" + data);
|
||||
QHash<QString, QString> rv;
|
||||
foreach(const QxtQueryItem& item, post.queryItems())
|
||||
{
|
||||
rv.insertMulti(item.first, item.second);
|
||||
}
|
||||
return rv;
|
||||
}
|
63
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtwebcontent.h
vendored
Normal file
63
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtwebcontent.h
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtWeb module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QXTWEBCONTENT_H
|
||||
#define QXTWEBCONTENT_H
|
||||
|
||||
#include <QAbstractSocket>
|
||||
#include <QByteArray>
|
||||
#include <QHash>
|
||||
#include <qxtglobal.h>
|
||||
|
||||
class QxtWebContentPrivate;
|
||||
class QXT_WEB_EXPORT QxtWebContent : public QIODevice
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QxtWebContent(int contentLength, const QByteArray& start, QIODevice* device);
|
||||
QxtWebContent(int contentLength, QIODevice* device);
|
||||
explicit QxtWebContent(const QByteArray& content, QObject* parent = 0);
|
||||
static QHash<QString, QString> parseUrlEncodedQuery(const QString& data);
|
||||
|
||||
virtual qint64 bytesAvailable() const;
|
||||
qint64 unreadBytes() const;
|
||||
|
||||
void waitForAllContent();
|
||||
|
||||
public Q_SLOTS:
|
||||
void ignoreRemainingContent();
|
||||
|
||||
protected:
|
||||
virtual qint64 readData(char* data, qint64 maxSize);
|
||||
virtual qint64 writeData(const char* data, qint64 maxSize);
|
||||
|
||||
private Q_SLOTS:
|
||||
void errorReceived(QAbstractSocket::SocketError);
|
||||
|
||||
private:
|
||||
QXT_DECLARE_PRIVATE(QxtWebContent)
|
||||
};
|
||||
|
||||
#endif // QXTWEBCONTENT_H
|
401
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtwebevent.cpp
vendored
Normal file
401
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtwebevent.cpp
vendored
Normal file
@@ -0,0 +1,401 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtWeb module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qxtwebevent.h"
|
||||
#include "qxtwebcontent.h"
|
||||
#include <QBuffer>
|
||||
|
||||
/*!
|
||||
\class QxtWebEvent
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtWebEvent class is a base class of all QxtWeb event types
|
||||
|
||||
QxtWebEvent is the base class for all QxtWeb event classes. Event objects
|
||||
contain event parameters.
|
||||
|
||||
The base QxtWebEvent class contains the type of the event and a session ID for
|
||||
the session it relates to. Subclasses of QxtWebEvent contain additional
|
||||
parameters describing the particular event.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\enum QxtWebEvent::EventType
|
||||
|
||||
\value None Not an event.
|
||||
\value Request A request event.
|
||||
\value FileUpload A file upload event.
|
||||
\value Page A page event.
|
||||
\value StoreCookie A store cookie event.
|
||||
\value RemoveCookie A remove cookie event.
|
||||
\value Redirect A redirect event.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Constructs a QxtWebEvent of the specified \a type for the specified \a sessionID.
|
||||
*/
|
||||
QxtWebEvent::QxtWebEvent(EventType type, int sessionID)
|
||||
: sessionID(sessionID), m_type(type) {}
|
||||
|
||||
/*!
|
||||
* Destroys the event.
|
||||
*/
|
||||
QxtWebEvent::~QxtWebEvent() {}
|
||||
|
||||
/*!
|
||||
* \fn EventType QxtWebEvent::type() const
|
||||
* Returns the event type.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebEvent::sessionID
|
||||
* Contains the ID of the session the event is related to.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\class QxtWebRequestEvent
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtWebRequestEvent class describes a request from a web browser
|
||||
|
||||
The QxtWebRequestEvent class contains information about a request from a web
|
||||
browser.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Constructs a QxtWebRequestEvent for the specified \a sessionID, \a requestID and \a url.
|
||||
*/
|
||||
QxtWebRequestEvent::QxtWebRequestEvent(int sessionID, int requestID, const QUrl& url)
|
||||
: QxtWebEvent(QxtWebEvent::Request, sessionID), requestID(requestID), url(url), originalUrl(url) {}
|
||||
|
||||
/*!
|
||||
* Destroys the event and any content that may still be associated with it.
|
||||
*/
|
||||
QxtWebRequestEvent::~QxtWebRequestEvent()
|
||||
{
|
||||
if (content) delete content;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \variable QxtWebRequestEvent::requestID
|
||||
* Contains an opaque value generated by the session manager. This request ID
|
||||
* must be included in the QxtWebPageEvent or QxtWebPageEvent subclass that
|
||||
* is the response to the request.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebRequestEvent::url
|
||||
* Contains the request URL, possibly after rewriting by intermediate services
|
||||
* such as QxtWebServiceDirectory.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebRequestEvent::originalUrl
|
||||
* Contains the request URL exactly as it was sent from the web browser.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebRequestEvent::contentType
|
||||
* Contains the MIME type of the request body, if present.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebRequestEvent::content
|
||||
* Contains the content of the request body, if present.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebRequestEvent::cookies
|
||||
* Contains all of the cookies sent by the web browser.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebRequestEvent::headers
|
||||
* Contains all of the headers sent by the web browser.
|
||||
*
|
||||
* Note that use of these values may not be portable across session maangers.
|
||||
*/
|
||||
|
||||
/*
|
||||
QxtWebFileUploadEvent::QxtWebFileUploadEvent(int sessionID)
|
||||
: QxtWebEvent(QxtWebEvent::FileUpload, sessionID) {}
|
||||
*/
|
||||
|
||||
/*!
|
||||
\class QxtWebErrorEvent
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtWebErrorEvent class describes an error condition to be sent to a web browser
|
||||
|
||||
The QxtWebErrorEvent class contains information about an error that will be
|
||||
sent to a web browser.
|
||||
|
||||
QxtWebErrorEvent is a QxtWebPageEvent, so the \a dataSource may be replaced
|
||||
with a custom error page. If you choose to do this, be sure to delete the
|
||||
original data source automatically generated by the constructor first.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Constructs a QxtWebErrorEvent for the specified \a sessionID and \a requestID,
|
||||
* with the provided \a statusCode and \a statusMessage.
|
||||
*
|
||||
* The requestID is an opaque value generated by the session manager; services
|
||||
* will receive this value via QxtWebRequestEvent and must use it in every
|
||||
* event that responds to that request.
|
||||
*/
|
||||
QxtWebErrorEvent::QxtWebErrorEvent(int sessionID, int requestID, int statusCode, QByteArray statusMessage)
|
||||
: QxtWebPageEvent(sessionID, requestID, "<html><body><h1>" + statusMessage + "</h1></body></html>\r\n")
|
||||
{
|
||||
status = statusCode;
|
||||
QxtWebPageEvent::statusMessage = statusMessage;
|
||||
}
|
||||
|
||||
/*!
|
||||
\class QxtWebPageEvent
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtWebPageEvent class describes a web page or other content to be sent to a web browser
|
||||
|
||||
The QxtWebPageEvent class contains information about a web page or other similar
|
||||
content that will be sent to a web browser.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Constructs a QxtWebPageEvent for the specified \a sessionID and \a requestID that will
|
||||
* use the data from \a source as the content to be sent to the web browser.
|
||||
*
|
||||
* The requestID is an opaque value generated by the session manager; services
|
||||
* will receive this value via QxtWebRequestEvent and must use it in every
|
||||
* event that responds to that request.
|
||||
*
|
||||
* QxtWeb takes ownership of the source and will delete it when the response
|
||||
* is completed.
|
||||
*/
|
||||
QxtWebPageEvent::QxtWebPageEvent(int sessionID, int requestID, QSharedPointer<QIODevice> source)
|
||||
: QxtWebEvent(QxtWebEvent::Page, sessionID), dataSource(source), chunked(true), streaming(true), requestID(requestID),
|
||||
status(200), statusMessage("OK"), contentType("text/html") {}
|
||||
|
||||
/*!
|
||||
* Constructs a QxtWebPageEvent for the specified \a sessionID and \a requestID that will
|
||||
* use \a source as the content to be sent to the web browser.
|
||||
*
|
||||
* The requestID is an opaque value generated by the session manager; services
|
||||
* will receive this value via QxtWebRequestEvent and must use it in every
|
||||
* event that responds to that request.
|
||||
*/
|
||||
QxtWebPageEvent::QxtWebPageEvent(int sessionID, int requestID, QByteArray source)
|
||||
: QxtWebEvent(QxtWebEvent::Page, sessionID), chunked(false), streaming(false), requestID(requestID),
|
||||
status(200), statusMessage("OK"), contentType("text/html")
|
||||
{
|
||||
QBuffer* buffer = new QBuffer;
|
||||
buffer->setData(source);
|
||||
buffer->open(QIODevice::ReadOnly);
|
||||
dataSource = QSharedPointer<QIODevice>( buffer );
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
QxtWebPageEvent::QxtWebPageEvent(QxtWebEvent::EventType typeOverride, int sessionID, int requestID, QByteArray source)
|
||||
: QxtWebEvent(typeOverride, sessionID), chunked(false), streaming(false), requestID(requestID),
|
||||
status(200), statusMessage("OK"), contentType("text/html")
|
||||
{
|
||||
QBuffer* buffer = new QBuffer;
|
||||
buffer->setData(source);
|
||||
buffer->open(QIODevice::ReadOnly);
|
||||
dataSource = QSharedPointer<QIODevice>( buffer );
|
||||
}
|
||||
|
||||
/*!
|
||||
* Destroys the event
|
||||
*/
|
||||
QxtWebPageEvent::~QxtWebPageEvent()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
* \variable QxtWebPageEvent::dataSource
|
||||
* Data will be read from this device and relayed to the web browser.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebPageEvent::chunked
|
||||
* If true, and if the web browser supports "chunked" encoding, the content
|
||||
* will be sent using "chunked" encoding. If false, or if the browser does not
|
||||
* support this encoding (for instance, HTTP/0.9 and HTTP/1.0 user agents),
|
||||
* HTTP keep-alive will be disabled.
|
||||
*
|
||||
* The default value is true when using the QIODevice* constructor and false
|
||||
* when using the QByteArray constructor.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebPageEvent::streaming
|
||||
* If true, the data source is considered to be a source of streaming data.
|
||||
* The QIODevice must emit the readyRead() signal when data is available and
|
||||
* must emit aboutToClose() after all data has been transferred. (This can
|
||||
* be accomplished by invoking QIODevice::close() on it after all data is
|
||||
* determined to have been transferred.)
|
||||
*
|
||||
* The default value is true when using the QIODevice* constructor and false
|
||||
* when using the QByteArray constructor. If using a QIODevice that does not
|
||||
* produce streaming data, such as QFile, this \a must be set to false to
|
||||
* ensure correct behavior.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebPageEvent::requestID
|
||||
* Contains the opaque requestID provided by QxtWebRequestEvent.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebPageEvent::status
|
||||
* Contains the HTTP status code that will be sent with the response.
|
||||
*
|
||||
* The default value is 200 ("OK").
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebPageEvent::statusMessage
|
||||
* Contains the human-readable message associated with the HTTP status code
|
||||
* that will be sent with the response.
|
||||
*
|
||||
* The default value is "OK".
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebPageEvent::contentType
|
||||
* Contains the MIME type of the content being sent to the web browser.
|
||||
*
|
||||
* The default value is "text/html".
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebPageEvent::headers
|
||||
* Contains custom headers to be sent to the web browser.
|
||||
*
|
||||
* It is empty by default.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\class QxtWebStoreCookieEvent
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtWebStoreCookieEvent class describes a cookie to be sent to a web browser
|
||||
|
||||
The QxtWebStoreCookieEvent class instructs the session manager to store
|
||||
a cookie on the web browser.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Constructs a QxtWebStoreCookieEvent for the specified \a sessionID that will
|
||||
* store a cookie with the specified \a name and \a data on the web browser.
|
||||
*
|
||||
* If an \a expiration date is supplied, it will be passed to the browser along
|
||||
* with the cookie. The browser will delete the cookie automatically after
|
||||
* the specified date. If an expiration date is not supplied, the cookie will
|
||||
* expire when the browser is closed.
|
||||
*/
|
||||
QxtWebStoreCookieEvent::QxtWebStoreCookieEvent(int sessionID, QString name, QString data, QDateTime expiration)
|
||||
: QxtWebEvent(QxtWebEvent::StoreCookie, sessionID), name(name), data(data), expiration(expiration) {}
|
||||
|
||||
/*!
|
||||
* \variable QxtWebStoreCookieEvent::name
|
||||
* Contains the name of the cookie to be stored.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebStoreCookieEvent::data
|
||||
* Contains the content of the cookie to be stored.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebStoreCookieEvent::expiration
|
||||
* Contains the expiration date of the cookie to be stored. If null, the
|
||||
* cookie will expire when the web browser is closed.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\class QxtWebRemoveCookieEvent
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtWebRemoveCookieEvent class describes a cookie to be deleted from a web browser
|
||||
|
||||
The QxtWebStoreCookieEvent class instructs the session manager to remove
|
||||
a cookie stored on the web browser.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Constructs a QxtWebRemoveCookieEvent for the specified \a sessionID that
|
||||
* removed the cookie with \a name from the web browser.
|
||||
*/
|
||||
QxtWebRemoveCookieEvent::QxtWebRemoveCookieEvent(int sessionID, QString name)
|
||||
: QxtWebEvent(QxtWebEvent::RemoveCookie, sessionID), name(name) {}
|
||||
|
||||
/*!
|
||||
* \variable QxtWebRemoveCookieEvent::name
|
||||
* Contains the name of the cookie to be removed.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\class QxtWebRedirectEvent
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtWebRedirectEvent class describes a redirect event to be sent to a web browser
|
||||
|
||||
The QxtWebRedirectEvent class instructs the web browser to load a page found at
|
||||
another location.
|
||||
|
||||
The default status code, 302, indicates that the requested page was found at
|
||||
a different location. Other useful status codes are 301, which indicates
|
||||
that the web browser should always use the new URL in place of the old one,
|
||||
and (in HTTP/1.1) 307, which indicates that the web browser should reissue
|
||||
the same request (including POST data) to the new URL.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Constructs a QxtWebRedirectEvent for the specified \a sessionID and \a requestID that
|
||||
* instructs the browser to move to the specified \a destination URL with \a statusCode.
|
||||
*/
|
||||
QxtWebRedirectEvent::QxtWebRedirectEvent(int sessionID, int requestID, const QString& destination, int statusCode)
|
||||
: QxtWebPageEvent(QxtWebEvent::Redirect, sessionID, requestID, QString("Redirect: <a href='%1'>%1</a>").arg(destination).toUtf8()), destination(destination)
|
||||
{
|
||||
QxtWebPageEvent::status = statusCode;
|
||||
QxtWebPageEvent::statusMessage = ("Redirect to " + destination).toUtf8();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \variable QxtWebRedirectEvent::destination
|
||||
* Contains the new location (absolute or relative) to which the browser
|
||||
* should redirect.
|
||||
*/
|
153
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtwebevent.h
vendored
Normal file
153
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtwebevent.h
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtWeb module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QXTWEBEVENT_H
|
||||
#define QXTWEBEVENT_H
|
||||
|
||||
#include <qxtglobal.h>
|
||||
#include <QString>
|
||||
#include <QByteArray>
|
||||
#include <QStringList>
|
||||
#include <QPointer>
|
||||
#include <QUrl>
|
||||
#include <QMultiHash>
|
||||
#include <QDateTime>
|
||||
QT_FORWARD_DECLARE_CLASS(QIODevice)
|
||||
class QxtWebContent;
|
||||
|
||||
class QXT_WEB_EXPORT QxtWebEvent
|
||||
{
|
||||
public:
|
||||
enum EventType
|
||||
{
|
||||
None = 0,
|
||||
Request,
|
||||
FileUpload,
|
||||
Page,
|
||||
StoreCookie,
|
||||
RemoveCookie,
|
||||
Redirect
|
||||
};
|
||||
|
||||
QxtWebEvent(EventType type, int sessionID);
|
||||
virtual ~QxtWebEvent();
|
||||
|
||||
inline EventType type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
const int sessionID;
|
||||
|
||||
private:
|
||||
EventType m_type;
|
||||
};
|
||||
|
||||
class QXT_WEB_EXPORT QxtWebRequestEvent : public QxtWebEvent
|
||||
{
|
||||
public:
|
||||
QxtWebRequestEvent(int sessionID, int requestID, const QUrl& url);
|
||||
~QxtWebRequestEvent();
|
||||
|
||||
const int requestID;
|
||||
|
||||
QUrl url;
|
||||
const QUrl originalUrl;
|
||||
QString contentType;
|
||||
QPointer<QxtWebContent> content;
|
||||
QString method;
|
||||
QString remoteAddress;
|
||||
|
||||
QMultiHash<QString, QString> cookies;
|
||||
QMultiHash<QString, QString> headers;
|
||||
};
|
||||
|
||||
/* TODO: refactor and implement
|
||||
class QXT_WEB_EXPORT QxtWebFileUploadEvent : public QxtWebEvent {
|
||||
public:
|
||||
QxtWebFileUploadEvent(int sessionID);
|
||||
|
||||
QString filename;
|
||||
int contentLength;
|
||||
QIODevice* content;
|
||||
};
|
||||
*/
|
||||
|
||||
class QxtWebRedirectEvent;
|
||||
class QXT_WEB_EXPORT QxtWebPageEvent : public QxtWebEvent
|
||||
{
|
||||
public:
|
||||
QxtWebPageEvent(int sessionID, int requestID, QSharedPointer<QIODevice> source);
|
||||
QxtWebPageEvent(int sessionID, int requestID, QByteArray source); // creates a QBuffer
|
||||
virtual ~QxtWebPageEvent();
|
||||
|
||||
QSharedPointer<QIODevice> dataSource; // data is read from this device and written to the client
|
||||
bool chunked;
|
||||
bool streaming;
|
||||
|
||||
const int requestID;
|
||||
int status;
|
||||
QByteArray statusMessage;
|
||||
QByteArray contentType;
|
||||
|
||||
QMultiHash<QString, QString> headers;
|
||||
|
||||
private:
|
||||
friend class QxtWebRedirectEvent;
|
||||
QxtWebPageEvent(QxtWebEvent::EventType typeOverride, int sessionID, int requestID, QByteArray source);
|
||||
};
|
||||
|
||||
class QXT_WEB_EXPORT QxtWebErrorEvent : public QxtWebPageEvent
|
||||
{
|
||||
public:
|
||||
QxtWebErrorEvent(int sessionID, int requestID, int status, QByteArray statusMessage);
|
||||
};
|
||||
|
||||
class QXT_WEB_EXPORT QxtWebStoreCookieEvent : public QxtWebEvent
|
||||
{
|
||||
public:
|
||||
QxtWebStoreCookieEvent(int sessionID, QString name, QString data, QDateTime expiration = QDateTime());
|
||||
|
||||
QString name;
|
||||
QString data;
|
||||
QDateTime expiration;
|
||||
};
|
||||
|
||||
class QXT_WEB_EXPORT QxtWebRemoveCookieEvent : public QxtWebEvent
|
||||
{
|
||||
public:
|
||||
QxtWebRemoveCookieEvent(int sessionID, QString name);
|
||||
|
||||
QString name;
|
||||
};
|
||||
|
||||
class QXT_WEB_EXPORT QxtWebRedirectEvent : public QxtWebPageEvent
|
||||
{
|
||||
public:
|
||||
QxtWebRedirectEvent(int sessionID, int requestID, const QString& destination, int statusCode = 302);
|
||||
|
||||
QString destination;
|
||||
};
|
||||
|
||||
#endif // QXTWEBEVENT_H
|
239
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtwebservicedirectory.cpp
vendored
Normal file
239
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtwebservicedirectory.cpp
vendored
Normal file
@@ -0,0 +1,239 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtWeb module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\class QxtWebServiceDirectory
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtWebServiceDirectory class provides Path-based web service dispatcher
|
||||
|
||||
QxtWebServiceDirectory allows multiple services to be associated with a single
|
||||
session. Selection between services is determined by the first path component
|
||||
in the URL. For example, the URL "/site/request?param=true" would relay the
|
||||
URL "/request?param=true" to the service named "site".
|
||||
|
||||
This class can be used recursively to declare a hierarchy of services. For
|
||||
example:
|
||||
\code
|
||||
QxtWebServiceDirectory* top = new QxtWebServiceDirectory(sm, sm);
|
||||
QxtWebServiceDirectory* service1 = new QxtWebServiceDirectory(sm, top);
|
||||
QxtWebServiceDirectory* service2 = new QxtWebServiceDirectory(sm, top);
|
||||
QxtWebServiceDirectory* service1a = new QxtWebServiceDirectory(sm, service1);
|
||||
QxtWebServiceDirectory* service1b = new QxtWebServiceDirectory(sm, service1);
|
||||
top->addService("1", service1);
|
||||
top->addService("2", service2);
|
||||
service1->addService("a", service1a);
|
||||
service1->addService("b", service1b);
|
||||
\endcode
|
||||
This accepts the URLs "/1/a/", "/1/b/", and "/2/".
|
||||
*/
|
||||
|
||||
#include "qxtwebservicedirectory.h"
|
||||
#include "qxtwebservicedirectory_p.h"
|
||||
#include "qxtwebevent.h"
|
||||
#include <QUrl>
|
||||
#include <QtDebug>
|
||||
|
||||
#ifndef QXT_DOXYGEN_RUN
|
||||
QxtWebServiceDirectoryPrivate::QxtWebServiceDirectoryPrivate() : QObject(0)
|
||||
{
|
||||
// initializers only
|
||||
}
|
||||
|
||||
void QxtWebServiceDirectoryPrivate::serviceDestroyed()
|
||||
{
|
||||
QxtAbstractWebService* service = qobject_cast<QxtAbstractWebService*>(sender());
|
||||
if (!service) return; // this shouldn't happen
|
||||
QString path;
|
||||
while (!(path = services.key(service)).isNull())
|
||||
{
|
||||
services.remove(path);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Constructs a QxtWebServiceDirectory object with the specified session manager \a sm and \a parent.
|
||||
*
|
||||
* Often, the session manager will also be the parent, but this is not a requirement.
|
||||
*/
|
||||
QxtWebServiceDirectory::QxtWebServiceDirectory(QxtAbstractWebSessionManager* sm, QObject* parent) : QxtAbstractWebService(sm, parent)
|
||||
{
|
||||
QXT_INIT_PRIVATE(QxtWebServiceDirectory);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Adds a \a service to the directory at the given \a path.
|
||||
* \sa removeService(), service()
|
||||
*/
|
||||
void QxtWebServiceDirectory::addService(const QString& path, QxtAbstractWebService* service)
|
||||
{
|
||||
if (qxt_d().services.contains(path))
|
||||
{
|
||||
qWarning() << "QxtWebServiceDirectory::addService:" << path << "already registered";
|
||||
}
|
||||
|
||||
qxt_d().services[path] = service;
|
||||
if (qxt_d().defaultRedirect.isEmpty())
|
||||
setDefaultRedirect(path);
|
||||
connect(service, SIGNAL(destroyed()), &qxt_d(), SLOT(serviceDestroyed()));
|
||||
}
|
||||
|
||||
/*!
|
||||
* Removes the service at the given \a path.
|
||||
*
|
||||
* Note that the service object is not destroyed.
|
||||
*/
|
||||
void QxtWebServiceDirectory::removeService(const QString& path)
|
||||
{
|
||||
if (!qxt_d().services.contains(path))
|
||||
{
|
||||
qWarning() << "QxtWebServiceDirectory::removeService:" << path << "not registered";
|
||||
}
|
||||
else
|
||||
{
|
||||
qxt_d().services.remove(path);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the service at the given \a path.
|
||||
*/
|
||||
QxtAbstractWebService* QxtWebServiceDirectory::service(const QString& path) const
|
||||
{
|
||||
if (!qxt_d().services.contains(path))
|
||||
return 0;
|
||||
return qxt_d().services[path];
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* Returns the first path segment from the URL in the \a event object.
|
||||
* (i.e. "a" from "/a/b/c") This also removes the path segment from the
|
||||
* event object. (in the previous example, the event's URL is now "/b/c")
|
||||
*/
|
||||
static QString extractPathLevel(QxtWebRequestEvent* event)
|
||||
{
|
||||
QString path = event->url.path();
|
||||
int pos = path.indexOf("/", 1); // the path always starts with /
|
||||
if (pos == -1)
|
||||
event->url.setPath(""); // cue to redirect to /service/
|
||||
else
|
||||
event->url.setPath(path.mid(pos));
|
||||
return path.mid(1, pos - 1);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
void QxtWebServiceDirectory::pageRequestedEvent(QxtWebRequestEvent* event)
|
||||
{
|
||||
QString path = extractPathLevel(event);
|
||||
if (path.isEmpty())
|
||||
{
|
||||
indexRequested(event);
|
||||
}
|
||||
else if (!qxt_d().services.contains(path))
|
||||
{
|
||||
unknownServiceRequested(event, path);
|
||||
}
|
||||
else if (event->url.path().isEmpty())
|
||||
{
|
||||
postEvent(new QxtWebRedirectEvent(event->sessionID, event->requestID, path + '/', 307));
|
||||
}
|
||||
else
|
||||
{
|
||||
qxt_d().services[path]->pageRequestedEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* \reimp unimplemented
|
||||
*/
|
||||
/*
|
||||
void QxtWebServiceDirectory::functionInvokedEvent(QxtWebRequestEvent* event) {
|
||||
QString path = extractPathLevel(event);
|
||||
if(path == "") {
|
||||
indexRequested(event);
|
||||
} else if(!qxt_d().services.contains(path)) {
|
||||
unknownServiceRequested(event, path);
|
||||
} else {
|
||||
qxt_d().services[path]->functionInvokedEvent(event);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*!
|
||||
* This \a event handler is called whenever the URL requests a service with \a name that has
|
||||
* not been added to the directory.
|
||||
*
|
||||
* The default implementation returns a 404 "Service not known" error.
|
||||
* Subclasses may reimplement this event handler to customize this behavior.
|
||||
*/
|
||||
void QxtWebServiceDirectory::unknownServiceRequested(QxtWebRequestEvent* event, const QString& name)
|
||||
{
|
||||
postEvent(new QxtWebErrorEvent(event->sessionID, event->requestID, 404, ("Service "" + QString(name).replace('<', "<") + "" not known").toUtf8()));
|
||||
}
|
||||
|
||||
/*!
|
||||
* This \a event handler is called whenever the URL does not contain a path, that
|
||||
* is, the URL is "/" or empty.
|
||||
*
|
||||
* The default implementation redirects to the service specified by
|
||||
* setDefaultRedirect(), or invokes unknownServiceRequested() if no default
|
||||
* redirect has been set.
|
||||
*/
|
||||
void QxtWebServiceDirectory::indexRequested(QxtWebRequestEvent* event)
|
||||
{
|
||||
if (defaultRedirect().isEmpty())
|
||||
{
|
||||
unknownServiceRequested(event, "/");
|
||||
}
|
||||
else
|
||||
{
|
||||
postEvent(new QxtWebRedirectEvent(event->sessionID, event->requestID, defaultRedirect() + '/', 307));
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the path that will be used by default by the indexRequested event.
|
||||
* \sa indexRequested(), setDefaultRedirect()
|
||||
*/
|
||||
QString QxtWebServiceDirectory::defaultRedirect() const
|
||||
{
|
||||
return qxt_d().defaultRedirect;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Sets the \a path that will be used by default by the indexRequested event.
|
||||
* \sa indexRequested(), defaultRedirect()
|
||||
*/
|
||||
void QxtWebServiceDirectory::setDefaultRedirect(const QString& path)
|
||||
{
|
||||
if (!qxt_d().services.contains(path))
|
||||
qWarning() << "QxtWebServiceDirectory::setDefaultRedirect:" << path << "not registered";
|
||||
qxt_d().defaultRedirect = path;
|
||||
}
|
59
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtwebservicedirectory.h
vendored
Normal file
59
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtwebservicedirectory.h
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtWeb module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QXTWEBSERVICEDIRECTORY_H
|
||||
#define QXTWEBSERVICEDIRECTORY_H
|
||||
|
||||
#include <qxtabstractwebservice.h>
|
||||
#include <QString>
|
||||
class QxtAbstractWebSessionManager;
|
||||
class QxtWebEvent;
|
||||
|
||||
class QxtWebServiceDirectoryPrivate;
|
||||
class QXT_WEB_EXPORT QxtWebServiceDirectory : public QxtAbstractWebService
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QxtWebServiceDirectory(QxtAbstractWebSessionManager* sm, QObject* parent = 0);
|
||||
|
||||
void addService(const QString& path, QxtAbstractWebService* service);
|
||||
void removeService(const QString& path);
|
||||
QxtAbstractWebService* service(const QString& path) const;
|
||||
|
||||
virtual void pageRequestedEvent(QxtWebRequestEvent* event);
|
||||
// virtual void functionInvokedEvent(QxtWebRequestEvent* event);
|
||||
|
||||
QString defaultRedirect() const;
|
||||
void setDefaultRedirect(const QString& path);
|
||||
|
||||
protected:
|
||||
virtual void unknownServiceRequested(QxtWebRequestEvent* event, const QString& name);
|
||||
virtual void indexRequested(QxtWebRequestEvent* event);
|
||||
|
||||
private:
|
||||
QXT_DECLARE_PRIVATE(QxtWebServiceDirectory)
|
||||
};
|
||||
|
||||
#endif // QXTWEBSERVICEDIRECTORY_H
|
49
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtwebservicedirectory_p.h
vendored
Normal file
49
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtwebservicedirectory_p.h
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtWeb module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QXTWEBSERVICEDIRECTORY_P_H
|
||||
#define QXTWEBSERVICEDIRECTORY_P_H
|
||||
|
||||
#include "qxtwebservicedirectory.h"
|
||||
#include <QString>
|
||||
#include <QHash>
|
||||
|
||||
#ifndef QXT_DOXYGEN_RUN
|
||||
class QxtWebServiceDirectoryPrivate : public QObject, public QxtPrivate<QxtWebServiceDirectory>
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QXT_DECLARE_PUBLIC(QxtWebServiceDirectory)
|
||||
QxtWebServiceDirectoryPrivate();
|
||||
|
||||
QHash<QString, QxtAbstractWebService*> services;
|
||||
QString defaultRedirect;
|
||||
|
||||
public Q_SLOTS:
|
||||
void serviceDestroyed();
|
||||
};
|
||||
#endif // QXT_DOXYGEN_RUN
|
||||
|
||||
#endif // QXTWEBSERVICEDIRECTORY_P_H
|
226
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtwebslotservice.cpp
vendored
Normal file
226
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtwebslotservice.cpp
vendored
Normal file
@@ -0,0 +1,226 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtWeb module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
/*!
|
||||
\class QxtWebSlotService
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtWebSlotService class provides a Slot based webservice
|
||||
|
||||
A WebService that resolves the first part of the path to a slot name and passes the rest as arguments.
|
||||
|
||||
\code
|
||||
class MyService : public QxtWebSlotService
|
||||
{
|
||||
Q_OBJECT
|
||||
public slots:
|
||||
void hello(QxtWebRequestEvent* event, QString a)
|
||||
{
|
||||
postEvent(new QxtWebPageEvent(event->sessionID, event->requestID, "<h1>"+a.toUtf8()+"</h1>));
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
|
||||
|
||||
/hello/foo<br>
|
||||
will output<br>
|
||||
<h1>Foo</h1><br>
|
||||
|
||||
|
||||
\sa QxtAbstractWebService
|
||||
*/
|
||||
|
||||
#include "qxtwebslotservice.h"
|
||||
#include "qxtwebevent.h"
|
||||
|
||||
/*!
|
||||
Constructs a new QxtWebSlotService with \a sm and \a parent.
|
||||
*/
|
||||
QxtWebSlotService::QxtWebSlotService(QxtAbstractWebSessionManager* sm, QObject* parent): QxtAbstractWebService(sm, parent)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the current absolute url of this service depending on the request \a event.
|
||||
*/
|
||||
QUrl QxtWebSlotService::self(QxtWebRequestEvent* event)
|
||||
|
||||
{
|
||||
QStringList u = event->url.path().split('/');
|
||||
QStringList o = event->originalUrl.path().split('/');
|
||||
u.removeFirst();
|
||||
o.removeFirst();
|
||||
for (int i = 0;i < u.count();i++)
|
||||
o.removeLast();
|
||||
|
||||
|
||||
QString r = "/";
|
||||
foreach(const QString& d, o)
|
||||
{
|
||||
r += d + '/';
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
void QxtWebSlotService::pageRequestedEvent(QxtWebRequestEvent* event)
|
||||
{
|
||||
QList<QString> args = event->url.path().split('/');
|
||||
args.removeFirst();
|
||||
if (args.at(args.count() - 1).isEmpty())
|
||||
args.removeLast();
|
||||
|
||||
|
||||
///--------------find action ------------------
|
||||
QByteArray action = "index";
|
||||
if (args.count())
|
||||
{
|
||||
action = args.at(0).toUtf8();
|
||||
if (action.trimmed().isEmpty())
|
||||
action = "index";
|
||||
args.removeFirst();
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool ok = false;
|
||||
if (args.count() > 7)
|
||||
{
|
||||
ok = QMetaObject::invokeMethod(this, action,
|
||||
Q_ARG(QxtWebRequestEvent*, event),
|
||||
Q_ARG(QString, args.at(0)),
|
||||
Q_ARG(QString, args.at(1)),
|
||||
Q_ARG(QString, args.at(2)),
|
||||
Q_ARG(QString, args.at(3)),
|
||||
Q_ARG(QString, args.at(4)),
|
||||
Q_ARG(QString, args.at(5)),
|
||||
Q_ARG(QString, args.at(6)),
|
||||
Q_ARG(QString, args.at(7))
|
||||
);
|
||||
}
|
||||
else if (args.count() > 6)
|
||||
{
|
||||
ok = QMetaObject::invokeMethod(this, action,
|
||||
Q_ARG(QxtWebRequestEvent*, event),
|
||||
Q_ARG(QString, args.at(0)),
|
||||
Q_ARG(QString, args.at(1)),
|
||||
Q_ARG(QString, args.at(2)),
|
||||
Q_ARG(QString, args.at(3)),
|
||||
Q_ARG(QString, args.at(4)),
|
||||
Q_ARG(QString, args.at(5)),
|
||||
Q_ARG(QString, args.at(6))
|
||||
);
|
||||
}
|
||||
else if (args.count() > 5)
|
||||
{
|
||||
ok = QMetaObject::invokeMethod(this, action,
|
||||
Q_ARG(QxtWebRequestEvent*, event),
|
||||
Q_ARG(QString, args.at(0)),
|
||||
Q_ARG(QString, args.at(1)),
|
||||
Q_ARG(QString, args.at(2)),
|
||||
Q_ARG(QString, args.at(3)),
|
||||
Q_ARG(QString, args.at(4)),
|
||||
Q_ARG(QString, args.at(5))
|
||||
);
|
||||
}
|
||||
else if (args.count() > 4)
|
||||
{
|
||||
ok = QMetaObject::invokeMethod(this, action,
|
||||
Q_ARG(QxtWebRequestEvent*, event),
|
||||
Q_ARG(QString, args.at(0)),
|
||||
Q_ARG(QString, args.at(1)),
|
||||
Q_ARG(QString, args.at(2)),
|
||||
Q_ARG(QString, args.at(3)),
|
||||
Q_ARG(QString, args.at(4))
|
||||
);
|
||||
}
|
||||
else if (args.count() > 3)
|
||||
{
|
||||
ok = QMetaObject::invokeMethod(this, action,
|
||||
Q_ARG(QxtWebRequestEvent*, event),
|
||||
Q_ARG(QString, args.at(0)),
|
||||
Q_ARG(QString, args.at(1)),
|
||||
Q_ARG(QString, args.at(2)),
|
||||
Q_ARG(QString, args.at(3))
|
||||
);
|
||||
}
|
||||
else if (args.count() > 2)
|
||||
{
|
||||
ok = QMetaObject::invokeMethod(this, action,
|
||||
Q_ARG(QxtWebRequestEvent*, event),
|
||||
Q_ARG(QString, args.at(0)),
|
||||
Q_ARG(QString, args.at(1)),
|
||||
Q_ARG(QString, args.at(2))
|
||||
);
|
||||
}
|
||||
else if (args.count() > 1)
|
||||
{
|
||||
ok = QMetaObject::invokeMethod(this, action,
|
||||
Q_ARG(QxtWebRequestEvent*, event),
|
||||
Q_ARG(QString, args.at(0)),
|
||||
Q_ARG(QString, args.at(1))
|
||||
);
|
||||
}
|
||||
else if (args.count() > 0)
|
||||
{
|
||||
ok = QMetaObject::invokeMethod(this, action,
|
||||
Q_ARG(QxtWebRequestEvent*, event),
|
||||
Q_ARG(QString, args.at(0))
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
ok = QMetaObject::invokeMethod(this, action,
|
||||
Q_ARG(QxtWebRequestEvent*, event)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
QByteArray err = "<h1>Can not find slot</h1> <pre>Class " + QByteArray(metaObject()->className()) + "\r{\npublic slots:\r void " + action.replace('<', "<") + " ( QxtWebRequestEvent* event, ";
|
||||
for (int i = 0;i < args.count();i++)
|
||||
err += "QString arg" + QByteArray::number(i) + ", ";
|
||||
err.chop(2);
|
||||
|
||||
err += " ); \r};\r</pre> ";
|
||||
|
||||
postEvent(new QxtWebErrorEvent(event->sessionID, event->requestID, 404, err));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
void QxtWebSlotService::functionInvokedEvent(QxtWebRequestEvent* event)
|
||||
{
|
||||
postEvent(new QxtWebErrorEvent(event->sessionID, event->requestID, 500, "<h1>Not supported</h1>"));
|
||||
}
|
45
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtwebslotservice.h
vendored
Normal file
45
thirdparty/qxt/qxtweb-standalone/qxtweb/qxtwebslotservice.h
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) Qxt Foundation. Some rights reserved.
|
||||
**
|
||||
** This file is part of the QxtWeb module of the Qxt library.
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the Common Public License, version 1.0, as published
|
||||
** by IBM, and/or under the terms of the GNU Lesser General Public License,
|
||||
** version 2.1, as published by the Free Software Foundation.
|
||||
**
|
||||
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
|
||||
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
|
||||
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
|
||||
** FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** You should have received a copy of the CPL and the LGPL along with this
|
||||
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
|
||||
** included with the source distribution for more information.
|
||||
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QXTWEBSLOTSERVICE_H
|
||||
#define QXTWEBSLOTSERVICE_H
|
||||
|
||||
#include "qxtabstractwebservice.h"
|
||||
#include <QUrl>
|
||||
|
||||
class QXT_WEB_EXPORT QxtWebSlotService : public QxtAbstractWebService
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QxtWebSlotService(QxtAbstractWebSessionManager* sm, QObject* parent = 0);
|
||||
|
||||
protected:
|
||||
QUrl self(QxtWebRequestEvent* event);
|
||||
|
||||
virtual void pageRequestedEvent(QxtWebRequestEvent* event);
|
||||
virtual void functionInvokedEvent(QxtWebRequestEvent* event);
|
||||
};
|
||||
|
||||
#endif // QXTWEBSLOTSERVICE_H
|
Reference in New Issue
Block a user