summaryrefslogtreecommitdiff
path: root/src/qookie-cast-client.cc
blob: d109249963984e2b3a46844655582b51e79ebc88 (plain)
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();
}