Commit 463fe25adc9402828bd029a9bf8da8da4fb18a3c
Committed by
Moritz Wirger
1 parent
e9c64111
Add safeGetMember function to get a json member or null.
Showing
4 changed files
with
38 additions
and
12 deletions
hueplusplus/Hue.cpp
| @@ -37,6 +37,7 @@ | @@ -37,6 +37,7 @@ | ||
| 37 | #include "include/SimpleColorHueStrategy.h" | 37 | #include "include/SimpleColorHueStrategy.h" |
| 38 | #include "include/SimpleColorTemperatureStrategy.h" | 38 | #include "include/SimpleColorTemperatureStrategy.h" |
| 39 | #include "include/UPnP.h" | 39 | #include "include/UPnP.h" |
| 40 | +#include "include/Utils.h" | ||
| 40 | 41 | ||
| 41 | HueFinder::HueFinder(std::shared_ptr<const IHttpHandler> handler) : http_handler(std::move(handler)) {} | 42 | HueFinder::HueFinder(std::shared_ptr<const IHttpHandler> handler) : http_handler(std::move(handler)) {} |
| 42 | 43 | ||
| @@ -180,10 +181,11 @@ std::string Hue::requestUsername(const std::string& ip) | @@ -180,10 +181,11 @@ std::string Hue::requestUsername(const std::string& ip) | ||
| 180 | 181 | ||
| 181 | if (answer.size() > 0) | 182 | if (answer.size() > 0) |
| 182 | { | 183 | { |
| 183 | - if (answer[0].count("success")) | 184 | + nlohmann::json jsonUser = utils::safeGetMember(answer, 0, "success", "username"); |
| 185 | + if (jsonUser != nullptr) | ||
| 184 | { | 186 | { |
| 185 | // [{"success":{"username": "<username>"}}] | 187 | // [{"success":{"username": "<username>"}}] |
| 186 | - username = answer[0]["success"]["username"]; | 188 | + username = jsonUser; |
| 187 | this->ip = ip; | 189 | this->ip = ip; |
| 188 | // Update commands with new username and ip | 190 | // Update commands with new username and ip |
| 189 | commands = HueCommandAPI(ip, port, username, http_handler); | 191 | commands = HueCommandAPI(ip, port, username, http_handler); |
| @@ -290,8 +292,7 @@ HueLight& Hue::getLight(int id) | @@ -290,8 +292,7 @@ HueLight& Hue::getLight(int id) | ||
| 290 | bool Hue::removeLight(int id) | 292 | bool Hue::removeLight(int id) |
| 291 | { | 293 | { |
| 292 | nlohmann::json result = commands.DELETERequest("/lights/" + std::to_string(id), nlohmann::json::object()); | 294 | nlohmann::json result = commands.DELETERequest("/lights/" + std::to_string(id), nlohmann::json::object()); |
| 293 | - bool success = result.is_array() && result.size() > 0 && result[0].count("success") | ||
| 294 | - && result[0]["success"] == "/lights/" + std::to_string(id) + " deleted"; | 295 | + bool success = utils::safeGetMember(result, 0, "success") == "/lights/" + std::to_string(id) + " deleted"; |
| 295 | if (success && lights.count(id) != 0) | 296 | if (success && lights.count(id) != 0) |
| 296 | { | 297 | { |
| 297 | lights.erase(id); | 298 | lights.erase(id); |
hueplusplus/HueLight.cpp
| @@ -132,8 +132,7 @@ bool HueLight::setName(const std::string& name) | @@ -132,8 +132,7 @@ bool HueLight::setName(const std::string& name) | ||
| 132 | nlohmann::json reply = SendPutRequest(request, "/name"); | 132 | nlohmann::json reply = SendPutRequest(request, "/name"); |
| 133 | 133 | ||
| 134 | // Check whether request was successful | 134 | // Check whether request was successful |
| 135 | - return reply.size() > 0 && reply[0].count("success") | ||
| 136 | - && reply[0]["success"]["/lights/" + std::to_string(id) + "/name"] == name; | 135 | + return utils::safeGetMember(reply, 0, "success", "/lights/" + std::to_string(id) + "/name") == name; |
| 137 | } | 136 | } |
| 138 | 137 | ||
| 139 | ColorType HueLight::getColorType() const | 138 | ColorType HueLight::getColorType() const |
| @@ -235,7 +234,7 @@ void HueLight::refreshState() | @@ -235,7 +234,7 @@ void HueLight::refreshState() | ||
| 235 | // std::chrono::steady_clock::now(); std::cout << "\tRefreshing lampstate of | 234 | // std::chrono::steady_clock::now(); std::cout << "\tRefreshing lampstate of |
| 236 | // lamp with id: " << id << ", ip: " << ip << "\n"; | 235 | // lamp with id: " << id << ", ip: " << ip << "\n"; |
| 237 | nlohmann::json answer = commands.GETRequest("/lights/" + std::to_string(id), nlohmann::json::object()); | 236 | nlohmann::json answer = commands.GETRequest("/lights/" + std::to_string(id), nlohmann::json::object()); |
| 238 | - if (answer.is_object() && answer.count("state")) | 237 | + if (answer.count("state")) |
| 239 | { | 238 | { |
| 240 | state = answer; | 239 | state = answer; |
| 241 | } | 240 | } |
hueplusplus/Utils.cpp
| @@ -26,25 +26,25 @@ | @@ -26,25 +26,25 @@ | ||
| 26 | 26 | ||
| 27 | namespace utils | 27 | namespace utils |
| 28 | { | 28 | { |
| 29 | - bool validateReplyForLight(nlohmann::json request, nlohmann::json reply, int lightId) | 29 | + bool validateReplyForLight(const nlohmann::json& request, const nlohmann::json& reply, int lightId) |
| 30 | { | 30 | { |
| 31 | bool success = false; | 31 | bool success = false; |
| 32 | std::string path = "/lights/" + std::to_string(lightId) + "/state/"; | 32 | std::string path = "/lights/" + std::to_string(lightId) + "/state/"; |
| 33 | - for (nlohmann::json::iterator it = reply.begin(); it != reply.end(); ++it) | 33 | + for (auto it = reply.begin(); it != reply.end(); ++it) |
| 34 | { | 34 | { |
| 35 | success = it.value().count("success"); | 35 | success = it.value().count("success"); |
| 36 | if (success) | 36 | if (success) |
| 37 | { | 37 | { |
| 38 | // Traverse through first object | 38 | // Traverse through first object |
| 39 | nlohmann::json successObject = it.value()["success"]; | 39 | nlohmann::json successObject = it.value()["success"]; |
| 40 | - for (nlohmann::json::iterator successIt = successObject.begin(); successIt != successObject.end(); | 40 | + for (auto successIt = successObject.begin(); successIt != successObject.end(); |
| 41 | ++successIt) | 41 | ++successIt) |
| 42 | { | 42 | { |
| 43 | const std::string successPath = successIt.key(); | 43 | const std::string successPath = successIt.key(); |
| 44 | if (successPath.find(path) == 0) | 44 | if (successPath.find(path) == 0) |
| 45 | { | 45 | { |
| 46 | const std::string valueKey = successPath.substr(path.size()); | 46 | const std::string valueKey = successPath.substr(path.size()); |
| 47 | - nlohmann::json::iterator requestIt = request.find(valueKey); | 47 | + auto requestIt = request.find(valueKey); |
| 48 | success = requestIt != request.end(); | 48 | success = requestIt != request.end(); |
| 49 | if (success) | 49 | if (success) |
| 50 | { | 50 | { |
hueplusplus/include/Utils.h
| @@ -30,7 +30,33 @@ namespace utils | @@ -30,7 +30,33 @@ namespace utils | ||
| 30 | //! \param reply The reply that was received | 30 | //! \param reply The reply that was received |
| 31 | //! \param lightId The identifier of the light | 31 | //! \param lightId The identifier of the light |
| 32 | //! \return True if request was executed correctly | 32 | //! \return True if request was executed correctly |
| 33 | - bool validateReplyForLight(nlohmann::json request, nlohmann::json reply, int lightId); | 33 | + bool validateReplyForLight(const nlohmann::json& request, const nlohmann::json& reply, int lightId); |
| 34 | + | ||
| 35 | + //! \brief Returns the object/array member or null if it does not exist | ||
| 36 | + template<typename... Paths> | ||
| 37 | + nlohmann::json safeGetMember(const nlohmann::json& json, std::size_t index, Paths&&... otherPaths) | ||
| 38 | + { | ||
| 39 | + if (!json.is_array() || json.size() <= index) | ||
| 40 | + { | ||
| 41 | + return nullptr; | ||
| 42 | + } | ||
| 43 | + return safeGetMember(json[index], std::forward<Paths>(otherPaths)...); | ||
| 44 | + } | ||
| 45 | + template<typename KeyT, typename... Paths, | ||
| 46 | + std::enable_if_t<!std::is_integral<std::remove_reference_t<KeyT>>::value>* = nullptr> | ||
| 47 | + nlohmann::json safeGetMember(const nlohmann::json& json, KeyT&& key, Paths&&... otherPaths) | ||
| 48 | + { | ||
| 49 | + auto memberIt = json.find(std::forward<KeyT>(key)); | ||
| 50 | + if (memberIt == json.end()) | ||
| 51 | + { | ||
| 52 | + return nullptr; | ||
| 53 | + } | ||
| 54 | + return safeGetMember(*memberIt, std::forward<Paths>(otherPaths)...); | ||
| 55 | + } | ||
| 56 | + inline nlohmann::json safeGetMember(const nlohmann::json& json) | ||
| 57 | + { | ||
| 58 | + return json; | ||
| 59 | + } | ||
| 34 | } // namespace utils | 60 | } // namespace utils |
| 35 | 61 | ||
| 36 | #endif | 62 | #endif |
| 37 | \ No newline at end of file | 63 | \ No newline at end of file |