speedtestpp: drop libxml2 dependency
[feed/packages.git] / net / speedtestpp / patches / 01-remove-libxml-dependency.patch
1 From b7db370449cfe2b453c22b74a660701f78bd7ce3 Mon Sep 17 00:00:00 2001
2 From: Anatolii Lapytskyi <ala@allunite.com>
3 Date: Tue, 6 Sep 2022 15:59:27 +0200
4 Subject: [PATCH] Remove dependency on libxml2
5
6 ---
7 CMakeLists.txt | 5 +-
8 README.md | 5 +-
9 SpeedTest.cpp | 136 ++++++++++++++-----------------------------------
10 SpeedTest.h | 2 -
11 4 files changed, 41 insertions(+), 107 deletions(-)
12
13 --- a/CMakeLists.txt
14 +++ b/CMakeLists.txt
15 @@ -44,7 +44,6 @@ add_executable(SpeedTest ${SOURCE_FILES}
16
17 INCLUDE (CheckIncludeFiles)
18 find_package(CURL REQUIRED)
19 -find_package(LibXml2 REQUIRED)
20
21 if (NOT (APPLE))
22 find_package(OpenSSL REQUIRED)
23 @@ -52,7 +51,7 @@ else()
24 CHECK_INCLUDE_FILES("CommonCrypto/CommonDigest.h" HAVE_COMMON_DIGEST_H)
25 endif()
26
27 -include_directories(${CURL_INCLUDE_DIRS} ${LIBXML2_INCLUDE_DIR})
28 -target_link_libraries(SpeedTest ${CURL_LIBRARIES} ${LIBXML2_LIBRARIES} -lpthread ${OPENSSL_LIBRARIES})
29 +include_directories(${CURL_INCLUDE_DIRS})
30 +target_link_libraries(SpeedTest ${CURL_LIBRARIES} -lpthread ${OPENSSL_LIBRARIES})
31
32 install(TARGETS SpeedTest RUNTIME DESTINATION bin)
33 --- a/README.md
34 +++ b/README.md
35 @@ -26,7 +26,6 @@ It supports the new (undocumented) raw T
36 2. cmake
37 3. libcurl
38 4. libssl
39 -5. libxml2
40
41 ### On Mac OS X
42
43 @@ -40,7 +39,7 @@ $ make install
44 ### On Ubuntu/Debian
45
46 ```
47 -$ sudo apt-get install build-essential libcurl4-openssl-dev libxml2-dev libssl-dev cmake
48 +$ sudo apt-get install build-essential libcurl4-openssl-dev libssl-dev cmake
49 $ git clone https://github.com/taganaka/SpeedTest
50 $ cd SpeedTest
51 $ cmake -DCMAKE_BUILD_TYPE=Release .
52 @@ -50,7 +49,7 @@ $ sudo make install
53 ### On OpenSuse
54
55 ```
56 -$ sudo zypper install cmake gcc-c++ libcurl-devel libxml2-devel libopenssl-devel git
57 +$ sudo zypper install cmake gcc-c++ libcurl-devel libopenssl-devel git
58 $ git clone https://github.com/taganaka/SpeedTest
59 $ cd SpeedTest
60 $ cmake -DCMAKE_BUILD_TYPE=Release .
61 --- a/SpeedTest.cpp
62 +++ b/SpeedTest.cpp
63 @@ -353,67 +353,16 @@ std::vector<std::string> SpeedTest::spli
64
65 }
66
67 -ServerInfo SpeedTest::processServerXMLNode(xmlTextReaderPtr reader) {
68 -
69 - auto name = xmlTextReaderConstName(reader);
70 - auto nodeName = std::string((char*)name);
71 -
72 - if (!name || nodeName != "server"){
73 - return ServerInfo();
74 - }
75 -
76 - if (xmlTextReaderAttributeCount(reader) > 0){
77 - auto info = ServerInfo();
78 - auto server_url = xmlTextReaderGetAttribute(reader, BAD_CAST "url");
79 - auto server_lat = xmlTextReaderGetAttribute(reader, BAD_CAST "lat");
80 - auto server_lon = xmlTextReaderGetAttribute(reader, BAD_CAST "lon");
81 - auto server_name = xmlTextReaderGetAttribute(reader, BAD_CAST "name");
82 - auto server_county = xmlTextReaderGetAttribute(reader, BAD_CAST "country");
83 - auto server_cc = xmlTextReaderGetAttribute(reader, BAD_CAST "cc");
84 - auto server_host = xmlTextReaderGetAttribute(reader, BAD_CAST "host");
85 - auto server_id = xmlTextReaderGetAttribute(reader, BAD_CAST "id");
86 - auto server_sponsor = xmlTextReaderGetAttribute(reader, BAD_CAST "sponsor");
87 -
88 - if (server_name)
89 - info.name.append((char*)server_name);
90 -
91 - if (server_url)
92 - info.url.append((char*)server_url);
93 -
94 - if (server_county)
95 - info.country.append((char*)server_county);
96 -
97 - if (server_cc)
98 - info.country_code.append((char*)server_cc);
99 -
100 - if (server_host)
101 - info.host.append((char*)server_host);
102 -
103 - if (server_sponsor)
104 - info.sponsor.append((char*)server_sponsor);
105 -
106 - if (server_id)
107 - info.id = std::atoi((char*)server_id);
108 -
109 - if (server_lat)
110 - info.lat = std::stof((char*)server_lat);
111 -
112 - if (server_lon)
113 - info.lon = std::stof((char*)server_lon);
114 -
115 - xmlFree(server_url);
116 - xmlFree(server_lat);
117 - xmlFree(server_lon);
118 - xmlFree(server_name);
119 - xmlFree(server_county);
120 - xmlFree(server_cc);
121 - xmlFree(server_host);
122 - xmlFree(server_id);
123 - xmlFree(server_sponsor);
124 - return info;
125 - }
126 -
127 - return ServerInfo();
128 +std::string getAttributeValue(const std::string& data, const size_t offset, const size_t max_pos, const std::string& attribute_name) {
129 + size_t pos = data.find(attribute_name + "=\"", offset);
130 + if (pos == std::string::npos)
131 + return "";
132 + if (pos >= max_pos)
133 + return "";
134 + size_t value_pos = pos + attribute_name.length() + 2;
135 + size_t end = data.find("\"", value_pos);
136 + std::string s = data.substr(pos + attribute_name.length() + 2, end - value_pos);
137 + return s;
138 }
139
140 bool SpeedTest::fetchServers(const std::string& url, std::vector<ServerInfo>& target, int &http_code) {
141 @@ -441,53 +390,42 @@ bool SpeedTest::fetchServers(const std::
142 http_code = 200;
143 }
144
145 - size_t len = oss.str().length();
146 - auto *xmlbuff = (char*)calloc(len + 1, sizeof(char));
147 - if (!xmlbuff){
148 - std::cerr << "Unable to calloc" << std::endl;
149 + IPInfo ipInfo;
150 + if (!SpeedTest::ipInfo(ipInfo)){
151 curl_easy_cleanup(curl);
152 + std::cerr << "OOPS!" <<std::endl;
153 return false;
154 }
155 - memcpy(xmlbuff, oss.str().c_str(), len);
156 - oss.str("");
157
158 - xmlTextReaderPtr reader = xmlReaderForMemory(xmlbuff, static_cast<int>(len), nullptr, nullptr, 0);
159 + std::string data = oss.str();
160
161 - if (reader != nullptr) {
162 - IPInfo ipInfo;
163 - if (!SpeedTest::ipInfo(ipInfo)){
164 - curl_easy_cleanup(curl);
165 - free(xmlbuff);
166 - xmlFreeTextReader(reader);
167 - std::cerr << "OOPS!" <<std::endl;
168 - return false;
169 - }
170 - auto ret = xmlTextReaderRead(reader);
171 - while (ret == 1) {
172 - ServerInfo info = processServerXMLNode(reader);
173 - if (!info.url.empty()){
174 - info.distance = harversine(std::make_pair(ipInfo.lat, ipInfo.lon), std::make_pair(info.lat, info.lon));
175 - target.push_back(info);
176 - }
177 - ret = xmlTextReaderRead(reader);
178 - }
179 - xmlFreeTextReader(reader);
180 - if (ret != 0) {
181 - curl_easy_cleanup(curl);
182 - free(xmlbuff);
183 - std::cerr << "Failed to parse" << std::endl;
184 - return false;
185 + const std::string server_tag_start = "<server ";
186 +
187 + size_t server_tag_begin = data.find(server_tag_start);
188 + while (server_tag_begin != std::string::npos) {
189 + size_t server_tag_end = data.find("/>", server_tag_begin);
190 +
191 + auto info = ServerInfo();
192 + info.name = getAttributeValue(data, server_tag_begin, server_tag_end, "name");
193 + info.url = getAttributeValue(data, server_tag_begin, server_tag_end, "url");
194 + info.country = getAttributeValue(data, server_tag_begin, server_tag_end, "country");
195 + info.country_code = getAttributeValue(data, server_tag_begin, server_tag_end, "cc");
196 + info.host = getAttributeValue(data, server_tag_begin, server_tag_end, "host");
197 + info.sponsor = getAttributeValue(data, server_tag_begin, server_tag_end, "sponsor");
198 + info.id = atoi(getAttributeValue(data, server_tag_begin, server_tag_end, "id").c_str());
199 + info.lat = std::stof(getAttributeValue(data, server_tag_begin, server_tag_end, "lat"));
200 + info.lon = std::stof(getAttributeValue(data, server_tag_begin, server_tag_end, "lon"));
201 +
202 + if (!info.url.empty()){
203 + info.distance = harversine(std::make_pair(ipInfo.lat, ipInfo.lon), std::make_pair(info.lat, info.lon));
204 + target.push_back(info);
205 }
206 - } else {
207 - std::cerr << "Unable to initialize xml parser" << std::endl;
208 - curl_easy_cleanup(curl);
209 - free(xmlbuff);
210 - return false;
211 +
212 + server_tag_begin = data.find(server_tag_start, server_tag_begin + 1);
213 }
214
215 +
216 curl_easy_cleanup(curl);
217 - free(xmlbuff);
218 - xmlCleanupParser();
219 std::sort(target.begin(), target.end(), [](const ServerInfo &a, const ServerInfo &b) -> bool {
220 return a.distance < b.distance;
221 });
222 --- a/SpeedTest.h
223 +++ b/SpeedTest.h
224 @@ -7,7 +7,6 @@
225
226 #include "SpeedTestConfig.h"
227 #include "SpeedTestClient.h"
228 -#include <libxml/xmlreader.h>
229 #include <functional>
230 #include <cmath>
231 #include <curl/curl.h>
232 @@ -50,7 +49,6 @@ private:
233 const ServerInfo findBestServerWithin(const std::vector<ServerInfo>& serverList, long& latency, int sample_size = 5, std::function<void(bool)> cb = nullptr);
234 static CURL* curl_setup(CURL* curl = nullptr);
235 static size_t writeFunc(void* buf, size_t size, size_t nmemb, void* userp);
236 - static ServerInfo processServerXMLNode(xmlTextReaderPtr reader);
237 double execute(const ServerInfo &server, const TestConfig &config, const opFn &fnc, std::function<void(bool)> cb = nullptr);
238 template <typename T>
239 static T deg2rad(T n);