From 463fe25adc9402828bd029a9bf8da8da4fb18a3c Mon Sep 17 00:00:00 2001 From: Jojo-1000 <33495614+Jojo-1000@users.noreply.github.com> Date: Thu, 2 Apr 2020 19:24:08 +0200 Subject: [PATCH] Add safeGetMember function to get a json member or null. --- hueplusplus/Hue.cpp | 9 +++++---- hueplusplus/HueLight.cpp | 5 ++--- hueplusplus/Utils.cpp | 8 ++++---- hueplusplus/include/Utils.h | 28 +++++++++++++++++++++++++++- 4 files changed, 38 insertions(+), 12 deletions(-) diff --git a/hueplusplus/Hue.cpp b/hueplusplus/Hue.cpp index 526b956..a5bddeb 100644 --- a/hueplusplus/Hue.cpp +++ b/hueplusplus/Hue.cpp @@ -37,6 +37,7 @@ #include "include/SimpleColorHueStrategy.h" #include "include/SimpleColorTemperatureStrategy.h" #include "include/UPnP.h" +#include "include/Utils.h" HueFinder::HueFinder(std::shared_ptr handler) : http_handler(std::move(handler)) {} @@ -180,10 +181,11 @@ std::string Hue::requestUsername(const std::string& ip) if (answer.size() > 0) { - if (answer[0].count("success")) + nlohmann::json jsonUser = utils::safeGetMember(answer, 0, "success", "username"); + if (jsonUser != nullptr) { // [{"success":{"username": ""}}] - username = answer[0]["success"]["username"]; + username = jsonUser; this->ip = ip; // Update commands with new username and ip commands = HueCommandAPI(ip, port, username, http_handler); @@ -290,8 +292,7 @@ HueLight& Hue::getLight(int id) bool Hue::removeLight(int id) { nlohmann::json result = commands.DELETERequest("/lights/" + std::to_string(id), nlohmann::json::object()); - bool success = result.is_array() && result.size() > 0 && result[0].count("success") - && result[0]["success"] == "/lights/" + std::to_string(id) + " deleted"; + bool success = utils::safeGetMember(result, 0, "success") == "/lights/" + std::to_string(id) + " deleted"; if (success && lights.count(id) != 0) { lights.erase(id); diff --git a/hueplusplus/HueLight.cpp b/hueplusplus/HueLight.cpp index 68cc66b..1b5877f 100755 --- a/hueplusplus/HueLight.cpp +++ b/hueplusplus/HueLight.cpp @@ -132,8 +132,7 @@ bool HueLight::setName(const std::string& name) nlohmann::json reply = SendPutRequest(request, "/name"); // Check whether request was successful - return reply.size() > 0 && reply[0].count("success") - && reply[0]["success"]["/lights/" + std::to_string(id) + "/name"] == name; + return utils::safeGetMember(reply, 0, "success", "/lights/" + std::to_string(id) + "/name") == name; } ColorType HueLight::getColorType() const @@ -235,7 +234,7 @@ void HueLight::refreshState() // std::chrono::steady_clock::now(); std::cout << "\tRefreshing lampstate of // lamp with id: " << id << ", ip: " << ip << "\n"; nlohmann::json answer = commands.GETRequest("/lights/" + std::to_string(id), nlohmann::json::object()); - if (answer.is_object() && answer.count("state")) + if (answer.count("state")) { state = answer; } diff --git a/hueplusplus/Utils.cpp b/hueplusplus/Utils.cpp index 1da50c2..3e4ee66 100644 --- a/hueplusplus/Utils.cpp +++ b/hueplusplus/Utils.cpp @@ -26,25 +26,25 @@ namespace utils { - bool validateReplyForLight(nlohmann::json request, nlohmann::json reply, int lightId) + bool validateReplyForLight(const nlohmann::json& request, const nlohmann::json& reply, int lightId) { bool success = false; std::string path = "/lights/" + std::to_string(lightId) + "/state/"; - for (nlohmann::json::iterator it = reply.begin(); it != reply.end(); ++it) + for (auto it = reply.begin(); it != reply.end(); ++it) { success = it.value().count("success"); if (success) { // Traverse through first object nlohmann::json successObject = it.value()["success"]; - for (nlohmann::json::iterator successIt = successObject.begin(); successIt != successObject.end(); + for (auto successIt = successObject.begin(); successIt != successObject.end(); ++successIt) { const std::string successPath = successIt.key(); if (successPath.find(path) == 0) { const std::string valueKey = successPath.substr(path.size()); - nlohmann::json::iterator requestIt = request.find(valueKey); + auto requestIt = request.find(valueKey); success = requestIt != request.end(); if (success) { diff --git a/hueplusplus/include/Utils.h b/hueplusplus/include/Utils.h index bd0a567..427572d 100644 --- a/hueplusplus/include/Utils.h +++ b/hueplusplus/include/Utils.h @@ -30,7 +30,33 @@ namespace utils //! \param reply The reply that was received //! \param lightId The identifier of the light //! \return True if request was executed correctly - bool validateReplyForLight(nlohmann::json request, nlohmann::json reply, int lightId); + bool validateReplyForLight(const nlohmann::json& request, const nlohmann::json& reply, int lightId); + + //! \brief Returns the object/array member or null if it does not exist + template + nlohmann::json safeGetMember(const nlohmann::json& json, std::size_t index, Paths&&... otherPaths) + { + if (!json.is_array() || json.size() <= index) + { + return nullptr; + } + return safeGetMember(json[index], std::forward(otherPaths)...); + } + template>::value>* = nullptr> + nlohmann::json safeGetMember(const nlohmann::json& json, KeyT&& key, Paths&&... otherPaths) + { + auto memberIt = json.find(std::forward(key)); + if (memberIt == json.end()) + { + return nullptr; + } + return safeGetMember(*memberIt, std::forward(otherPaths)...); + } + inline nlohmann::json safeGetMember(const nlohmann::json& json) + { + return json; + } } // namespace utils #endif \ No newline at end of file -- libgit2 0.21.4