stdex
Additional custom or not Standard C++ covered algorithms
Loading...
Searching...
No Matches
parser.cpp
1/*
2 SPDX-License-Identifier: MIT
3 Copyright © 2023-2024 Amebis
4*/
5
6#include "pch.hpp"
7
8using namespace std;
9using namespace stdex;
10using namespace stdex::parser;
11#ifdef _WIN32
12using namespace Microsoft::VisualStudio::CppUnitTestFramework;
13
14namespace Microsoft {
15 namespace VisualStudio {
16 namespace CppUnitTestFramework {
17 static std::wstring ToString(const stdex::interval<size_t>& q)
18 {
19 return stdex::sprintf(L"<%zu, %zu>", nullptr, q.start, q.end);
20 }
21 }
22 }
23}
24#endif
25
26namespace UnitTests
27{
28 TEST_CLASS(parser)
29 {
30 public:
32 {
33 static const wchar_t text[] = L"This is a test.\nSecond line.";
34
35 {
36 wnoop p;
37 Assert::IsTrue(p.match(text));
38 Assert::AreEqual((size_t)0, p.interval.start);
39 Assert::AreEqual((size_t)0, p.interval.end);
40 }
41
42 {
43 wcu p(L't');
44 Assert::IsFalse(p.match(text));
45 Assert::IsTrue(p.match(text, 0, _countof(text), match_case_insensitive));
46 Assert::AreEqual((size_t)0, p.interval.start);
47 Assert::AreEqual((size_t)1, p.interval.end);
48 }
49
50 {
51 wspace_cu p;
52 Assert::IsFalse(p.match(text));
53 Assert::IsTrue(p.match(text, 4));
54 Assert::AreEqual((size_t)4, p.interval.start);
55 Assert::AreEqual((size_t)5, p.interval.end);
56 }
57
58 {
59 wpunct_cu p;
60 Assert::IsFalse(p.match(text));
61 Assert::IsTrue(p.match(text, 14));
62 Assert::AreEqual((size_t)14, p.interval.start);
63 Assert::AreEqual((size_t)15, p.interval.end);
64 }
65
66 {
68 Assert::IsFalse(p.match(text));
69 Assert::IsTrue(p.match(text, 4));
70 Assert::AreEqual((size_t)4, p.interval.start);
71 Assert::AreEqual((size_t)5, p.interval.end);
72 Assert::IsTrue(p.match(text, 14));
73 Assert::AreEqual((size_t)14, p.interval.start);
74 Assert::AreEqual((size_t)15, p.interval.end);
75 }
76
77 {
78 wbol p;
79 Assert::IsTrue(p.match(text));
80 Assert::AreEqual((size_t)0, p.interval.start);
81 Assert::AreEqual((size_t)0, p.interval.end);
82 Assert::IsFalse(p.match(text, 1));
83 Assert::IsFalse(p.match(text, 15));
84 Assert::IsTrue(p.match(text, 16));
85 Assert::AreEqual((size_t)16, p.interval.start);
86 Assert::AreEqual((size_t)16, p.interval.end);
87 }
88
89 {
90 weol p;
91 Assert::IsFalse(p.match(text));
92 Assert::IsFalse(p.match(text, 1));
93 Assert::IsTrue(p.match(text, 15));
94 Assert::AreEqual((size_t)15, p.interval.start);
95 Assert::AreEqual((size_t)15, p.interval.end);
96 Assert::IsFalse(p.match(text, 16));
97 }
98
99 {
100 wcu_set p(L"abcD");
101 Assert::IsFalse(p.match(text));
102 Assert::IsTrue(p.match(text, 8));
103 Assert::AreEqual((size_t)8, p.interval.start);
104 Assert::AreEqual((size_t)9, p.interval.end);
105 Assert::AreEqual((size_t)0, p.hit_offset);
106 Assert::IsFalse(p.match(text, 21));
107 Assert::IsTrue(p.match(text, 21, _countof(text), match_case_insensitive));
108 Assert::AreEqual((size_t)21, p.interval.start);
109 Assert::AreEqual((size_t)22, p.interval.end);
110 Assert::AreEqual((size_t)3, p.hit_offset);
111 }
112
113 {
114 stdex::parser::wstring p(L"this");
115 Assert::IsFalse(p.match(text));
116 Assert::IsTrue(p.match(text, 0, sizeof(text), match_case_insensitive));
117 Assert::AreEqual((size_t)0, p.interval.start);
118 Assert::AreEqual((size_t)4, p.interval.end);
119 }
120
121 {
122 wany_cu chr;
123 witerations p(make_shared_no_delete(&chr), 1, 5);
124 Assert::IsTrue(p.match(text));
125 Assert::AreEqual((size_t)0, p.interval.start);
126 Assert::AreEqual((size_t)5, p.interval.end);
127 }
128
129 {
130 wspace_cu nospace(true);
131 witerations p(make_shared_no_delete(&nospace), 1);
132 Assert::IsTrue(p.match(text));
133 Assert::AreEqual((size_t)0, p.interval.start);
134 Assert::AreEqual((size_t)4, p.interval.end);
135 }
136
137 {
138 wcu chr_t(L't'), chr_h(L'h'), chr_i(L'i'), chr_s(L's');
139 wspace_cu space;
140 wsequence p({
141 make_shared_no_delete(&chr_t),
142 make_shared_no_delete(&chr_h),
143 make_shared_no_delete(&chr_i),
144 make_shared_no_delete(&chr_s),
145 make_shared_no_delete(&space) });
146 Assert::IsFalse(p.match(text));
147 Assert::IsTrue(p.match(text, 0, _countof(text), match_case_insensitive));
148 Assert::AreEqual((size_t)0, p.interval.start);
149 Assert::AreEqual((size_t)5, p.interval.end);
150 }
151
152 {
153 stdex::parser::wstring apple(L"apple"), orange(L"orange"), _this(L"this");
154 wspace_cu space;
155 wbranch p({
156 make_shared_no_delete(&apple),
157 make_shared_no_delete(&orange),
158 make_shared_no_delete(&_this),
159 make_shared_no_delete(&space) });
160 Assert::IsFalse(p.match(text));
161 Assert::IsTrue(p.match(text, 0, _countof(text), match_case_insensitive));
162 Assert::AreEqual((size_t)2, p.hit_offset);
163 Assert::AreEqual((size_t)0, p.interval.start);
164 Assert::AreEqual((size_t)4, p.interval.end);
165 }
166
167 {
168 wstring_branch p(L"apple", L"orange", L"this", nullptr);
169 Assert::IsFalse(p.match(text));
170 Assert::IsTrue(p.match(text, 0, _countof(text), match_case_insensitive));
171 Assert::AreEqual((size_t)2, p.hit_offset);
172 Assert::AreEqual((size_t)0, p.interval.start);
173 Assert::AreEqual((size_t)4, p.interval.end);
174 }
175
176 {
177 wcu chr_s(L's'), chr_h(L'h'), chr_i(L'i'), chr_t(L't');
178 wpermutation p({
179 make_shared_no_delete(&chr_s),
180 make_shared_no_delete(&chr_h),
181 make_shared_no_delete(&chr_i),
182 make_shared_no_delete(&chr_t) });
183 Assert::IsFalse(p.match(text));
184 Assert::IsTrue(p.match(text, 0, _countof(text), match_case_insensitive));
185 Assert::AreEqual((size_t)0, p.interval.start);
186 Assert::AreEqual((size_t)4, p.interval.end);
187 }
188
189 {
190 std::locale locale_slSI("sl_SI");
191 wspace_cu space(false, locale_slSI);
192 wiban p(make_shared_no_delete(&space), locale_slSI);
193 Assert::IsTrue(p.match(L"SI56023120015226972", 0, SIZE_MAX));
194 Assert::IsTrue(p.is_valid);
195 Assert::AreEqual(L"SI", p.country);
196 Assert::AreEqual(L"56", p.check_digits);
197 Assert::AreEqual(L"023120015226972", p.bban);
198 Assert::IsTrue(p.match(L"SI56 0231 2001 5226 972", 0, SIZE_MAX));
199 Assert::IsTrue(p.is_valid);
200 Assert::AreEqual(L"SI", p.country);
201 Assert::AreEqual(L"56", p.check_digits);
202 Assert::AreEqual(L"023120015226972", p.bban);
203 Assert::IsFalse(p.match(L"si56 0231 2001 5226 972", 0, SIZE_MAX));
204 Assert::IsFalse(p.is_valid);
205 Assert::IsTrue(p.match(L"si56 0231 2001 5226 972", 0, SIZE_MAX, match_case_insensitive));
206 Assert::IsTrue(p.is_valid);
207 Assert::IsTrue(p.match(L"SI56 0231 2001 5226 9720", 0, SIZE_MAX));
208 Assert::AreEqual(stdex::interval<size_t>(0, 23), p.interval);
209 Assert::IsTrue(p.is_valid);
210 Assert::IsTrue(p.match(L"...SI56 0231 2001 5226 972...", 3, SIZE_MAX));
211 Assert::IsTrue(p.is_valid);
212 Assert::IsTrue(p.match(L"SI56 0231 2001 5226 972", 0, SIZE_MAX)); // no-break space
213 Assert::IsTrue(p.is_valid);
214
215 Assert::IsTrue(p.match(L"BE71 0961 2345 6769", 0, SIZE_MAX));
216 Assert::IsTrue(p.is_valid);
217 Assert::IsTrue(p.match(L"BR15 0000 0000 0000 1093 2840 814 P2", 0, SIZE_MAX));
218 Assert::IsTrue(p.is_valid);
219 Assert::IsTrue(p.match(L"CR99 0000 0000 0000 8888 88", 0, SIZE_MAX));
220 Assert::IsFalse(p.is_valid);
221 Assert::IsTrue(p.match(L"FR76 3000 6000 0112 3456 7890 189", 0, SIZE_MAX));
222 Assert::IsTrue(p.is_valid);
223 Assert::IsTrue(p.match(L"IE12 BOFI 9000 0112 3456 78", 0, SIZE_MAX));
224 Assert::IsFalse(p.is_valid);
225 Assert::IsTrue(p.match(L"DE91 1000 0000 0123 4567 89", 0, SIZE_MAX));
226 Assert::IsTrue(p.is_valid);
227 Assert::IsTrue(p.match(L"GR96 0810 0010 0000 0123 4567 890", 0, SIZE_MAX));
228 Assert::IsTrue(p.is_valid);
229 Assert::IsTrue(p.match(L"MU43 BOMM 0101 1234 5678 9101 000 MUR", 0, SIZE_MAX));
230 Assert::IsTrue(p.is_valid);
231 Assert::IsTrue(p.match(L"PK70 BANK 0000 1234 5678 9000", 0, SIZE_MAX));
232 Assert::IsTrue(p.is_valid);
233 Assert::IsTrue(p.match(L"PL10 1050 0099 7603 1234 5678 9123", 0, SIZE_MAX));
234 Assert::IsTrue(p.is_valid);
235 Assert::IsTrue(p.match(L"RO09 BCYP 0000 0012 3456 7890", 0, SIZE_MAX));
236 Assert::IsTrue(p.is_valid);
237 Assert::IsTrue(p.match(L"LC14 BOSL 1234 5678 9012 3456 7890 1234", 0, SIZE_MAX));
238 Assert::IsTrue(p.is_valid);
239 Assert::IsTrue(p.match(L"SA44 2000 0001 2345 6789 1234", 0, SIZE_MAX));
240 Assert::IsTrue(p.is_valid);
241 Assert::IsTrue(p.match(L"ES79 2100 0813 6101 2345 6789", 0, SIZE_MAX));
242 Assert::IsTrue(p.is_valid);
243 Assert::IsTrue(p.match(L"SE87 3000 0000 0101 2345 6789", 0, SIZE_MAX));
244 Assert::IsFalse(p.is_valid);
245 Assert::IsTrue(p.match(L"CH56 0483 5012 3456 7800 9", 0, SIZE_MAX));
246 Assert::IsTrue(p.is_valid);
247 Assert::IsTrue(p.match(L"GB98 MIDL 0700 9312 3456 78", 0, SIZE_MAX));
248 Assert::IsTrue(p.is_valid);
249 }
250
251 {
252 std::locale locale_slSI("sl_SI");
253 wspace_cu space(false, locale_slSI);
254 wcreditor_reference p(make_shared_no_delete(&space), locale_slSI);
255 Assert::IsTrue(p.match(L"RF18539007547034", 0, SIZE_MAX));
256 Assert::IsTrue(p.is_valid);
257 Assert::AreEqual(L"18", p.check_digits);
258 Assert::AreEqual(L"000000000539007547034", p.reference);
259 Assert::IsTrue(p.match(L"RF18 5390 0754 7034", 0, SIZE_MAX));
260 Assert::IsTrue(p.is_valid);
261 Assert::AreEqual(L"18", p.check_digits);
262 Assert::AreEqual(L"000000000539007547034", p.reference);
263 Assert::IsFalse(p.match(L"rf18 5390 0754 7034", 0, SIZE_MAX));
264 Assert::IsFalse(p.is_valid);
265 Assert::IsTrue(p.match(L"rf18 5390 0754 7034", 0, SIZE_MAX, match_case_insensitive));
266 Assert::IsTrue(p.is_valid);
267 Assert::IsTrue(p.match(L"RF18 5390 0754 70340", 0, SIZE_MAX));
268 Assert::IsFalse(p.is_valid);
269 Assert::IsTrue(p.match(L"...RF18 5390 0754 7034...", 3, SIZE_MAX));
270 Assert::IsTrue(p.is_valid);
271 Assert::IsTrue(p.match(L"RF18 5390 0754 7034", 0, SIZE_MAX)); // no-break space
272 Assert::IsTrue(p.is_valid);
273 }
274
275 {
276 std::locale locale_slSI("sl_SI");
277 wspace_cu space(false, locale_slSI);
278 wsi_reference p(make_shared_no_delete(&space), locale_slSI);
279 Assert::IsTrue(p.match(L"SI121234567890120", 0, SIZE_MAX));
280 Assert::IsTrue(p.is_valid);
281 Assert::AreEqual(L"12", p.model);
282 Assert::AreEqual(stdex::interval<size_t>(4, 17), p.part1.interval);
283 Assert::IsTrue(p.match(L"SI12 1234567890120", 0, SIZE_MAX));
284 Assert::IsTrue(p.is_valid);
285 Assert::AreEqual(L"12", p.model);
286 Assert::AreEqual(stdex::interval<size_t>(5, 18), p.part1.interval);
287 Assert::IsFalse(p.match(L"si12 1234567890120", 0, SIZE_MAX));
288 Assert::IsTrue(p.match(L"si12 1234567890120", 0, SIZE_MAX, match_case_insensitive));
289 Assert::IsTrue(p.match(L"...SI12 1234567890120...", 3, SIZE_MAX));
290 Assert::IsTrue(p.match(L"SI12 1234567890120", 0, SIZE_MAX)); // no-break space
291 }
292 }
293
295 {
296 std::locale locale_slSI("sl_SI");
297 static const char text[] = "V ko&zcaron;u&scaron;&ccaron;ku zlobnega mizarja stopiclja fant\nin kli&ccaron;e&nbsp;1234567890.";
298
299 {
300 sgml_noop p;
301 Assert::IsTrue(p.match(text));
302 Assert::AreEqual((size_t)0, p.interval.start);
303 Assert::AreEqual((size_t)0, p.interval.end);
304 }
305
306 {
307 sgml_cp p("v");
308 Assert::IsFalse(p.match(text));
309 Assert::IsTrue(p.match(text, 0, _countof(text), match_case_insensitive));
310 Assert::AreEqual((size_t)0, p.interval.start);
311 Assert::AreEqual((size_t)1, p.interval.end);
312 }
313
314 {
315 sgml_cp p("&Zcaron;", SIZE_MAX, false, locale_slSI);
316 Assert::IsFalse(p.match(text, 4));
317 Assert::IsTrue(p.match(text, 4, _countof(text), match_case_insensitive));
318 Assert::AreEqual((size_t)4, p.interval.start);
319 Assert::AreEqual((size_t)12, p.interval.end);
320 }
321
322 {
323 sgml_space_cp p(false, locale_slSI);
324 Assert::IsFalse(p.match(text));
325 Assert::IsTrue(p.match(text, 1));
326 Assert::AreEqual((size_t)1, p.interval.start);
327 Assert::AreEqual((size_t)2, p.interval.end);
328 Assert::IsTrue(p.match(text, 79));
329 Assert::AreEqual((size_t)79, p.interval.start);
330 Assert::AreEqual((size_t)85, p.interval.end);
331 }
332
333 {
334 sgml_string_branch p(locale_slSI, "apple", "orange", "Ko&Zcaron;u&Scaron;&ccaron;Ku", nullptr);
335 Assert::IsFalse(p.match(text, 2));
336 Assert::IsTrue(p.match(text, 2, _countof(text), match_case_insensitive));
337 Assert::AreEqual((size_t)2, p.hit_offset);
338 Assert::AreEqual((size_t)2, p.interval.start);
339 Assert::AreEqual((size_t)31, p.interval.end);
340 }
341
342 {
343 sgml_space_cp space(false, locale_slSI);
344 sgml_iban p(make_shared_no_delete(&space), locale_slSI);
345 Assert::IsTrue(p.match("SI56023120015226972", 0, SIZE_MAX));
346 Assert::IsTrue(p.is_valid);
347 Assert::AreEqual("SI", p.country);
348 Assert::AreEqual("56", p.check_digits);
349 Assert::AreEqual("023120015226972", p.bban);
350 Assert::IsTrue(p.match("SI56 0231 2001 5226 972", 0, SIZE_MAX));
351 Assert::IsTrue(p.is_valid);
352 Assert::AreEqual("SI", p.country);
353 Assert::AreEqual("56", p.check_digits);
354 Assert::AreEqual("023120015226972", p.bban);
355 Assert::IsFalse(p.match("si56 0231 2001 5226 972", 0, SIZE_MAX));
356 Assert::IsFalse(p.is_valid);
357 Assert::IsTrue(p.match("si56 0231 2001 5226 972", 0, SIZE_MAX, match_case_insensitive));
358 Assert::IsTrue(p.is_valid);
359 Assert::IsTrue(p.match("SI56 0231 2001 5226 9720", 0, SIZE_MAX));
360 Assert::AreEqual(stdex::interval<size_t>(0, 23), p.interval);
361 Assert::IsTrue(p.is_valid);
362 Assert::IsTrue(p.match("...SI56 0231 2001 5226 972...", 3, SIZE_MAX));
363 Assert::IsTrue(p.is_valid);
364 Assert::IsTrue(p.match("SI56&nbsp;0231&nbsp;2001&nbsp;5226&nbsp;972", 0, SIZE_MAX));
365 Assert::IsTrue(p.is_valid);
366 }
367
368 {
369 sgml_space_cp space(false, locale_slSI);
370 sgml_creditor_reference p(make_shared_no_delete(&space), locale_slSI);
371 Assert::IsTrue(p.match("RF18539007547034", 0, SIZE_MAX));
372 Assert::IsTrue(p.is_valid);
373 Assert::AreEqual("18", p.check_digits);
374 Assert::AreEqual("000000000539007547034", p.reference);
375 Assert::IsTrue(p.match("RF18 5390 0754 7034", 0, SIZE_MAX));
376 Assert::IsTrue(p.is_valid);
377 Assert::AreEqual("18", p.check_digits);
378 Assert::AreEqual("000000000539007547034", p.reference);
379 Assert::IsFalse(p.match("rf18 5390 0754 7034", 0, SIZE_MAX));
380 Assert::IsFalse(p.is_valid);
381 Assert::IsTrue(p.match("rf18 5390 0754 7034", 0, SIZE_MAX, match_case_insensitive));
382 Assert::IsTrue(p.is_valid);
383 Assert::IsTrue(p.match("RF18 5390 0754 70340", 0, SIZE_MAX));
384 Assert::IsFalse(p.is_valid);
385 Assert::IsTrue(p.match("...RF18 5390 0754 7034...", 3, SIZE_MAX));
386 Assert::IsTrue(p.is_valid);
387 Assert::IsTrue(p.match("RF18&nbsp;5390&nbsp;0754&nbsp;7034", 0, SIZE_MAX));
388 Assert::IsTrue(p.is_valid);
389 }
390
391 {
392 sgml_space_cp space(false, locale_slSI);
393 sgml_si_reference p(make_shared_no_delete(&space), locale_slSI);
394 Assert::IsTrue(p.match("SI121234567890120", 0, SIZE_MAX));
395 Assert::IsTrue(p.is_valid);
396 Assert::AreEqual("12", p.model);
397 Assert::AreEqual(stdex::interval<size_t>(4, 17), p.part1.interval);
398 Assert::IsTrue(p.match("SI12 1234567890120", 0, SIZE_MAX));
399 Assert::IsTrue(p.is_valid);
400 Assert::AreEqual("12", p.model);
401 Assert::AreEqual(stdex::interval<size_t>(5, 18), p.part1.interval);
402 Assert::IsFalse(p.match("si12 1234567890120", 0, SIZE_MAX));
403 Assert::IsTrue(p.match("si12 1234567890120", 0, SIZE_MAX, match_case_insensitive));
404 Assert::IsTrue(p.match("...SI12 1234567890120...", 3, SIZE_MAX));
405 Assert::IsTrue(p.match("SI12&nbsp;1234567890120", 0, SIZE_MAX));
406 }
407 }
408
410 {
411 static const std::locale locale("en_US.UTF-8");
412 static const char request[] =
413 "GET / HTTP/2\r\n"
414 "Host: stackoverflow.com\r\n"
415 "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/110.0\r\n"
416 "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8\r\n"
417 "Accept-Language: sl,en-US;q=0.8,en;q=0.6,de-DE;q=0.4,de;q=0.2\r\n"
418 "Accept-Encoding: gzip, deflate, br\r\n"
419 "DNT: 1\r\n"
420 "Connection: keep-alive\r\n"
421 "Cookie: prov=00000000-0000-0000-0000-000000000000; acct=t=00000000000000000%2f%2f0000%2b0000%2b000&s=00000000000000000000000000000000; OptanonConsent=isGpcEnabled=0&datestamp=Fri+Feb+03+2023+11%3A11%3A08+GMT%2B0100+(Srednjeevropski+standardni+%C4%8Das)&version=6.37.0&isIABGlobal=false&hosts=&consentId=00000000-0000-0000-0000-000000000000&interactionCount=1&landingPath=NotLandingPage&groups=00000%3A0%2C00000%3A0%2C00000%3A0%2C00000%3A0; OptanonAlertBoxClosed=2023-02-03T10:11:08.683Z\r\n"
422 "Upgrade-Insecure-Requests: 1\r\n"
423 "Sec-Fetch-Dest: document\r\n"
424 "Sec-Fetch-Mode: navigate\r\n"
425 "Sec-Fetch-Site: none\r\n"
426 "Sec-Fetch-User: ?1\r\n"
427 "Pragma: no-cache\r\n"
428 "Cache-Control: no-cache\r\n"
429 "\r\n";
430
431 {
433 Assert::IsTrue(p.match(request));
434 Assert::AreEqual((size_t)0, p.interval.start);
435 Assert::AreEqual((size_t)14, p.interval.end);
436 Assert::AreEqual((size_t)0, p.verb.start);
437 Assert::AreEqual((size_t)3, p.verb.end);
438 Assert::AreEqual((size_t)4, p.url.interval.start);
439 Assert::AreEqual((size_t)5, p.url.interval.end);
440 Assert::AreEqual((size_t)6, p.protocol.interval.start);
441 Assert::AreEqual((size_t)12, p.protocol.interval.end);
442 Assert::AreEqual((uint16_t)0x200, p.protocol.version);
443 }
444
445 {
446 std::list<http_header> hdrs;
447 size_t offset = 14;
448 for (;;) {
450 if (h.match(request, offset)) {
452 hdrs.push_back(std::move(h));
453 }
454 else
455 break;
456 }
457 Assert::AreEqual((size_t)15, hdrs.size());
459 for (const auto& h : hdrs)
460 if (strnicmp(request + h.name.start, h.name.size(), "Accept-Language", SIZE_MAX, locale) == 0)
461 langs.insert(request, h.value.start, h.value.end);
462 Assert::IsTrue(!langs.empty());
463 {
465 "sl", "en-US", "en", "de-DE", "de"
466 };
467 auto c = control.cbegin();
468 auto l = langs.cbegin();
469 for (; c != control.cend() && l != langs.cend(); ++c, ++l)
470 Assert::IsTrue(strnicmp(request + l->value.interval.start, l->value.interval.size(), c->c_str(), c->size(), locale) == 0);
471 Assert::IsTrue(c == control.cend());
472 Assert::IsTrue(l == langs.cend());
473 }
474 }
475
476 //static const char response[] =
477 // "HTTP/2 200 OK\r\n"
478 // "cache-control: private\r\n"
479 // "content-type: text/html; charset=utf-8\r\n"
480 // "content-encoding: gzip\r\n"
481 // "strict-transport-security: max-age=15552000\r\n"
482 // "x-frame-options: SAMEORIGIN\r\n"
483 // "set-cookie: acct=t=00000000000000000%2f%2f0000%2b0000%2b000&s=00000000000000000000000000000000; expires=Sat, 16 Sep 2023 10:23:00 GMT; domain=.stackoverflow.com; path=/; secure; samesite=none; httponly\r\n"
484 // "set-cookie: prov_tgt=; expires=Tue, 14 Mar 2023 10:23:00 GMT; domain=.stackoverflow.com; path=/; secure; samesite=none; httponly\r\n"
485 // "x-request-guid: a6536a49-b473-4c6f-b313-c1e7c0d8f600\r\n"
486 // "feature-policy: microphone 'none'; speaker 'none'\r\n"
487 // "content-security-policy: upgrade-insecure-requests; frame-ancestors 'self' https://stackexchange.com\r\n"
488 // "accept-ranges: bytes\r\n"
489 // "date: Thu, 16 Mar 2023 10:23:00 GMT\r\n"
490 // "via: 1.1 varnish\r\n"
491 // "x-served-by: cache-vie6354-VIE\r\n"
492 // "x-cache: MISS\r\n"
493 // "x-cache-hits: 0\r\n"
494 // "x-timer: S1678962181.533907,VS0,VE144\r\n"
495 // "vary: Accept-Encoding,Fastly-SSL\r\n"
496 // "x-dns-prefetch-control: off\r\n"
497 // "X-Firefox-Spdy: h2\r\n"
498 // "\r\n";
499 }
500 };
501}
locale_t helper class to free_locale when going out of scope.
Definition locale.hpp:69
stdex::interval< size_t > interval
Region of the last match.
Definition parser.hpp:116
Test for given string.
Definition parser.hpp:831
Test for HTTP header.
Definition parser.hpp:7069
Test for HTTP request.
Definition parser.hpp:6937
Test for specific SGML code point.
Definition parser.hpp:353
Test for any SGML space code point.
Definition parser.hpp:440
Numerical interval.
Definition interval.hpp:18
T size() const
Returns interval size.
Definition interval.hpp:47
T end
interval end
Definition interval.hpp:20
T start
interval start
Definition interval.hpp:19