File indexing completed on 2024-04-21 16:12:46

0001 /*
0002     SPDX-FileCopyrightText: 2007 Jeff Cooper <weirdsox11@gmail.com>
0003     SPDX-FileCopyrightText: 2007 Thomas Georgiou <TAGeorgiou@gmail.com>
0004     SPDX-FileCopyrightText: 2022 Alexander Lohnau <alexander.lohnau@gmx.de>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-only
0007 */
0008 
0009 #pragma once
0010 
0011 #include <array>
0012 #include <QMap>
0013 #include <QObject>
0014 #include <QTcpSocket>
0015 #include <QTimer>
0016 #include <QVariantMap>
0017 
0018 /**
0019  * This class evaluates the basic expressions given in the interface.
0020  */
0021 
0022 class DictEngine : public QObject
0023 {
0024     Q_OBJECT
0025 
0026 public:
0027     DictEngine(QObject *parent = nullptr);
0028     ~DictEngine() override;
0029 
0030 Q_SIGNALS:
0031     /**
0032      * @param socketError the type of the last socket error
0033      * @param errorString a human-readable description of the last socket error
0034      */
0035     void dictErrorOccurred(QAbstractSocket::SocketError socketError, const QString &errorString);
0036 
0037     /**
0038      * @param loading @c true if the dict finder is downloading dict list from
0039      * the Internet, @c false otherwise.
0040      */
0041     void dictLoadingChanged(bool loading);
0042 
0043     void dictsRecieved(const QMap<QString, QString> &dicts);
0044     void definitionRecieved(const QString &html);
0045 
0046 public Q_SLOTS:
0047     void requestDicts();
0048     void requestDefinition(const QString &query);
0049 
0050 private Q_SLOTS:
0051     /**
0052      * Slot to asynchronously handle \readyRead signal emitted
0053      * when receiving new definitions.
0054      */
0055     void slotDefinitionReadyRead();
0056 
0057     /**
0058      * Slot to process definition data when any end response
0059      * listed in \m_definitionResponses is received, or to handle
0060      * \QTimer::timeout signal when no new data are received
0061      * from the socket and no end response is received.
0062      */
0063     void slotDefinitionReadFinished();
0064 
0065     void socketClosed();
0066 
0067 private:
0068     void getDefinition();
0069     void getDicts();
0070     void setDict(const QByteArray &dict);
0071     void setServer(const QString &server);
0072 
0073     QHash<QString, QString> m_dictNameToDictCode;
0074     QTcpSocket *m_tcpSocket = nullptr;
0075     QString m_currentWord;
0076     QString m_currentQuery;
0077     QByteArrayList m_dictNames;
0078     QString m_serverName;
0079     QMap<QString, QMap<QString, QString>> m_availableDictsCache;
0080 
0081     /**
0082      * Stores temporarily received definition data
0083      */
0084     QByteArray m_definitionData;
0085 
0086     /**
0087      * When \QTimer::timeout is emitted, the existing socket will be closed
0088      * and deleted, and will emit \definitionRecieved to stop the loading
0089      * process.
0090      */
0091     QTimer m_definitionTimer;
0092 
0093     // https://datatracker.ietf.org/doc/html/rfc2229
0094     const std::array<QByteArray, 4> m_definitionResponses;
0095 };