From abbb1a42a72a83f83194b34c1e4dcb7b61849f54 Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 31 Oct 2018 17:51:07 +0300 Subject: [PATCH] Static execute in JSON interface. GitOrigin-RevId: 58748f011a6def1d81e11063e9a15f5a8750174e --- example/python/tdjson_example.py | 2 +- td/telegram/ClientJson.cpp | 63 +++++++++++++++++++------------- td/telegram/ClientJson.h | 12 +----- td/telegram/td_json_client.cpp | 2 +- td/telegram/td_json_client.h | 2 +- 5 files changed, 42 insertions(+), 39 deletions(-) diff --git a/example/python/tdjson_example.py b/example/python/tdjson_example.py index 57e2013ca..27ef64eb7 100644 --- a/example/python/tdjson_example.py +++ b/example/python/tdjson_example.py @@ -79,7 +79,7 @@ def td_receive(): def td_execute(query): query = json.dumps(query).encode('utf-8') - result = td_json_client_execute(client, query) + result = td_json_client_execute(None, query) if result: result = json.loads(result.decode('utf-8')) return result diff --git a/td/telegram/ClientJson.cpp b/td/telegram/ClientJson.cpp index ad61126f0..2092f4d24 100644 --- a/td/telegram/ClientJson.cpp +++ b/td/telegram/ClientJson.cpp @@ -14,55 +14,50 @@ #include "td/utils/format.h" #include "td/utils/JsonBuilder.h" #include "td/utils/logging.h" +#include "td/utils/port/thread_local.h" #include "td/utils/Status.h" +#include + namespace td { -Result ClientJson::to_request(Slice request) { +static Result, string>> to_request(Slice request) { auto request_str = request.str(); TRY_RESULT(json_value, json_decode(request_str)); if (json_value.type() != JsonValue::Type::Object) { return Status::Error("Expected an Object"); } - std::uint64_t extra_id = extra_id_.fetch_add(1, std::memory_order_relaxed); + + string extra; if (has_json_object_field(json_value.get_object(), "@extra")) { - std::lock_guard guard(mutex_); - extra_[extra_id] = json_encode( + extra = json_encode( get_json_object_field(json_value.get_object(), "@extra", JsonValue::Type::Null).move_as_ok()); } td_api::object_ptr func; TRY_STATUS(from_json(func, json_value)); - return Client::Request{extra_id, std::move(func)}; + return std::make_pair(std::move(func), extra); } -std::string ClientJson::from_response(Client::Response response) { - auto str = json_encode(ToJson(*response.object)); +static std::string from_response(const td_api::Object &object, const string &extra) { + auto str = json_encode(ToJson(object)); CHECK(!str.empty() && str.back() == '}'); - std::string extra; - if (response.id != 0) { - std::lock_guard guard(mutex_); - auto it = extra_.find(response.id); - if (it != extra_.end()) { - extra = std::move(it->second); - extra_.erase(it); - } - } if (!extra.empty()) { str.pop_back(); - str.reserve(str.size() + 10 + extra.size()); + str.reserve(str.size() + 11 + extra.size()); str += ",\"@extra\":"; str += extra; - str += "}"; + str += '}'; } return str; } -TD_THREAD_LOCAL std::string *ClientJson::current_output_; -CSlice ClientJson::store_string(std::string str) { - init_thread_local(ClientJson::current_output_); - *current_output_ = std::move(str); - return *current_output_; +static TD_THREAD_LOCAL std::string *current_output; + +static CSlice store_string(std::string str) { + init_thread_local(current_output); + *current_output = std::move(str); + return *current_output; } void ClientJson::send(Slice request) { @@ -72,7 +67,12 @@ void ClientJson::send(Slice request) { return; } - client_.send(r_request.move_as_ok()); + std::uint64_t extra_id = extra_id_.fetch_add(1, std::memory_order_relaxed); + if (!r_request.ok_ref().second.empty()) { + std::lock_guard guard(mutex_); + extra_[extra_id] = std::move(r_request.ok_ref().second); + } + client_.send(Client::Request{extra_id, std::move(r_request.ok_ref().first)}); } CSlice ClientJson::receive(double timeout) { @@ -80,7 +80,17 @@ CSlice ClientJson::receive(double timeout) { if (!response.object) { return {}; } - return store_string(from_response(std::move(response))); + + std::string extra; + if (response.id != 0) { + std::lock_guard guard(mutex_); + auto it = extra_.find(response.id); + if (it != extra_.end()) { + extra = std::move(it->second); + extra_.erase(it); + } + } + return store_string(from_response(*response.object, extra)); } CSlice ClientJson::execute(Slice request) { @@ -90,7 +100,8 @@ CSlice ClientJson::execute(Slice request) { return {}; } - return store_string(from_response(Client::execute(r_request.move_as_ok()))); + return store_string(from_response(*Client::execute(Client::Request{0, std::move(r_request.ok_ref().first)}).object, + r_request.ok().second)); } } // namespace td diff --git a/td/telegram/ClientJson.h b/td/telegram/ClientJson.h index 880f144d9..f7848dff1 100644 --- a/td/telegram/ClientJson.h +++ b/td/telegram/ClientJson.h @@ -8,16 +8,13 @@ #include "td/telegram/Client.h" -#include "td/utils/port/thread_local.h" #include "td/utils/Slice.h" -#include "td/utils/Status.h" #include #include #include #include #include -#include namespace td { @@ -27,18 +24,13 @@ class ClientJson final { CSlice receive(double timeout); - CSlice execute(Slice request); + static CSlice execute(Slice request); private: Client client_; std::mutex mutex_; // for extra_ std::unordered_map extra_; std::atomic extra_id_{1}; - static TD_THREAD_LOCAL std::string *current_output_; - - CSlice store_string(std::string str); - - Result to_request(Slice request); - std::string from_response(Client::Response response); }; + } // namespace td diff --git a/td/telegram/td_json_client.cpp b/td/telegram/td_json_client.cpp index b83bab28c..36b498961 100644 --- a/td/telegram/td_json_client.cpp +++ b/td/telegram/td_json_client.cpp @@ -36,7 +36,7 @@ const char *td_json_client_receive(void *client, double timeout) { } const char *td_json_client_execute(void *client, const char *request) { - auto slice = static_cast(client)->execute(td::Slice(request == nullptr ? "" : request)); + auto slice = td::ClientJson::execute(td::Slice(request == nullptr ? "" : request)); if (slice.empty()) { return nullptr; } else { diff --git a/td/telegram/td_json_client.h b/td/telegram/td_json_client.h index 55a0f0083..2efd92471 100644 --- a/td/telegram/td_json_client.h +++ b/td/telegram/td_json_client.h @@ -82,7 +82,7 @@ TDJSON_EXPORT const char *td_json_client_receive(void *client, double timeout); * Only a few requests can be executed synchronously. * Returned pointer will be deallocated by TDLib during next call to td_json_client_receive or td_json_client_execute * in the same thread, so it can't be used after that. - * \param[in] client The client. + * \param[in] client The client. Currently ignored for all requests, so NULL can be passed. * \param[in] request JSON-serialized null-terminated request to TDLib. * \return JSON-serialized null-terminated request response. May be NULL if the request can't be parsed. */