Commit 648a545b0802db6886f88aa37ce07d55e063533c
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.
Showing
2 changed files
with
39 additions
and
21 deletions
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<const IHttpHandler> handler) | @@ -39,15 +41,8 @@ HueFinder::HueFinder(std::shared_ptr<const IHttpHandler> 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<HueFinder::HueIdentification> HueFinder::FindBridges() const { | @@ -57,18 +52,12 @@ std::vector<HueFinder::HueIdentification> 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 |