Akonadi

asapcat/session.cpp
1/***************************************************************************
2 * SPDX-FileCopyrightText: 2013 Volker Krause <vkrause@kde.org> *
3 * *
4 * SPDX-License-Identifier: LGPL-2.0-or-later *
5 ***************************************************************************/
6
7#include "session.h"
8
9#include "private/standarddirs_p.h"
10
11#include <QCoreApplication>
12#include <QFile>
13#include <QSettings>
14#include <QSocketNotifier>
15
16#include <fcntl.h>
17#include <iostream>
18#include <unistd.h>
19
20Session::Session(const QString &input, QObject *parent)
21 : QObject(parent)
22{
23 auto file = new QFile(this);
24 if (input != QLatin1StringView("-")) {
25 file->setFileName(input);
26 if (!file->open(QFile::ReadOnly)) {
27 qFatal("Failed to open %s", qPrintable(input));
28 }
29 } else {
30 // ### does that work on Windows?
31 const int flags = fcntl(0, F_GETFL);
32 fcntl(0, F_SETFL, flags | O_NONBLOCK); // NOLINT(hicpp-signed-bitwise)
33
34 if (!file->open(stdin, QFile::ReadOnly | QFile::Unbuffered)) {
35 qFatal("Failed to open stdin!");
36 }
37 m_notifier = new QSocketNotifier(0, QSocketNotifier::Read, this);
38 connect(m_notifier, &QSocketNotifier::activated, this, &Session::inputAvailable);
39 }
40 m_input = file;
41}
42
43Session::~Session()
44{
45}
46
47void Session::connectToHost()
48{
49 const QSettings connectionSettings(Akonadi::StandardDirs::connectionConfigFile(), QSettings::IniFormat);
50
51 QString serverAddress;
52#ifdef Q_OS_WIN
53 serverAddress = connectionSettings.value(QStringLiteral("Data/NamedPipe"), QString()).toString();
54#else
55 serverAddress = connectionSettings.value(QStringLiteral("Data/UnixPath"), QString()).toString();
56#endif
57 if (serverAddress.isEmpty()) {
58 qFatal("Unable to determine server address.");
59 }
60
61 auto socket = new QLocalSocket(this);
62 connect(socket, &QLocalSocket::errorOccurred, this, &Session::serverError);
63 connect(socket, &QLocalSocket::disconnected, this, &Session::serverDisconnected);
64 connect(socket, &QIODevice::readyRead, this, &Session::serverRead);
65 connect(socket, &QLocalSocket::connected, this, &Session::inputAvailable);
66
67 m_session = socket;
68 socket->connectToServer(serverAddress);
69
70 m_connectionTime.start();
71}
72
73void Session::inputAvailable()
74{
75 if (!m_session->isOpen()) {
76 return;
77 }
78
79 if (m_notifier) {
80 m_notifier->setEnabled(false);
81 }
82
83 if (m_input->atEnd()) {
84 return;
85 }
86
87 QByteArray buffer(1024, Qt::Uninitialized);
88 qint64 readSize = 0;
89
90 while ((readSize = m_input->read(buffer.data(), buffer.size())) > 0) {
91 m_session->write(buffer.constData(), readSize);
92 m_sentBytes += readSize;
93 }
94
95 if (m_notifier) {
96 m_notifier->setEnabled(true);
97 }
98}
99
100void Session::serverDisconnected()
101{
103}
104
105void Session::serverError(QLocalSocket::LocalSocketError socketError)
106{
107 if (socketError == QLocalSocket::PeerClosedError) {
109 return;
110 }
111
112 std::cerr << qPrintable(m_session->errorString());
114}
115
116void Session::serverRead()
117{
118 QByteArray buffer(1024, Qt::Uninitialized);
119 qint64 readSize = 0;
120
121 while ((readSize = m_session->read(buffer.data(), buffer.size())) > 0) {
122 write(1, buffer.data(), readSize);
123 m_receivedBytes += readSize;
124 }
125}
126
127void Session::printStats() const
128{
129 std::cerr << "Connection time: " << m_connectionTime.elapsed() << " ms" << std::endl;
130 std::cerr << "Sent: " << m_sentBytes << " bytes" << std::endl;
131 std::cerr << "Received: " << m_receivedBytes << " bytes" << std::endl;
132}
133
134#include "moc_session.cpp"
void exit(int returnCode)
qint64 elapsed() const const
virtual bool atEnd() const const
QString errorString() const const
bool isOpen() const const
QByteArray read(qint64 maxSize)
void readyRead()
qint64 write(const QByteArray &data)
void connected()
void disconnected()
void errorOccurred(QLocalSocket::LocalSocketError socketError)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void activated(QSocketDescriptor socket, QSocketNotifier::Type type)
void setEnabled(bool enable)
bool isEmpty() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:08:30 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.