Commit 463fe25adc9402828bd029a9bf8da8da4fb18a3c

Authored by Jojo-1000
Committed by Moritz Wirger
1 parent e9c64111

Add safeGetMember function to get a json member or null.

hueplusplus/Hue.cpp
... ... @@ -37,6 +37,7 @@
37 37 #include "include/SimpleColorHueStrategy.h"
38 38 #include "include/SimpleColorTemperatureStrategy.h"
39 39 #include "include/UPnP.h"
  40 +#include "include/Utils.h"
40 41  
41 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&amp; ip)
180 181  
181 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 187 // [{"success":{"username": "<username>"}}]
186   - username = answer[0]["success"]["username"];
  188 + username = jsonUser;
187 189 this->ip = ip;
188 190 // Update commands with new username and ip
189 191 commands = HueCommandAPI(ip, port, username, http_handler);
... ... @@ -290,8 +292,7 @@ HueLight&amp; Hue::getLight(int id)
290 292 bool Hue::removeLight(int id)
291 293 {
292 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 296 if (success && lights.count(id) != 0)
296 297 {
297 298 lights.erase(id);
... ...
hueplusplus/HueLight.cpp
... ... @@ -132,8 +132,7 @@ bool HueLight::setName(const std::string&amp; name)
132 132 nlohmann::json reply = SendPutRequest(request, "/name");
133 133  
134 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 138 ColorType HueLight::getColorType() const
... ... @@ -235,7 +234,7 @@ void HueLight::refreshState()
235 234 // std::chrono::steady_clock::now(); std::cout << "\tRefreshing lampstate of
236 235 // lamp with id: " << id << ", ip: " << ip << "\n";
237 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 239 state = answer;
241 240 }
... ...
hueplusplus/Utils.cpp
... ... @@ -26,25 +26,25 @@
26 26  
27 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 31 bool success = false;
32 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 35 success = it.value().count("success");
36 36 if (success)
37 37 {
38 38 // Traverse through first object
39 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 41 ++successIt)
42 42 {
43 43 const std::string successPath = successIt.key();
44 44 if (successPath.find(path) == 0)
45 45 {
46 46 const std::string valueKey = successPath.substr(path.size());
47   - nlohmann::json::iterator requestIt = request.find(valueKey);
  47 + auto requestIt = request.find(valueKey);
48 48 success = requestIt != request.end();
49 49 if (success)
50 50 {
... ...
hueplusplus/include/Utils.h
... ... @@ -30,7 +30,33 @@ namespace utils
30 30 //! \param reply The reply that was received
31 31 //! \param lightId The identifier of the light
32 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 60 } // namespace utils
35 61  
36 62 #endif
37 63 \ No newline at end of file
... ...