summaryrefslogtreecommitdiffstats
path: root/src/jsonrpc/qjsonrpcprotocol_p_p.h
blob: a31f5b6a9d9f650a5833169a9b318c169a993072 (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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only

#ifndef QJSONRPCPROTOCOL_P_P_H
#define QJSONRPCPROTOCOL_P_P_H

//
//  W A R N I N G
//  -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//

#include <QtJsonRpc/private/qjsonrpcprotocol_p.h>
#include <QtJsonRpc/private/qjsonrpctransport_p.h>

#include <QtCore/qjsondocument.h>
#include <QtCore/qjsonobject.h>

#include <unordered_map>
#include <memory>

QT_BEGIN_NAMESPACE

template<typename T>
struct QHasher
{
    using argument_type = T;
    using result_type = size_t;
    result_type operator()(const argument_type &value) const { return qHash(value); }
};

class QJsonRpcProtocolPrivate
{
public:
    template<typename K, typename V>
    using Map = std::unordered_map<K, V, QHasher<K>>;

    using ResponseHandler = QJsonRpcProtocol::ResponseHandler;
    using MessageHandler = QJsonRpcProtocol::MessageHandler;
    using OwnedMessageHandler = std::unique_ptr<MessageHandler>;
    using MessageHandlerMap = Map<QString, OwnedMessageHandler>;
    using ResponseMap = Map<QJsonValue, QJsonRpcProtocol::Handler<QJsonRpcProtocol::Response>>;

    void processMessage(const QJsonDocument &message, const QJsonParseError &error);
    void processError(const QString &error);

    template<typename JSON>
    void sendMessage(const JSON &value)
    {
        m_transport->sendMessage(QJsonDocument(value));
    }

    void processRequest(const QJsonObject &object);
    void processResponse(const QJsonObject &object);
    void processNotification(const QJsonObject &object);

    MessageHandler *messageHandler(const QString &method) const
    {
        auto it = m_messageHandlers.find(method);
        return it != m_messageHandlers.end() ? it->second.get() : m_defaultHandler.get();
    }

    void setMessageHandler(const QString &method, OwnedMessageHandler handler)
    {
        m_messageHandlers[method] = std::move(handler);
    }

    MessageHandler *defaultMessageHandler() const { return m_defaultHandler.get(); }
    void setDefaultMessageHandler(OwnedMessageHandler handler)
    {
        m_defaultHandler = std::move(handler);
    }

    bool addPendingRequest(const QJsonValue &id,
                           QJsonRpcProtocol::Handler<QJsonRpcProtocol::Response> handler)
    {
        auto it = m_pendingRequests.find(id);
        if (it == m_pendingRequests.end()) {
            m_pendingRequests.insert(std::make_pair(id, std::move(handler)));
            return true;
        }
        return false;
    }

    void setTransport(QJsonRpcTransport *newTransport);
    QJsonRpcTransport *transport() const { return m_transport; }

    ResponseHandler invalidResponseHandler() const { return m_invalidResponseHandler; }
    void setInvalidResponseHandler(ResponseHandler handler)
    {
        m_invalidResponseHandler = std::move(handler);
    }

    ResponseHandler protocolErrorHandler() const { return m_protocolErrorHandler; }
    void setProtocolErrorHandler(ResponseHandler handler)
    {
        m_protocolErrorHandler = std::move(handler);
    }

    QJsonRpcProtocol::MessagePreprocessor messagePreprocessor() const
    {
        return m_messagePreprocessor;
    }
    void installMessagePreprocessor(QJsonRpcProtocol::MessagePreprocessor preHandler)
    {
        m_messagePreprocessor = std::move(preHandler);
    }

private:
    ResponseMap m_pendingRequests;
    MessageHandlerMap m_messageHandlers;

    OwnedMessageHandler m_defaultHandler;

    QJsonRpcTransport *m_transport = nullptr;

    ResponseHandler m_protocolErrorHandler;
    ResponseHandler m_invalidResponseHandler;
    QJsonRpcProtocol::MessagePreprocessor m_messagePreprocessor;
};

class QJsonRpcProtocol::BatchPrivate
{
public:
    struct Item
    {
        QJsonValue id = QJsonValue::Undefined;
        QString method;
        QJsonValue params = QJsonValue::Undefined;
    };

    std::vector<Item> m_items;
};

QT_END_NAMESPACE

#endif // QJSONRPCPROTOCOL_P_P_H