File: jsonrpc_handler.h

package info (click to toggle)
eiskaltdcpp 2.2.9-3~bpo70%2B1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy-backports
  • size: 20,372 kB
  • sloc: cpp: 94,068; ansic: 8,832; perl: 1,523; xml: 1,378; sh: 685; php: 661; makefile: 101
file content (345 lines) | stat: -rw-r--r-- 10,633 bytes parent folder | download | duplicates (5)
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
/*
 *  JsonRpc-Cpp - JSON-RPC implementation.
 *  Copyright (C) 2008-2012 Sebastien Vincent <sebastien.vincent@cppextrem.com>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * \file jsonrpc_handler.h
 * \brief JSON-RPC server processor engine.
 * \author Sebastien Vincent
 */

#ifndef JSONRPC_HANDLER_H
#define JSONRPC_HANDLER_H

#include <cstdio>

#include <string>
#include <list>

#include <jsoncpp/json.h>

#include "jsonrpc_common.h"

namespace Json
{
  namespace Rpc
  {
    /**
     * \class CallbackMethod
     * \brief Abstract callback-style method.
     * \see RpcMethod
     */
    class CallbackMethod
    {
      public:
        /**
         * \brief Destructor.
         */
        virtual ~CallbackMethod();

        /**
         * \brief Call the method.
         * \param msg JSON-RPC request or notification
         * \param response response produced (may be Json::Value::null)
         * \return true if message has been correctly processed, false otherwise
         * \note Have to be implemented by subclasses
         */
        virtual bool Call(const Json::Value& msg, Json::Value& response) = 0;

        /**
         * \brief Get the name of the methods (optional).
         * \return name of the method as std::string
         * \note Have to be implemented by subclasses
         */
        virtual std::string GetName() const = 0;

        /**
         * \brief Get the description of the methods (optional).
         * \return description
         */
        virtual Json::Value GetDescription() const = 0;
    };

    /**
     * \class RpcMethod
     * \brief Template class that represent the RPC method.
     *
     * Typically RpcMethod object is created inside another class and use
     * a method of this class. See Handler class documentation for an example
     * of how to use RpcMethod class.
     *
     * \warning As class keep pointer of object reference, you should take
     * care at the lifetime of object you pass in RpcMethod constructor,
     * else it could lead to crash your program.
     */
    template<class T> class RpcMethod : public CallbackMethod
    {
      public:
        /**
         * \typedef Method
         * \brief T method signature.
         */
        typedef bool (T::*Method)(const Json::Value& msg,
            Json::Value& response);

        /**
         * \brief Constructor.
         * \param obj object
         * \param method class method
         * \param name symbolic name (i.e. system.describe)
         * \param description method description (in JSON format)
         */
        RpcMethod(T& obj, Method method, const std::string& name,
            const Json::Value description = Json::Value::null)
        {
          m_obj = &obj;
          m_name = name;
          m_method = method;
          m_description = description;
        }

        /**
         * \brief Call the method.
         * \param msg JSON-RPC request or notification
         * \param response response produced (may be Json::Value::null)
         * \return true if message has been correctly processed, false otherwise
         * \note JSON-RPC's notification method MUST set response to
         * Json::Value::null
         */
        virtual bool Call(const Json::Value& msg, Json::Value& response)
        {
          return (m_obj->*m_method)(msg, response);
        }

        /**
         * \brief Get the name of the methods (optional).
         * \return name of the method as std::string
         */
        virtual std::string GetName() const
        {
          return m_name;
        }

        /**
         * \brief Get the description of the methods (optional).
         * \return description
         */
        virtual Json::Value GetDescription() const
        {
          return m_description;
        }

      private:
        /**
         * \brief Copy constructor (private to avoid copy).
         * \param obj objec to copy
         */
        RpcMethod(const RpcMethod& obj);

         /**
         * \brief Operator copy assignment (redefined because of "resource"
         * class).
         * \param obj object to copy
         * \return object copied object reference
         */
        RpcMethod& operator=(const RpcMethod& obj);

        /**
         * \brief JSON reader.
         */
        Json::Reader m_reader;

        /**
         * \brief Object pointer.
         */
        T* m_obj;

        /**
         * \brief Method of T class.
         */
        Method m_method;

        /**
         * \brief Symbolic name.
         */
        std::string m_name;

        /**
         * \brief JSON-formated description of the RPC method.
         */
        Json::Value m_description;
    };

