From b7db370449cfe2b453c22b74a660701f78bd7ce3 Mon Sep 17 00:00:00 2001 From: Anatolii Lapytskyi Date: Tue, 6 Sep 2022 15:59:27 +0200 Subject: [PATCH] Remove dependency on libxml2 --- CMakeLists.txt | 5 +- README.md | 5 +- SpeedTest.cpp | 136 ++++++++++++++----------------------------------- SpeedTest.h | 2 - 4 files changed, 41 insertions(+), 107 deletions(-) --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,7 +44,6 @@ add_executable(SpeedTest ${SOURCE_FILES} INCLUDE (CheckIncludeFiles) find_package(CURL REQUIRED) -find_package(LibXml2 REQUIRED) if (NOT (APPLE)) find_package(OpenSSL REQUIRED) @@ -52,7 +51,7 @@ else() CHECK_INCLUDE_FILES("CommonCrypto/CommonDigest.h" HAVE_COMMON_DIGEST_H) endif() -include_directories(${CURL_INCLUDE_DIRS} ${LIBXML2_INCLUDE_DIR}) -target_link_libraries(SpeedTest ${CURL_LIBRARIES} ${LIBXML2_LIBRARIES} -lpthread ${OPENSSL_LIBRARIES}) +include_directories(${CURL_INCLUDE_DIRS}) +target_link_libraries(SpeedTest ${CURL_LIBRARIES} -lpthread ${OPENSSL_LIBRARIES}) install(TARGETS SpeedTest RUNTIME DESTINATION bin) --- a/README.md +++ b/README.md @@ -26,7 +26,6 @@ It supports the new (undocumented) raw T 2. cmake 3. libcurl 4. libssl -5. libxml2 ### On Mac OS X @@ -40,7 +39,7 @@ $ make install ### On Ubuntu/Debian ``` -$ sudo apt-get install build-essential libcurl4-openssl-dev libxml2-dev libssl-dev cmake +$ sudo apt-get install build-essential libcurl4-openssl-dev libssl-dev cmake $ git clone https://github.com/taganaka/SpeedTest $ cd SpeedTest $ cmake -DCMAKE_BUILD_TYPE=Release . @@ -50,7 +49,7 @@ $ sudo make install ### On OpenSuse ``` -$ sudo zypper install cmake gcc-c++ libcurl-devel libxml2-devel libopenssl-devel git +$ sudo zypper install cmake gcc-c++ libcurl-devel libopenssl-devel git $ git clone https://github.com/taganaka/SpeedTest $ cd SpeedTest $ cmake -DCMAKE_BUILD_TYPE=Release . --- a/SpeedTest.cpp +++ b/SpeedTest.cpp @@ -353,67 +353,16 @@ std::vector SpeedTest::spli } -ServerInfo SpeedTest::processServerXMLNode(xmlTextReaderPtr reader) { - - auto name = xmlTextReaderConstName(reader); - auto nodeName = std::string((char*)name); - - if (!name || nodeName != "server"){ - return ServerInfo(); - } - - if (xmlTextReaderAttributeCount(reader) > 0){ - auto info = ServerInfo(); - auto server_url = xmlTextReaderGetAttribute(reader, BAD_CAST "url"); - auto server_lat = xmlTextReaderGetAttribute(reader, BAD_CAST "lat"); - auto server_lon = xmlTextReaderGetAttribute(reader, BAD_CAST "lon"); - auto server_name = xmlTextReaderGetAttribute(reader, BAD_CAST "name"); - auto server_county = xmlTextReaderGetAttribute(reader, BAD_CAST "country"); - auto server_cc = xmlTextReaderGetAttribute(reader, BAD_CAST "cc"); - auto server_host = xmlTextReaderGetAttribute(reader, BAD_CAST "host"); - auto server_id = xmlTextReaderGetAttribute(reader, BAD_CAST "id"); - auto server_sponsor = xmlTextReaderGetAttribute(reader, BAD_CAST "sponsor"); - - if (server_name) - info.name.append((char*)server_name); - - if (server_url) - info.url.append((char*)server_url); - - if (server_county) - info.country.append((char*)server_county); - - if (server_cc) - info.country_code.append((char*)server_cc); - - if (server_host) - info.host.append((char*)server_host); - - if (server_sponsor) - info.sponsor.append((char*)server_sponsor); - - if (server_id) - info.id = std::atoi((char*)server_id); - - if (server_lat) - info.lat = std::stof((char*)server_lat); - - if (server_lon) - info.lon = std::stof((char*)server_lon); - - xmlFree(server_url); - xmlFree(server_lat); - xmlFree(server_lon); - xmlFree(server_name); - xmlFree(server_county); - xmlFree(server_cc); - xmlFree(server_host); - xmlFree(server_id); - xmlFree(server_sponsor); - return info; - } - - return ServerInfo(); +std::string getAttributeValue(const std::string& data, const size_t offset, const size_t max_pos, const std::string& attribute_name) { + size_t pos = data.find(attribute_name + "=\"", offset); + if (pos == std::string::npos) + return ""; + if (pos >= max_pos) + return ""; + size_t value_pos = pos + attribute_name.length() + 2; + size_t end = data.find("\"", value_pos); + std::string s = data.substr(pos + attribute_name.length() + 2, end - value_pos); + return s; } bool SpeedTest::fetchServers(const std::string& url, std::vector& target, int &http_code) { @@ -441,53 +390,42 @@ bool SpeedTest::fetchServers(const std:: http_code = 200; } - size_t len = oss.str().length(); - auto *xmlbuff = (char*)calloc(len + 1, sizeof(char)); - if (!xmlbuff){ - std::cerr << "Unable to calloc" << std::endl; + IPInfo ipInfo; + if (!SpeedTest::ipInfo(ipInfo)){ curl_easy_cleanup(curl); + std::cerr << "OOPS!" <(len), nullptr, nullptr, 0); + std::string data = oss.str(); - if (reader != nullptr) { - IPInfo ipInfo; - if (!SpeedTest::ipInfo(ipInfo)){ - curl_easy_cleanup(curl); - free(xmlbuff); - xmlFreeTextReader(reader); - std::cerr << "OOPS!" <", server_tag_begin); + + auto info = ServerInfo(); + info.name = getAttributeValue(data, server_tag_begin, server_tag_end, "name"); + info.url = getAttributeValue(data, server_tag_begin, server_tag_end, "url"); + info.country = getAttributeValue(data, server_tag_begin, server_tag_end, "country"); + info.country_code = getAttributeValue(data, server_tag_begin, server_tag_end, "cc"); + info.host = getAttributeValue(data, server_tag_begin, server_tag_end, "host"); + info.sponsor = getAttributeValue(data, server_tag_begin, server_tag_end, "sponsor"); + info.id = atoi(getAttributeValue(data, server_tag_begin, server_tag_end, "id").c_str()); + info.lat = std::stof(getAttributeValue(data, server_tag_begin, server_tag_end, "lat")); + info.lon = std::stof(getAttributeValue(data, server_tag_begin, server_tag_end, "lon")); + + if (!info.url.empty()){ + info.distance = harversine(std::make_pair(ipInfo.lat, ipInfo.lon), std::make_pair(info.lat, info.lon)); + target.push_back(info); } - } else { - std::cerr << "Unable to initialize xml parser" << std::endl; - curl_easy_cleanup(curl); - free(xmlbuff); - return false; + + server_tag_begin = data.find(server_tag_start, server_tag_begin + 1); } + curl_easy_cleanup(curl); - free(xmlbuff); - xmlCleanupParser(); std::sort(target.begin(), target.end(), [](const ServerInfo &a, const ServerInfo &b) -> bool { return a.distance < b.distance; }); --- a/SpeedTest.h +++ b/SpeedTest.h @@ -7,7 +7,6 @@ #include "SpeedTestConfig.h" #include "SpeedTestClient.h" -#include #include #include #include @@ -50,7 +49,6 @@ private: const ServerInfo findBestServerWithin(const std::vector& serverList, long& latency, int sample_size = 5, std::function cb = nullptr); static CURL* curl_setup(CURL* curl = nullptr); static size_t writeFunc(void* buf, size_t size, size_t nmemb, void* userp); - static ServerInfo processServerXMLNode(xmlTextReaderPtr reader); double execute(const ServerInfo &server, const TestConfig &config, const opFn &fnc, std::function cb = nullptr); template static T deg2rad(T n);