9
9
#include < iterator> // distance()
10
10
#include < stdexcept> // logic_error, runtime_error
11
11
12
+ #include < nn/ac.h>
13
+
12
14
#include " utils.hpp"
13
15
14
16
#include " http_client.hpp"
15
17
16
18
17
19
using namespace std ::literals;
18
20
21
+ using std::logic_error;
22
+ using std::runtime_error;
23
+
19
24
20
25
namespace utils {
21
26
@@ -123,17 +128,14 @@ namespace utils {
123
128
case 2 :
124
129
return " https://ipapi.co" ;
125
130
default :
126
- throw std:: logic_error{" invalid tz service" };
131
+ throw logic_error{" Invalid tz service. " };
127
132
}
128
133
}
129
134
130
135
131
136
std::pair<std::string, std::chrono::minutes>
132
137
fetch_timezone (int idx)
133
138
{
134
- if (idx < 0 || idx >= num_tz_services)
135
- throw std::logic_error{" invalid service" };
136
-
137
139
const char * service = get_tz_service_name (idx);
138
140
139
141
static const char * urls[num_tz_services] = {
@@ -142,6 +144,8 @@ namespace utils {
142
144
" https://ipapi.co/csv"
143
145
};
144
146
147
+ network_guard net_guard;
148
+
145
149
std::string response = http::get (urls[idx]);
146
150
147
151
switch (idx) {
@@ -150,7 +154,7 @@ namespace utils {
150
154
{
151
155
auto tokens = csv_split (response);
152
156
if (size (tokens) != 2 )
153
- throw std:: runtime_error{" Could not parse response from " s + service};
157
+ throw runtime_error{" Could not parse response from " s + service};
154
158
std::string name = tokens[0 ];
155
159
auto offset = std::chrono::seconds{std::stoi (tokens[1 ])};
156
160
return {name, duration_cast<std::chrono::minutes>(offset)};
@@ -163,26 +167,26 @@ namespace utils {
163
167
// returned as +HHMM, not seconds.
164
168
auto lines = split (response, " \r\n " );
165
169
if (size (lines) != 2 )
166
- throw std:: runtime_error{" Could not parse response from " s + service};
170
+ throw runtime_error{" Could not parse response from " s + service};
167
171
168
172
auto keys = csv_split (lines[0 ]);
169
173
auto values = csv_split (lines[1 ]);
170
174
if (size (keys) != size (values))
171
- throw std:: runtime_error{" Incoherent response from " s + service};
175
+ throw runtime_error{" Incoherent response from " s + service};
172
176
173
177
auto tz_it = std::ranges::find (keys, " timezone" );
174
178
auto offset_it = std::ranges::find (keys, " utc_offset" );
175
179
if (tz_it == keys.end () || offset_it == keys.end ())
176
- throw std:: runtime_error{" Could not find timezone or utc_offset fields"
177
- " in response." };
180
+ throw runtime_error{" Could not find timezone or utc_offset fields"
181
+ " in response." };
178
182
179
183
auto tz_idx = std::distance (keys.begin (), tz_it);;
180
184
auto offset_idx = std::distance (keys.begin (), offset_it);
181
185
182
186
std::string name = values[tz_idx];
183
187
std::string hhmm = values[offset_idx];
184
188
if (empty (hhmm))
185
- throw std:: runtime_error{" Invalid UTC offset string." };
189
+ throw runtime_error{" Invalid UTC offset string." };
186
190
187
191
char sign = hhmm[0 ];
188
192
std::string hh = hhmm.substr (1 , 2 );
@@ -196,9 +200,35 @@ namespace utils {
196
200
}
197
201
198
202
default :
199
- throw std:: logic_error{" invalid tz service" };
203
+ throw logic_error{" Invalid tz service. " };
200
204
}
201
205
202
206
}
203
207
208
+
209
+ network_guard::init_guard::init_guard ()
210
+ {
211
+ if (!nn::ac::Initialize ())
212
+ throw runtime_error{" Network error (nn::ac::Initialize() failed)" };
213
+ }
214
+
215
+
216
+ network_guard::init_guard::~init_guard ()
217
+ {
218
+ nn::ac::Finalize ();
219
+ }
220
+
221
+
222
+ network_guard::connect_guard::connect_guard ()
223
+ {
224
+ if (!nn::ac::Connect ())
225
+ throw runtime_error{" Network error (nn::ac::Connect() failed)" };
226
+ }
227
+
228
+
229
+ network_guard::connect_guard::~connect_guard ()
230
+ {
231
+ nn::ac::Close ();
232
+ }
233
+
204
234
} // namespace utils
0 commit comments