Changeset 14552


Ignore:
Timestamp:
Jul 13, 2015, 12:32:48 AM (7 years ago)
Author:
mikedld
Message:

Improve RPC performance for local sessions

Don't unnecessarily de-/serialize JSON data if local session is used.

Location:
trunk
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/gtk/details.c

    r14509 r14552  
    24432443          if (tr_urlIsValidTracker (url))
    24442444            {
    2445               char * json = g_strdup_printf (
    2446                 "{\n"
    2447                 "  \"method\": \"torrent-set\",\n"
    2448                 "  \"arguments\": { \"id\": %d, \"trackerAdd\": [ \"%s\" ] }\n"
    2449                 "}\n",
    2450               torrent_id, url);
    2451               gtr_core_exec_json (di->core, json);
     2445              tr_variant top, * args, * trackers;
     2446
     2447              tr_variantInitDict (&top, 2);
     2448              tr_variantDictAddStr (&top, TR_KEY_method, "torrent-set");
     2449              args = tr_variantDictAddDict (&top, TR_KEY_arguments, 2);
     2450              tr_variantDictAddInt (args, TR_KEY_id, torrent_id);
     2451              trackers = tr_variantDictAddList (args, TR_KEY_trackerAdd, 1);
     2452              tr_variantListAddStr (trackers, url);
     2453
     2454              gtr_core_exec (di->core, &top);
    24522455              refresh (di);
    2453               g_free (json);
     2456
     2457              tr_variantFree (&top);
    24542458            }
    24552459          else
     
    25192523  if (gtk_tree_selection_get_selected (sel, &model, &iter))
    25202524    {
    2521       char * json;
    25222525      int torrent_id;
    25232526      int tracker_id;
     2527      tr_variant top, * args, * trackers;
     2528
    25242529      gtk_tree_model_get (model, &iter, TRACKER_COL_TRACKER_ID, &tracker_id,
    25252530                                        TRACKER_COL_TORRENT_ID, &torrent_id,
    25262531                                        -1);
    2527       json = g_strdup_printf ("{\n"
    2528                               "  \"method\": \"torrent-set\",\n"
    2529                               "  \"arguments\": { \"id\": %d, \"trackerRemove\": [ %d ] }\n"
    2530                               "}\n",
    2531                               torrent_id, tracker_id);
    2532       gtr_core_exec_json (di->core, json);
     2532
     2533      tr_variantInitDict (&top, 2);
     2534      tr_variantDictAddStr (&top, TR_KEY_method, "torrent-set");
     2535      args = tr_variantDictAddDict (&top, TR_KEY_arguments, 2);
     2536      tr_variantDictAddInt (args, TR_KEY_id, torrent_id);
     2537      trackers = tr_variantDictAddList (args, TR_KEY_trackerRemove, 1);
     2538      tr_variantListAddInt (trackers, tracker_id);
     2539
     2540      gtr_core_exec (di->core, &top);
    25332541      refresh (di);
    2534       g_free (json);
     2542
     2543      tr_variantFree (&top);
    25352544    }
    25362545}
  • trunk/gtk/main.c

    r14428 r14552  
    14151415  if (tr_variantListSize (ids) != 0)
    14161416    {
    1417       int json_len;
    1418       char * json = tr_variantToStr (&top, TR_VARIANT_FMT_JSON_LEAN, &json_len);
    1419       tr_rpc_request_exec_json (session, json, json_len, NULL, NULL);
    1420       g_free (json);
     1417      tr_rpc_request_exec_json (session, &top, NULL, NULL);
    14211418      invoked = TRUE;
    14221419    }
     
    14681465{
    14691466  tr_session * session = gtr_core_session (data->core);
    1470   const char * cmd = "{ \"method\": \"torrent-start\" }";
    1471   tr_rpc_request_exec_json (session, cmd, strlen (cmd), NULL, NULL);
     1467  tr_variant request;
     1468
     1469  tr_variantInitDict (&request, 1);
     1470  tr_variantDictAddStr (&request, TR_KEY_method, "torrent-start");
     1471  tr_rpc_request_exec_json (session, &request, NULL, NULL);
     1472  tr_variantFree (&request);
    14721473}
    14731474
     
    14761477{
    14771478  tr_session * session = gtr_core_session (data->core);
    1478   const char * cmd = "{ \"method\": \"torrent-stop\" }";
    1479   tr_rpc_request_exec_json (session, cmd, strlen (cmd), NULL, NULL);
     1479  tr_variant request;
     1480
     1481  tr_variantInitDict (&request, 1);
     1482  tr_variantDictAddStr (&request, TR_KEY_method, "torrent-stop");
     1483  tr_rpc_request_exec_json (session, &request, NULL, NULL);
     1484  tr_variantFree (&request);
    14801485}
    14811486
  • trunk/gtk/tr-core.c

    r14532 r14552  
    17271727core_read_rpc_response_idle (void * vresponse)
    17281728{
    1729   tr_variant top;
    17301729  int64_t intVal;
    1731   struct evbuffer * response = vresponse;
    1732 
    1733   tr_variantFromJson (&top, evbuffer_pullup (response, -1), evbuffer_get_length (response));
    1734 
    1735   if (tr_variantDictFindInt (&top, TR_KEY_tag, &intVal))
     1730  tr_variant * response = vresponse;
     1731
     1732  if (tr_variantDictFindInt (response, TR_KEY_tag, &intVal))
    17361733    {
    17371734      const int tag = (int)intVal;
     
    17401737        {
    17411738          if (data->response_func)
    1742             (*data->response_func)(data->core, &top, data->response_func_user_data);
     1739            (*data->response_func)(data->core, response, data->response_func_user_data);
    17431740          g_hash_table_remove (pendingRequests, &tag);
    17441741        }
    17451742    }
    17461743
    1747   tr_variantFree (&top);
    1748   evbuffer_free (response);
     1744  tr_variantFree (response);
     1745  tr_free (response);
    17491746  return G_SOURCE_REMOVE;
    17501747}
    17511748
    17521749static void
    1753 core_read_rpc_response (tr_session       * session UNUSED,
    1754                         struct evbuffer  * response,
    1755                         void             * unused UNUSED)
    1756 {
    1757   struct evbuffer * buf = evbuffer_new ();
    1758   evbuffer_add_buffer (buf, response);
    1759   gdk_threads_add_idle (core_read_rpc_response_idle, buf);
    1760 }
    1761 
    1762 static void
    1763 core_send_rpc_request (TrCore * core, const char * json, int tag,
     1750core_read_rpc_response (tr_session * session UNUSED,
     1751                        tr_variant * response,
     1752                        void       * unused UNUSED)
     1753{
     1754  tr_variant * response_copy = tr_new (tr_variant, 1);
     1755
     1756  *response_copy = *response;
     1757  tr_variantInitBool (response, false);
     1758
     1759  gdk_threads_add_idle (core_read_rpc_response_idle, response_copy);
     1760}
     1761
     1762static void
     1763core_send_rpc_request (TrCore * core, const tr_variant * request, int tag,
    17641764                       server_response_func * response_func,
    17651765                       void * response_func_user_data)
     
    17881788      /* make the request */
    17891789#ifdef DEBUG_RPC
    1790       g_message ("request: [%s]", json);
     1790      {
     1791        struct evbuffer * buf = tr_variantToBuf (request, TR_VARIANT_FMT_JSON_LEAN);
     1792        const size_t buf_len = evbuffer_get_length (buf);
     1793        g_message ("request: [%*.*s]", (int) buf_len, (int) buf_len, evbuffer_pullup (buf, -1));
     1794        evbuffer_free (buf);
     1795      }
    17911796#endif
    1792       tr_rpc_request_exec_json (session, json, strlen (json), core_read_rpc_response, GINT_TO_POINTER (tag));
     1797
     1798      tr_rpc_request_exec_json (session, request, core_read_rpc_response, GINT_TO_POINTER (tag));
    17931799    }
    17941800}
     
    18141820gtr_core_port_test (TrCore * core)
    18151821{
    1816   char buf[64];
    18171822  const int tag = nextTag++;
    1818   g_snprintf (buf, sizeof (buf), "{ \"method\": \"port-test\", \"tag\": %d }", tag);
    1819   core_send_rpc_request (core, buf, tag, on_port_test_response, NULL);
     1823  tr_variant request;
     1824
     1825  tr_variantInitDict (&request, 2);
     1826  tr_variantDictAddStr (&request, TR_KEY_method, "port-test");
     1827  tr_variantDictAddInt (&request, TR_KEY_tag, tag);
     1828  core_send_rpc_request (core, &request, tag, on_port_test_response, NULL);
     1829  tr_variantFree (&request);
    18201830}
    18211831
     
    18431853gtr_core_blocklist_update (TrCore * core)
    18441854{
    1845   char buf[64];
    18461855  const int tag = nextTag++;
    1847   g_snprintf (buf, sizeof (buf), "{ \"method\": \"blocklist-update\", \"tag\": %d }", tag);
    1848   core_send_rpc_request (core, buf, tag, on_blocklist_response, NULL);
     1856  tr_variant request;
     1857
     1858  tr_variantInitDict (&request, 2);
     1859  tr_variantDictAddStr (&request, TR_KEY_method, "blocklist-update");
     1860  tr_variantDictAddInt (&request, TR_KEY_tag, tag);
     1861  core_send_rpc_request (core, &request, tag, on_blocklist_response, NULL);
     1862  tr_variantFree (&request);
    18491863}
    18501864
     
    18541868
    18551869void
    1856 gtr_core_exec_json (TrCore * core, const char * json)
     1870gtr_core_exec (TrCore * core, const tr_variant * top)
    18571871{
    18581872  const int tag = nextTag++;
    1859   core_send_rpc_request (core, json, tag, NULL, NULL);
    1860 }
    1861 
    1862 void
    1863 gtr_core_exec (TrCore * core, const tr_variant * top)
    1864 {
    1865   char * json = tr_variantToStr (top, TR_VARIANT_FMT_JSON_LEAN, NULL);
    1866   gtr_core_exec_json (core, json);
    1867   tr_free (json);
     1873  core_send_rpc_request (core, top, tag, NULL, NULL);
    18681874}
    18691875
  • trunk/gtk/tr-core.h

    r13983 r14552  
    156156void gtr_core_exec (TrCore * core, const tr_variant * benc);
    157157
    158 void gtr_core_exec_json (TrCore * core, const char * json);
    159 
    160158void gtr_core_open_folder (TrCore * core, int torrent_id);
    161159
  • trunk/libtransmission/rpc-server.c

    r14525 r14552  
    266266
    267267          if (have_source)
    268             {
    269               struct evbuffer * json = tr_variantToBuf (&top, TR_VARIANT_FMT_JSON);
    270               tr_rpc_request_exec_json (server->session,
    271                                         evbuffer_pullup (json, -1),
    272                                         evbuffer_get_length (json),
    273                                         NULL, NULL);
    274               evbuffer_free (json);
    275             }
     268            tr_rpc_request_exec_json (server->session, &top, NULL, NULL);
    276269
    277270          tr_variantFree (&top);
     
    517510
    518511static void
    519 rpc_response_func (tr_session      * session UNUSED,
    520                    struct evbuffer * response,
    521                    void            * user_data)
     512rpc_response_func (tr_session * session UNUSED,
     513                   tr_variant * response,
     514                   void       * user_data)
    522515{
    523516  struct rpc_response_data * data = user_data;
     517  struct evbuffer * response_buf = tr_variantToBuf (response, TR_VARIANT_FMT_JSON_LEAN);
    524518  struct evbuffer * buf = evbuffer_new ();
    525519
    526   add_response (data->req, data->server, buf, response);
     520  add_response (data->req, data->server, buf, response_buf);
    527521  evhttp_add_header (data->req->output_headers,
    528522                     "Content-Type", "application/json; charset=UTF-8");
     
    530524
    531525  evbuffer_free (buf);
     526  evbuffer_free (response_buf);
    532527  tr_free (data);
    533528}
     
    539534                      size_t                  json_len)
    540535{
     536  tr_variant top;
     537  bool have_content = tr_variantFromJson (&top, json, json_len) == 0;
    541538  struct rpc_response_data * data;
    542539
     
    545542  data->server = server;
    546543
    547   tr_rpc_request_exec_json (server->session, json, json_len, rpc_response_func, data);
     544  tr_rpc_request_exec_json (server->session, have_content ? &top : NULL, rpc_response_func, data);
     545
     546  if (have_content)
     547    tr_variantFree (&top);
    548548}
    549549
  • trunk/libtransmission/rpc-test.c

    r14241 r14552  
    77 * $Id$
    88 */
    9 
    10 #include <string.h>
    11 
    12 #include <event2/buffer.h>
    139
    1410#include "transmission.h"
     
    7672
    7773static void
    78 rpc_response_func (tr_session      * session    UNUSED,
    79                    struct evbuffer * response,
    80                    void            * setme)
     74rpc_response_func (tr_session * session    UNUSED,
     75                   tr_variant * response,
     76                   void       * setme)
    8177{
    82   tr_variantFromBuf (setme, TR_VARIANT_FMT_JSON, evbuffer_pullup(response,-1), evbuffer_get_length(response), NULL, NULL);
     78  *(tr_variant *) setme = *response;
     79  tr_variantInitBool (response, false);
    8380}
    8481
     
    8784{
    8885  tr_session * session;
    89   const char * json;
     86  tr_variant request;
    9087  tr_variant response;
    9188  tr_variant * args;
     
    9693  check (tor != NULL);
    9794
    98   json = "{\"method\":\"session-get\"}";
    99   tr_rpc_request_exec_json (session, json, strlen(json), rpc_response_func, &response);
     95  tr_variantInitDict (&request, 1);
     96  tr_variantDictAddStr (&request, TR_KEY_method, "session-get");
     97  tr_rpc_request_exec_json (session, &request, rpc_response_func, &response);
     98  tr_variantFree (&request);
    10099
    101   check (tr_variantIsDict(&response));
    102100  check (tr_variantIsDict(&response));
    103101  check (tr_variantDictFindDict (&response, TR_KEY_arguments, &args));
  • trunk/libtransmission/rpcimpl.c

    r14526 r14552  
    8585struct tr_rpc_idle_data
    8686{
    87  tr_session            * session;
    88  tr_variant            * response;
    89  tr_variant            * args_out;
    90  tr_rpc_response_func    callback;
    91  void                  * callback_user_data;
     87  tr_session            * session;
     88  tr_variant            * response;
     89  tr_variant            * args_out;
     90  tr_rpc_response_func    callback;
     91  void                  * callback_user_data;
    9292};
    9393
     
    9595tr_idle_function_done (struct tr_rpc_idle_data * data, const char * result)
    9696{
    97  struct evbuffer * buf;
    98 
    99  if (result == NULL)
    100    result = "success";
    101  tr_variantDictAddStr (data->response, TR_KEY_result, result);
    102 
    103  buf = tr_variantToBuf (data->response, TR_VARIANT_FMT_JSON_LEAN);
    104  (*data->callback)(data->session, buf, data->callback_user_data);
    105  evbuffer_free (buf);
    106 
    107  tr_variantFree (data->response);
    108  tr_free (data->response);
    109  tr_free (data);
     97  if (result == NULL)
     98    result = "success";
     99  tr_variantDictAddStr (data->response, TR_KEY_result, result);
     100
     101  (*data->callback)(data->session, data->response, data->callback_user_data);
     102
     103  tr_variantFree (data->response);
     104  tr_free (data->response);
     105  tr_free (data);
    110106}
    111107
     
    14511447    }
    14521448
    1453     tr_idle_function_done (data, result);
     1449  tr_idle_function_done (data, result);
    14541450}
    14551451
     
    21782174
    21792175static void
    2180 noop_response_callback (tr_session       * session UNUSED,
    2181                         struct evbuffer * response UNUSED,
    2182                         void             * user_data UNUSED)
    2183 {
    2184 }
    2185 
    2186 static void
    2187 request_exec (tr_session             * session,
    2188               tr_variant             * request,
    2189               tr_rpc_response_func     callback,
    2190               void                   * callback_user_data)
     2176noop_response_callback (tr_session * session UNUSED,
     2177                        tr_variant * response UNUSED,
     2178                        void       * user_data UNUSED)
     2179{
     2180}
     2181
     2182void
     2183tr_rpc_request_exec_json (tr_session            * session,
     2184                          const tr_variant      * request,
     2185                          tr_rpc_response_func    callback,
     2186                          void                  * callback_user_data)
    21912187{
    21922188  int i;
    21932189  const char * str;
    2194   tr_variant * args_in = tr_variantDictFind (request, TR_KEY_arguments);
     2190  tr_variant * const mutable_request = (tr_variant *) request;
     2191  tr_variant * args_in = tr_variantDictFind (mutable_request, TR_KEY_arguments);
    21952192  const char * result = NULL;
    21962193
     
    21992196
    22002197  /* parse the request */
    2201   if (!tr_variantDictFindStr (request, TR_KEY_method, &str, NULL))
     2198  if (!tr_variantDictFindStr (mutable_request, TR_KEY_method, &str, NULL))
    22022199    {
    22032200      result = "no method name";
     
    22202217      int64_t tag;
    22212218      tr_variant response;
    2222       struct evbuffer * buf;
    22232219
    22242220      tr_variantInitDict (&response, 3);
    22252221      tr_variantDictAddDict (&response, TR_KEY_arguments, 0);
    22262222      tr_variantDictAddStr (&response, TR_KEY_result, result);
    2227       if (tr_variantDictFindInt (request, TR_KEY_tag, &tag))
     2223      if (tr_variantDictFindInt (mutable_request, TR_KEY_tag, &tag))
    22282224        tr_variantDictAddInt (&response, TR_KEY_tag, tag);
    22292225
    2230       buf = tr_variantToBuf (&response, TR_VARIANT_FMT_JSON_LEAN);
    2231       (*callback)(session, buf, callback_user_data);
    2232       evbuffer_free (buf);
     2226      (*callback)(session, &response, callback_user_data);
    22332227
    22342228      tr_variantFree (&response);
     
    22392233      tr_variant response;
    22402234      tr_variant * args_out;
    2241       struct evbuffer * buf;
    22422235
    22432236      tr_variantInitDict (&response, 3);
     
    22472240        result = "success";
    22482241      tr_variantDictAddStr (&response, TR_KEY_result, result);
    2249       if (tr_variantDictFindInt (request, TR_KEY_tag, &tag))
     2242      if (tr_variantDictFindInt (mutable_request, TR_KEY_tag, &tag))
    22502243        tr_variantDictAddInt (&response, TR_KEY_tag, tag);
    22512244
    2252       buf = tr_variantToBuf (&response, TR_VARIANT_FMT_JSON_LEAN);
    2253       (*callback)(session, buf, callback_user_data);
    2254       evbuffer_free (buf);
     2245      (*callback)(session, &response, callback_user_data);
    22552246
    22562247      tr_variantFree (&response);
     
    22632254      data->response = tr_new0 (tr_variant, 1);
    22642255      tr_variantInitDict (data->response, 3);
    2265       if (tr_variantDictFindInt (request, TR_KEY_tag, &tag))
     2256      if (tr_variantDictFindInt (mutable_request, TR_KEY_tag, &tag))
    22662257        tr_variantDictAddInt (data->response, TR_KEY_tag, tag);
    22672258      data->args_out = tr_variantDictAddDict (data->response, TR_KEY_arguments, 0);
     
    22702261      (*methods[i].func)(session, args_in, data->args_out, data);
    22712262    }
    2272 }
    2273 
    2274 void
    2275 tr_rpc_request_exec_json (tr_session            * session,
    2276                           const void            * request_json,
    2277                           int                     request_len,
    2278                           tr_rpc_response_func    callback,
    2279                           void                  * callback_user_data)
    2280 {
    2281   tr_variant top;
    2282   int have_content;
    2283 
    2284   if (request_len < 0)
    2285     request_len = strlen (request_json);
    2286 
    2287   have_content = !tr_variantFromJson (&top, request_json, request_len);
    2288   request_exec (session, have_content ? &top : NULL, callback, callback_user_data);
    2289 
    2290   if (have_content)
    2291     tr_variantFree (&top);
    22922263}
    22932264
     
    23672338    }
    23682339
    2369   request_exec (session, &top, callback, callback_user_data);
     2340  tr_rpc_request_exec_json (session, &top, callback, callback_user_data);
    23702341
    23712342  /* cleanup */
  • trunk/libtransmission/rpcimpl.h

    r14241 r14552  
    2222***/
    2323
    24 struct evbuffer;
     24typedef void (*tr_rpc_response_func)(tr_session * session,
     25                                     tr_variant * response,
     26                                     void       * user_data);
    2527
    26 typedef void (*tr_rpc_response_func)(tr_session      * session,
    27                                      struct evbuffer * response,
    28                                      void            * user_data);
    2928/* http://www.json.org/ */
    3029void tr_rpc_request_exec_json (tr_session            * session,
    31                                const void            * request_json,
    32                                int                     request_len,
     30                               const tr_variant      * request,
    3331                               tr_rpc_response_func    callback,
    3432                               void                  * callback_user_data);
  • trunk/qt/RpcClient.cc

    r14537 r14552  
    2929#define REQUEST_DATA_PROPERTY_KEY "requestData"
    3030
     31namespace
     32{
     33  void
     34  destroyVariant (tr_variant * json)
     35  {
     36    tr_variantFree (json);
     37    tr_free (json);
     38  }
     39
     40  TrVariantPtr
     41  createVariant ()
     42  {
     43    return TrVariantPtr (tr_new0 (tr_variant, 1), &destroyVariant);
     44  }
     45}
     46
    3147RpcClient::RpcClient (QObject * parent):
    3248  QObject (parent),
     
    3450  myNAM (nullptr)
    3551{
    36   connect (this, SIGNAL (responseReceived (QByteArray)),
    37            this, SLOT (parseResponse (QByteArray)));
     52  qRegisterMetaType<TrVariantPtr> ("TrVariantPtr");
     53
     54  connect (this, SIGNAL (responseReceived (TrVariantPtr)),
     55           this, SLOT (parseResponse (TrVariantPtr)));
    3856}
    3957
     
    97115RpcClient::exec (const char* method, tr_variant * args, int64_t tag)
    98116{
    99   tr_variant top;
    100   tr_variantInitDict (&top, 3);
    101   tr_variantDictAddStr (&top, TR_KEY_method, method);
     117  TrVariantPtr json = createVariant ();
     118  tr_variantInitDict (json.get (), 3);
     119  tr_variantDictAddStr (json.get (), TR_KEY_method, method);
    102120  if (tag >= 0)
    103     tr_variantDictAddInt (&top, TR_KEY_tag, tag);
     121    tr_variantDictAddInt (json.get (), TR_KEY_tag, tag);
    104122  if (args != nullptr)
    105     tr_variantDictSteal (&top, TR_KEY_arguments, args);
    106 
    107   int length;
    108   char * str = tr_variantToStr (&top, TR_VARIANT_FMT_JSON_LEAN, &length);
    109   sendRequest (QByteArray (str, length));
    110   tr_free (str);
    111 
    112   tr_variantFree (&top);
    113 }
    114 
    115 void
    116 RpcClient::sendRequest (const QByteArray& json)
     123    tr_variantDictSteal (json.get (), TR_KEY_arguments, args);
     124
     125  sendRequest (json);
     126}
     127
     128void
     129RpcClient::sendRequest (TrVariantPtr json)
    117130{
    118131  if (mySession != nullptr)
    119132    {
    120       tr_rpc_request_exec_json (mySession, json.constData (), json.size (), localSessionCallback, this);
     133      tr_rpc_request_exec_json (mySession, json.get (), localSessionCallback, this);
    121134    }
    122135  else if (!myUrl.isEmpty ())
     
    130143        request.setRawHeader (TR_RPC_SESSION_ID_HEADER, mySessionId.toUtf8 ());
    131144
    132       QNetworkReply * reply = networkAccessManager ()->post (request, json);
    133       reply->setProperty (REQUEST_DATA_PROPERTY_KEY, json);
     145      int rawJsonDataLength;
     146      char * rawJsonData = tr_variantToStr (json.get (), TR_VARIANT_FMT_JSON_LEAN, &rawJsonDataLength);
     147      QByteArray jsonData (rawJsonData, rawJsonDataLength);
     148      tr_free (rawJsonData);
     149
     150      QNetworkReply * reply = networkAccessManager ()->post (request, jsonData);
     151      reply->setProperty (REQUEST_DATA_PROPERTY_KEY, QVariant::fromValue (json));
    134152      connect (reply, SIGNAL (downloadProgress (qint64, qint64)), this, SIGNAL (dataReadProgress ()));
    135153      connect (reply, SIGNAL (uploadProgress (qint64, qint64)), this, SIGNAL (dataSendProgress ()));
     
    143161                  << request.rawHeader (b).constData ()
    144162                  << std::endl;
    145       std::cerr << "Body:\n" << json.constData () << std::endl;
     163      std::cerr << "Body:\n" << jsonData.constData () << std::endl;
    146164#endif
    147165    }
     
    166184
    167185void
    168 RpcClient::localSessionCallback (tr_session * s, evbuffer * json, void * vself)
     186RpcClient::localSessionCallback (tr_session * s, tr_variant * response, void * vself)
    169187{
    170188  Q_UNUSED (s);
    171189
    172190  RpcClient * self = static_cast<RpcClient*> (vself);
     191
     192  TrVariantPtr json = createVariant ();
     193  *json = *response;
     194  tr_variantInitBool (response, false);
    173195
    174196  // this callback is invoked in the libtransmission thread, so we don't want
    175197  // to process the response here... let's push it over to the Qt thread.
    176   self->responseReceived (QByteArray (reinterpret_cast<const char*> (evbuffer_pullup (json, -1)),
    177                                       static_cast<int> (evbuffer_get_length (json))).trimmed ());
     198  self->responseReceived (json);
    178199}
    179200
     
    197218      // update it and resubmit the request.
    198219      mySessionId = QString::fromUtf8 (reply->rawHeader (TR_RPC_SESSION_ID_HEADER));
    199       sendRequest (reply->property (REQUEST_DATA_PROPERTY_KEY).toByteArray ());
     220      sendRequest (reply->property (REQUEST_DATA_PROPERTY_KEY).value<TrVariantPtr> ());
    200221    }
    201222  else if (reply->error () != QNetworkReply::NoError)
     
    205226  else
    206227    {
    207       parseResponse (reply->readAll ().trimmed ());
     228      const QByteArray jsonData = reply->readAll ().trimmed ();
     229
     230      TrVariantPtr json = createVariant ();
     231      if (tr_variantFromJson (json.get (), jsonData.constData (), jsonData.size ()) == 0)
     232        parseResponse (json);
     233
    208234      emit error (QNetworkReply::NoError);
    209235    }
     
    213239
    214240void
    215 RpcClient::parseResponse (const QByteArray& json)
    216 {
    217   tr_variant top;
    218   if (tr_variantFromJson (&top, json.constData (), json.size ()) != 0)
    219     return;
    220 
     241RpcClient::parseResponse (TrVariantPtr json)
     242{
    221243  int64_t tag;
    222   if (!tr_variantDictFindInt (&top, TR_KEY_tag, &tag))
     244  if (!tr_variantDictFindInt (json.get (), TR_KEY_tag, &tag))
    223245    tag = -1;
    224246
    225247  const char * result;
    226   if (!tr_variantDictFindStr (&top, TR_KEY_result, &result, nullptr))
     248  if (!tr_variantDictFindStr (json.get (), TR_KEY_result, &result, nullptr))
    227249    result = nullptr;
    228250
    229251  tr_variant * args;
    230   if (!tr_variantDictFindDict (&top, TR_KEY_arguments, &args))
     252  if (!tr_variantDictFindDict (json.get (), TR_KEY_arguments, &args))
    231253    args = nullptr;
    232254
    233255  emit executed (tag, result == nullptr ? QString () : QString::fromUtf8 (result), args);
    234 
    235   tr_variantFree (&top);
    236 }
     256}
  • trunk/qt/RpcClient.h

    r14537 r14552  
    1111#define QTR_RPC_CLIENT_H
    1212
     13#include <memory>
     14
    1315#include <QNetworkReply>
    1416#include <QObject>
     
    1820#include <libtransmission/transmission.h>
    1921#include <libtransmission/quark.h>
     22#include <libtransmission/variant.h>
    2023
    2124class QByteArray;
    2225class QNetworkAccessManager;
     26
     27typedef std::shared_ptr<tr_variant> TrVariantPtr;
     28Q_DECLARE_METATYPE (TrVariantPtr);
    2329
    2430extern "C"
     
    2632  struct evbuffer;
    2733  struct tr_session;
    28   struct tr_variant;
    2934}
    3035
     
    5661
    5762    // private
    58     void responseReceived (const QByteArray& json);
     63    void responseReceived (TrVariantPtr json);
    5964
    6065  private:
    61     void sendRequest (const QByteArray& json);
     66    void sendRequest (TrVariantPtr json);
    6267    QNetworkAccessManager * networkAccessManager ();
    6368
    64     static void localSessionCallback (tr_session * s, evbuffer * json, void * vself);
     69    static void localSessionCallback (tr_session * s, tr_variant * response, void * vself);
    6570
    6671  private slots:
    6772    void onFinished (QNetworkReply * reply);
    68     void parseResponse (const QByteArray& json);
     73    void parseResponse (TrVariantPtr json);
    6974
    7075  private:
Note: See TracChangeset for help on using the changeset viewer.