#include "qookie-cast-client.h" #include #include #include #include #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) // Qt4 support #include #define WebView QWebView #else #include using WebView = QTextEdit; #endif Server::Server(QTabWidget& tabs, QObject *parent) : QObject(parent) , tabs(tabs) , payload_size(-1) { server = new QTcpServer(this); connect(server, SIGNAL(newConnection()), SLOT(newConnection())); server->listen(QHostAddress::Any, 10024); } void Server::newConnection() { payload_size = -1; payload.clear(); while (server->hasPendingConnections()) { QTcpSocket *socket = server->nextPendingConnection(); connect(socket, SIGNAL(readyRead()), SLOT(readyRead())); connect(socket, SIGNAL(disconnected()), SLOT(disconnected())); } } void Server::disconnected() { QTcpSocket *socket = static_cast(sender()); socket->deleteLater(); } void Server::readyRead() { QTcpSocket *socket = static_cast(sender()); while(socket->bytesAvailable() > 0) { payload.append(socket->readAll()); } // New/incoming qookie-cast if(payload_size < 0 && payload.size() >= (int)sizeof(std::uint32_t)) { std::uint32_t* size_ptr = (std::uint32_t*)payload.data(); payload_size = *size_ptr; // Skip the size field payload = payload.mid(sizeof(std::uint32_t)); } // We have full payload if(payload_size > 0 && payload_size <= payload.size()) { std::uint32_t* title_size_ptr = (std::uint32_t*)payload.data(); auto title_ptr = payload.data() + sizeof(std::uint32_t); auto title_size = *title_size_ptr; QByteArray title(title_ptr, title_size); // Calculate the html size as the remaining of the payload. auto html_size = payload_size - title_size - sizeof(std::uint32_t); QByteArray html(title_ptr + title_size, html_size); auto webview = new WebView(); webview->setHtml(QString::fromUtf8(html)); webview->setReadOnly(true); tabs.addTab(webview, QString::fromUtf8(title)); payload_size = -1; // Store remainder (ie. skip, title_size, title and html) payload = payload.mid(html_size + title_size + sizeof(std::uint32_t)); if(payload.size() > 0) { // If theres enything left recurse to process excess. readyRead(); } } } MyTabs::MyTabs() { connect(this, SIGNAL(tabCloseRequested(int)), SLOT(doCloseIt(int))); } void MyTabs::doCloseIt(int index) { removeTab(index); } int main(int argc, char *argv[]) { QApplication qapp(argc, argv); MyTabs tabs; tabs.setTabsClosable(true); tabs.setMovable(true); tabs.setWindowTitle("Qookie-cast client"); tabs.showMaximized(); Server server(tabs); return qapp.exec(); }