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,9 +19,11 @@
19 19
20 #include "include/Hue.h" 20 #include "include/Hue.h"
21 21
  22 +#include <algorithm>
  23 +#include <cctype>
22 #include <chrono> 24 #include <chrono>
23 #include <iostream> 25 #include <iostream>
24 -#include <regex> 26 +#include <locale>
25 #include <stdexcept> 27 #include <stdexcept>
26 #include <thread> 28 #include <thread>
27 29
@@ -39,15 +41,8 @@ HueFinder::HueFinder(std::shared_ptr&lt;const IHttpHandler&gt; handler) @@ -39,15 +41,8 @@ HueFinder::HueFinder(std::shared_ptr&lt;const IHttpHandler&gt; handler)
39 std::vector<HueFinder::HueIdentification> HueFinder::FindBridges() const { 41 std::vector<HueFinder::HueIdentification> HueFinder::FindBridges() const {
40 UPnP uplug; 42 UPnP uplug;
41 std::vector<std::pair<std::string, std::string>> foundDevices = 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 std::vector<HueIdentification> foundBridges; 46 std::vector<HueIdentification> foundBridges;
52 for (const std::pair<std::string, std::string> &p : foundDevices) { 47 for (const std::pair<std::string, std::string> &p : foundDevices) {
53 size_t found = p.second.find("IpBridge"); 48 size_t found = p.second.find("IpBridge");
@@ -57,18 +52,12 @@ std::vector&lt;HueFinder::HueIdentification&gt; HueFinder::FindBridges() const { @@ -57,18 +52,12 @@ std::vector&lt;HueFinder::HueIdentification&gt; HueFinder::FindBridges() const {
57 size_t length = p.first.find(":", start) - start; 52 size_t length = p.first.find(":", start) - start;
58 bridge.ip = p.first.substr(start, length); 53 bridge.ip = p.first.substr(start, length);
59 std::string desc = http_handler->GETString( 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 foundBridges.push_back(std::move(bridge)); 59 foundBridges.push_back(std::move(bridge));
70 } 60 }
71 - // break;  
72 } 61 }
73 } 62 }
74 return foundBridges; 63 return foundBridges;
@@ -113,6 +102,28 @@ std::string HueFinder::NormalizeMac(std::string input) { @@ -113,6 +102,28 @@ std::string HueFinder::NormalizeMac(std::string input) {
113 return input; 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 Hue::Hue(const std::string &ip, const std::string &username, 127 Hue::Hue(const std::string &ip, const std::string &username,
117 std::shared_ptr<const IHttpHandler> handler) 128 std::shared_ptr<const IHttpHandler> handler)
118 : ip(ip), username(username), http_handler(std::move(handler)), 129 : ip(ip), username(username), http_handler(std::move(handler)),
hueplusplus/include/Hue.h
@@ -86,9 +86,16 @@ private: @@ -86,9 +86,16 @@ private:
86 //! \returns \p input without separators and whitespace, in upper case. 86 //! \returns \p input without separators and whitespace, in upper case.
87 static std::string NormalizeMac(std::string input); 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 std::map<std::string, std::string> 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 std::shared_ptr<const IHttpHandler> http_handler; 99 std::shared_ptr<const IHttpHandler> http_handler;
93 }; 100 };
94 101