File indexing completed on 2024-04-14 03:52:48

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 2000 Stephan Kulow <coolo@kde.org>
0004     SPDX-FileCopyrightText: 2000 David Faure <faure@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #ifndef KIO_CONNECTION_P_H
0010 #define KIO_CONNECTION_P_H
0011 
0012 #include "connectionbackend_p.h"
0013 #include <QList>
0014 #include <QObject>
0015 #include <QString>
0016 #include <QUrl>
0017 
0018 #include <memory>
0019 
0020 namespace KIO
0021 {
0022 class ConnectionServer;
0023 class ConnectionPrivate;
0024 /**
0025  * @private
0026  *
0027  * This class provides a simple means for IPC between two applications
0028  * via a pipe.
0029  * It handles a queue of commands to be sent which makes it possible to
0030  * queue data before an actual connection has been established.
0031  */
0032 class Connection : public QObject
0033 {
0034     Q_OBJECT
0035 
0036 public:
0037     enum class ReadMode {
0038         Polled, /// Any new tasks will be polled
0039         EventDriven, /// We need to emit signals when we have pending events. Requires a working QEventLoop
0040     };
0041     /**
0042      * Creates a new connection.
0043      * @see connectToRemote, listenForRemote
0044      */
0045     explicit Connection(QObject *parent = nullptr);
0046     ~Connection() override;
0047 
0048     /**
0049      * Connects to the remote address.
0050      * @param address a local:// or tcp:// URL.
0051      */
0052     void connectToRemote(const QUrl &address);
0053 
0054     /// Closes the connection.
0055     void close();
0056 
0057     QString errorString() const;
0058 
0059     bool isConnected() const;
0060 
0061     /**
0062      * Checks whether the connection has been initialized.
0063      * @return true if the initialized
0064      * @see init()
0065      */
0066     bool inited() const;
0067 
0068     /**
0069      * Sends/queues the given command to be sent.
0070      * @param cmd the command to set
0071      * @param arr the bytes to send
0072      * @return true if successful, false otherwise
0073      */
0074     bool send(int cmd, const QByteArray &arr = QByteArray());
0075 
0076     /**
0077      * Sends the given command immediately.
0078      * @param _cmd the command to set
0079      * @param data the bytes to send
0080      * @return true if successful, false otherwise
0081      */
0082     bool sendnow(int _cmd, const QByteArray &data);
0083 
0084     /**
0085      * Returns true if there are packets to be read immediately,
0086      * false if waitForIncomingTask must be called before more data
0087      * is available.
0088      */
0089     bool hasTaskAvailable() const;
0090 
0091     /**
0092      * Waits for one more command to be handled and ready.
0093      *
0094      * @param ms   the time to wait in milliseconds
0095      * @returns true if one command can be read, false if we timed out
0096      */
0097     bool waitForIncomingTask(int ms = 30000);
0098 
0099     /**
0100      * Receive data.
0101      *
0102      * @param _cmd the received command will be written here
0103      * @param data the received data will be written here
0104 
0105      * @return >=0 indicates the received data size upon success
0106      *         -1  indicates error
0107      */
0108     int read(int *_cmd, QByteArray &data);
0109 
0110     /**
0111      * Don't handle incoming data until resumed.
0112      */
0113     void suspend();
0114 
0115     /**
0116      * Resume handling of incoming data.
0117      */
0118     void resume();
0119 
0120     /**
0121      * Returns status of connection.
0122      * @return true if suspended, false otherwise
0123      */
0124     bool suspended() const;
0125 
0126     void setReadMode(ReadMode mode);
0127 
0128 Q_SIGNALS:
0129     void readyRead();
0130 
0131 private:
0132     friend class ConnectionPrivate;
0133     friend class ConnectionServer;
0134     std::unique_ptr<class ConnectionPrivate> const d;
0135 };
0136 
0137 // Separated from Connection only for historical reasons - they are both private now
0138 class ConnectionPrivate
0139 {
0140 public:
0141     inline ConnectionPrivate()
0142         : backend(nullptr)
0143         , q(nullptr)
0144         , suspended(false)
0145         , readMode(Connection::ReadMode::EventDriven)
0146     {
0147     }
0148 
0149     void dequeue();
0150     void commandReceived(const Task &task);
0151     void disconnected();
0152     void setBackend(ConnectionBackend *b);
0153 
0154     QList<Task> outgoingTasks;
0155     QList<Task> incomingTasks;
0156     ConnectionBackend *backend;
0157     Connection *q;
0158     bool suspended;
0159     Connection::ReadMode readMode;
0160 };
0161 
0162 class ConnectionServerPrivate;
0163 }
0164 
0165 #endif