    /**
     * \class Handler
     * \brief Container of methods which can be called remotely.
     *
     * Preferred use of this class is to construct RpcMethod inside
     * another class and pass <code>*this</code> as obj parameter:\n
     * \n
     * \code
     * class MyClass
     * {
     *    public:
     *      void Init()
     *      {
     *        RpcMethod* method = new RpcMethod<MyClass>(*this, &MyClass::RemoteMethod, std::string("remote_method"),
     *          std::string("Description"));
     *        m_handler.AddMethod(method);
     *      }
     *
     *      bool RemoteMethod(const Json::Value& msg, Json::Value& response)
     *      {
     *        // do stuff
     *      }
     *
     *    private:
     *      Handler m_handler;
     * };
     * \endcode
     * \note Always pass it in function with reference
     * (i.e. void foo(Json::Rpc::Handler& handler)).
     * \see RpcMethod
     */
    class Handler
    {
      public:
        /**
         * \brief Constructor.
         */
        Handler();

        /**
         * \brief Destructor.
         */
        virtual ~Handler();

        /**
         * \brief Add a new RPC method.
         * \param method RPC method to add (MUST be dynamically allocated)
         * \note Json::Rpc::Handler object takes care of freeing method memory\n
         * The way of calling this method is:
         * <code>
         * handler.AddMethod(new RpcMethod<MyClass>(...));
         * </code>
         * \warning The "method" parameter MUST be dynamically allocated.
         */
        void AddMethod(CallbackMethod* method);

        /**
         * \brief Remote a RPC method.
         * \param name name of the RPC method
         */
        void DeleteMethod(const std::string& name);

        /**
         * \brief Process a JSON-RPC message.
         * \param msg JSON-RPC message as std::string
         * \param response JSON-RPC response (could be Json::Value::null)
         * \return true if the request has been correctly processed, false
         * otherwise (may be caused by parsed error, ...)
         * \note in case msg is a notification, response is equal to
         * Json::Value::null and the return value is true.
         */
        bool Process(const std::string& msg, Json::Value& response);

        /**
         * \brief Process a JSON-RPC message.
         * \param msg JSON-RPC message as C-String
         * \param response JSON-RPC response (could be Json::Value::null)
         * \return true if the request has been correctly processed, false
         * otherwise (may be caused by parsed error, ...)
         * \note in case msg is a notification, response is equal to
         * Json::Value::null and the return value is true.
         */
        bool Process(const char* msg, Json::Value& response);

        /**
         * \brief RPC method that get all the RPC methods and their description.
         * \param msg request
         * \param response response
         * \return true if processed correctly, false otherwise
         */
        bool SystemDescribe(const Json::Value& msg, Json::Value& response);

        /**
         * \brief Get a std::string representation of Json::Value.
         * \param value JSON message
         * \return string representation
         */
        std::string GetString(Json::Value value);

      private:
         /**
          * \brief Copy constructor (private to avoid copy).
          * \param obj object to copy
          */
        Handler(const Handler& obj);

        /**
         * \brief Operator copy assignment (redefined because of "resource"
         * class).
         * \param obj object to copy
         * \return object copied object reference
         */
        Handler& operator=(const Handler& obj);

        /**
         * \brief JSON reader.
         */
        Json::Reader m_reader;

        /**
         * \brief JSON writer.
         */
        Json::FastWriter m_writer;

        /**
         * \brief List of RPC methods.
         */
        std::list<CallbackMethod*> m_methods;

        /**
         * \brief Find CallbackMethod by name.
         * \param name name of the CallbackMethod
         * \return a CallbackMethod pointer if found, 0 otherwise
         */
        CallbackMethod* Lookup(const std::string& name) const;

        /**
         * \brief Check if the message is a valid JSON object one.
         * \param root message to check validity
         * \param error complete JSON-RPC error message if method failed
         * \return true if the message is a JSON one, false otherwise
         */
        bool Check(const Json::Value& root, Json::Value& error);

        /**
         * \brief Process a JSON-RPC object message.
         * \param root JSON-RPC message as Json::Value
         * \param response JSON-RPC response that will be filled in this method
         * \return true if request has been correctly processed, false otherwise
         * (may be caused by parsed error, ...)
         * \note In case msg is a notification, response is equal to
         * Json::Value::null and the return value is true.
         */
        bool Process(const Json::Value& root, Json::Value& response);
    };
  } /* namespace Rpc */
} /* namespace Json */

#endif /* JSONRPC_HANDLER_H */