Commit 648a545b0802db6886f88aa37ce07d55e063533c

Authored by Jojo-1000
Committed by Jan
1 parent 6914599f

Replace regex matching of description.xml with string find.

C++ regex library is slow and not fully supported for earlier gcc versions.
hueplusplus/Hue.cpp
... ... @@ -19,9 +19,11 @@
19 19  
20 20 #include "include/Hue.h"
21 21  
  22 +#include <algorithm>
  23 +#include <cctype>
22 24 #include <chrono>
23 25 #include <iostream>
24   -#include <regex>
  26 +#include <locale>
25 27 #include <stdexcept>
26 28 #include <thread>
27 29  
... ... @@ -39,15 +41,8 @@ HueFinder::HueFinder(std::shared_ptr&lt;const IHttpHandler&gt; handler)
39 41 std::vector<HueFinder::HueIdentification> HueFinder::FindBridges() const {
40 42 UPnP uplug;
41 43 std::vector<std::pair<std::string, std::string>> foundDevices =
42   - uplug.getDevices(http_handler);
  44 + uplug.getDevices(http_handler);
43 45  
44   - // Does not work
45   - std::regex manufRegex(
46   - "<manufacturer>Royal Philips Electronics</manufacturer>");
47   - std::regex manURLRegex(
48   - "<manufacturerURL>http://www\\.philips\\.com</manufacturerURL>");
49   - std::regex modelRegex("<modelName>Philips hue bridge[^<]*</modelName>");
50   - std::regex serialRegex("<serialNumber>(\\w+)</serialNumber>");
51 46 std::vector<HueIdentification> foundBridges;
52 47 for (const std::pair<std::string, std::string> &p : foundDevices) {
53 48 size_t found = p.second.find("IpBridge");
... ... @@ -57,18 +52,12 @@ std::vector&lt;HueFinder::HueIdentification&gt; HueFinder::FindBridges() const {
57 52 size_t length = p.first.find(":", start) - start;
58 53 bridge.ip = p.first.substr(start, length);
59 54 std::string desc = http_handler->GETString(
60   - "/description.xml", "application/xml", "", bridge.ip);
61   - std::smatch matchResult;
62   - if (std::regex_search(desc, manufRegex) &&
63   - std::regex_search(desc, manURLRegex) &&
64   - std::regex_search(desc, modelRegex) &&
65   - std::regex_search(desc, matchResult, serialRegex)) {
66   - // The string matches
67   - // Get 1st submatch (0 is whole match)
68   - bridge.mac = matchResult[1].str();
  55 + "/description.xml", "application/xml", "", bridge.ip);
  56 + std::string mac = ParseDescription(desc);
  57 + if (!mac.empty()) {
  58 + bridge.mac = NormalizeMac(mac);
69 59 foundBridges.push_back(std::move(bridge));
70 60 }
71   - // break;
72 61 }
73 62 }
74 63 return foundBridges;
... ... @@ -113,6 +102,28 @@ std::string HueFinder::NormalizeMac(std::string input) {
113 102 return input;
114 103 }
115 104  
  105 +std::string HueFinder::ParseDescription(const std::string & description)
  106 +{
  107 + const char* manufacturer = "<manufacturer>Royal Philips Electronics</manufacturer>";
  108 + const char* manURL = "<manufacturerURL>http://www.philips.com</manufacturerURL>";
  109 + const char* model = "<modelName>Philips hue bridge";
  110 + const char* serialBegin = "<serialNumber>";
  111 + const char* serialEnd = "</serialNumber>";
  112 + if (description.find(manufacturer) != std::string::npos && description.find(manURL) != std::string::npos
  113 + && description.find(model) != std::string::npos) {
  114 + std::size_t begin = description.find(serialBegin);
  115 + std::size_t end = description.find(serialEnd, begin);
  116 + if (begin != std::string::npos && end != std::string::npos) {
  117 + begin += std::strlen(serialBegin);
  118 + if (begin < description.size()) {
  119 + std::string result = description.substr(begin, end);
  120 + return result;
  121 + }
  122 + }
  123 + }
  124 + return std::string();
  125 +}
  126 +
116 127 Hue::Hue(const std::string &ip, const std::string &username,
117 128 std::shared_ptr<const IHttpHandler> handler)
118 129 : ip(ip), username(username), http_handler(std::move(handler)),
... ...
hueplusplus/include/Hue.h
... ... @@ -86,9 +86,16 @@ private:
86 86 //! \returns \p input without separators and whitespace, in upper case.
87 87 static std::string NormalizeMac(std::string input);
88 88  
  89 + //! \brief Parses mac address from description.xml
  90 + //!
  91 + //! \param description Content of description.xml file as returned by GET request.
  92 + //! \returns Content of xml element \c serialNumber if description matches a Hue bridge,
  93 + //! otherwise an empty string.
  94 + static std::string ParseDescription(const std::string& description);
  95 +
89 96 std::map<std::string, std::string>
90   - usernames; //!< Maps all macs to usernames added by \ref
91   - //!< HueFinder::AddUsername
  97 + usernames; //!< Maps all macs to usernames added by \ref
  98 + //!< HueFinder::AddUsername
92 99 std::shared_ptr<const IHttpHandler> http_handler;
93 100 };
94 101  
... ...