1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
#include "qookie-cast-client.h"
#include <cstdint>
#include <iostream>
#include <QtWidgets/QApplication>
#include <QtWidgets/QTabWidget>
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
// Qt4 support
#include <QtWidgets/QWebView>
#define WebView QWebView
#else
#include <QtWidgets/QTextEdit>
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<QTcpSocket*>(sender());
socket->deleteLater();
}
void Server::readyRead()
{
QTcpSocket *socket = static_cast<QTcpSocket*>(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();
}
|