cgv
Loading...
Searching...
No Matches
scan.cxx
1#include "scan.h"
2
3#include <stdlib.h>
4#include <algorithm>
5#if __cplusplus >= 201703L
6#include <charconv>
7#endif
8
9namespace cgv {
10 namespace utils {
11
12bool is_space(char c) {
13 return c == ' ' || c == '\t' || c == '\n' || c == '\r';
14}
15
16bool is_url_special(char c) {
17 return c == '.' || c == ',' || c == ';' || c == ':';
18}
19
20bool is_digit(char c) {
21 return c >= '0' && c <= '9';
22}
23
24bool is_letter(char c)
25{
26 c = to_lower(c);
27 return c >= 'a' && c <= 'z';
28}
29
30// C++-Version:
31const unsigned char AE = static_cast<unsigned char>(142);
32const unsigned char ae = static_cast<unsigned char>(132);
33const unsigned char OE = static_cast<unsigned char>(153);
34const unsigned char oe = static_cast<unsigned char>(148);
35const unsigned char UE = static_cast<unsigned char>(154);
36const unsigned char ue = static_cast<unsigned char>(129);
37const unsigned char ss = static_cast<unsigned char>(225);
38
39char to_lower(char c)
40{
41 if (c >= 'A' && c <= 'Z')
42 return (c - 'A') + 'a';
43 unsigned char uc = c;
44 switch (uc) {
45 case OE: return (char)oe;
46 case UE: return (char)ue;
47 case AE: return (char)ae;
48 default: return c;
49 }
50}
51
52std::string to_hex(uint8_t v, bool use_upper_case)
53{
54 static const char lc_hex_digits[] = "0123456789abcdef";
55 static const char uc_hex_digits[] = "0123456789ABCDEF";
56 const char* hex_digits = use_upper_case ? uc_hex_digits : lc_hex_digits;
57 char res[2] = { hex_digits[v / 16], hex_digits[v & 15] };
58 return std::string(res, 2);
59}
60uint8_t from_hex(char c)
61{
62 switch (c) {
63 case '0':
64 case '1':
65 case '2':
66 case '3':
67 case '4':
68 case '5':
69 case '6':
70 case '7':
71 case '8':
72 case '9':
73 return c - '0';
74 case 'A':
75 case 'B':
76 case 'C':
77 case 'D':
78 case 'E':
79 case 'F':
80 return c - 'A';
81 case 'a':
82 case 'b':
83 case 'c':
84 case 'd':
85 case 'e':
86 case 'f':
87 return c - 'a';
88 }
89 return 0;
90}
91std::vector<uint8_t> parse_hex_bytes(const std::string& byte_str)
92{
93 std::vector<uint8_t> bytes;
94 for (size_t i = 0; i < byte_str.size(); i += 2)
95 bytes.push_back(16 * from_hex(byte_str[i]) + from_hex(byte_str[i + 1]));
96 return bytes;
97}
98std::string to_lower(const std::string& _s)
99{
100 std::string s(_s);
101 for (unsigned int i = 0; i < s.size(); ++i)
102 s[i] = to_lower(s[i]);
103 return s;
104}
105
106char to_upper(char c)
107{
108 if (c >= 'a' && c <= 'z')
109 return (c - 'a') + 'A';
110 unsigned char uc = c;
111 switch (uc) {
112 case oe: return (char)OE;
113 case ue: return (char)UE;
114 case ae: return (char)AE;
115 default: return c;
116 }
117}
118
119std::string to_upper(const std::string& _s)
120{
121 std::string s(_s);
122 for (unsigned int i = 0; i < s.size(); ++i)
123 s[i] = to_upper(s[i]);
124 return s;
125}
126
127std::string& remove(std::string& s, char c)
128{
129 s.erase(std::remove(s.begin(), s.end(), c), s.end());
130 return s;
131}
132
133
134std::string remove_copy(const std::string& s, char c)
135{
136 std::string r;
137 std::remove_copy(s.begin(), s.end(), std::back_inserter(r), c);
138 return r;
139}
140
141std::string replace_special(const std::string& _s)
142{
143 std::string s;
144 for (unsigned int i=0; i<_s.size(); ++i) {
145 switch ((unsigned char)s[i]) {
146 case AE: s += "Ae"; break;
147 case OE: s += "Oe"; break;
148 case UE: s += "Ue"; break;
149 case ae: s += "ae"; break;
150 case oe: s += "oe"; break;
151 case ue: s += "ue"; break;
152 case ss: s += "ss"; break;
153 default : s += _s[i]; break;
154 }
155 }
156 return s;
157}
158
159unsigned int replace(std::string& s, char c1, char c2)
160{
161 unsigned int count = 0;
162 for (unsigned int i=0; i<s.size(); ++i) {
163 if (s[i] == c1) {
164 s[i] = c2;
165 ++count;
166 }
167 }
168 return count;
169}
170
171unsigned int replace(std::string& _s, const std::string& s1, const std::string& s2)
172{
173 if (s1.empty())
174 return 0;
175 size_t l = _s.size();
176 size_t l1 = s1.size();
177 if (l1 > l)
178 return 0;
179 size_t l2 = s2.size();
180 // count number of replacements in n
181 size_t n = 0;
182 for (size_t pos = 0; pos <= l - l1; ++pos) {
183 size_t i;
184 for (i=0; i<l1; ++i)
185 if (_s[pos+i] != s1[i])
186 break;
187 if (i == l1) {
188 if (l1 == l2) {
189 for (i=0; i<l1; ++i)
190 _s[pos+i] = s2[i];
191 }
192 else {
193 _s = _s.substr(0, pos) + s2 + _s.substr(pos+l1);
194 l = _s.size();
195 }
196 pos += l2;
197 ++n;
198 if (l1 > l)
199 return (unsigned)n;
200 }
201 }
202 return (unsigned)n;
203}
204
205std::string escape_special(const std::string& s)
206{
207 std::string r;
208 for (unsigned int i = 0; i < s.size(); ++i) {
209 switch (s[i]) {
210 case '\a' : r += "\\a"; break;
211 case '\b' : r += "\\b"; break;
212 case '\f' : r += "\\f"; break;
213 case '\n' : r += "\\n"; break;
214 case '\r' : r += "\\r"; break;
215 case '\t' : r += "\\t"; break;
216 case '\v' : r += "\\v"; break;
217 case '\'' : r += "\\'"; break;
218 case '"' : r += "\\\""; break;
219 case '\\' : r += "\\\\"; break;
220 default:
221 r += s[i];
222 }
223 }
224 return r;
225}
226
227std::string interpret_special(const std::string& s)
228{
229 std::string r;
230 for (unsigned int i = 0; i < s.size(); ++i) {
231 if (s[i] == '\\') {
232 if (i+1 < s.size()) {
233 ++i;
234 switch (s[i]) {
235 case 'a' : r += '\a'; break;
236 case 'b' : r += '\b'; break;
237 case 'f' : r += '\f'; break;
238 case 'n' : r += '\n'; break;
239 case 'r' : r += '\r'; break;
240 case 't' : r += '\t'; break;
241 case 'v' : r += '\v'; break;
242 case '\'' : r += '\''; break;
243 case '\"' : r += '\"'; break;
244 case '\\' : r += '\\'; break;
245 case '?' : r += '\?'; break;
246 case '0':
247 case '1':
248 case '2':
249 case '3':
250 case '4':
251 case '5':
252 case '6':
253 case '7':
254 if (i+2 < s.size() && is_digit(s[i+1]) && is_digit(s[i+2]) ) {
255 r += char((s[i]-'0')*64+(s[i+1]-'0')*8+(s[i+2]-'0'));
256 i += 2;
257 }
258 else
259 r += s[i];
260 break;
261 case 'x' :
262 if (i+2 < s.size()) {
263 char c = 0;
264 if (is_digit(s[i+1]))
265 c += (s[i+1]-'0')*16;
266 else
267 c += (to_lower(s[i+1])-'a')*16;
268 if (is_digit(s[i+2]))
269 c += s[i+2]-'0';
270 else
271 c += to_lower(s[i+2])-'a';
272 r += c;
273 i += 2;
274 }
275 else
276 r += s[i];
277 break;
278 default: r += s[i]; break;
279 }
280 }
281 else
282 r += s[i];
283 }
284 else
285 r += s[i];
286 }
287 return r;
288}
289
290
291bool is_element(char c, const std::string& s)
292{
293 return s.find_first_of(c) != std::string::npos;
294}
295
296bool is_element(const std::string& e, const std::string& s, char sep)
297{
298 return get_element_index(e,s,sep) != -1;
299}
300
301std::string get_element(const std::string& s, int element_index, char sep)
302{
303 size_t end_pos, start_pos = 0;
304 int ei = -1;
305 do {
306 ++ei;
307 if (ei > 0) {
308 start_pos = end_pos + 1;
309 if (start_pos == s.size())
310 return "";
311 }
312 end_pos = s.find_first_of(sep, start_pos);
313 if (end_pos == std::string::npos) {
314 end_pos = s.size();
315 break;
316 }
317 } while (ei < element_index);
318 if (ei < element_index)
319 return "";
320 return s.substr(start_pos, end_pos - start_pos);
321}
322
323int get_element_index(const std::string& e, const std::string& s, char sep)
324{
325 if (e.empty() && s.empty())
326 return 0;
327
328 size_t n = s.size();
329 bool at_start = true;
330 int idx = 0;
331 unsigned k = 0;
332 bool match = true;
333 for (size_t i = 0; i<n; ++i) {
334 if (s[i] == sep) {
335 if (k == e.size() && match)
336 return idx;
337 k = 0;
338 ++idx;
339 match = true;
340 }
341 else {
342 at_start = false;
343 if (match) {
344 if (k == e.size() || s[i] != e[k])
345 match = false;
346 else
347 ++k;
348 }
349 }
350 }
351 if (k == e.size() && match)
352 return idx;
353 return -1;
354}
355
356#if __cplusplus >= 201703L
357 // We will be using std::from_chars below for parsing, this provides the whitespace check we need there
358 inline const bool char_is_zero_or_whitespace (const char ch) {
359 return ch == 0 || ch == '\r' || ch == '\n' || ch == ' ' || ch == '\t';
360 }
361 // This is the logic we're using to test whether a from_chars conversion was successful
362 inline const bool from_chars_success (const std::from_chars_result &r, const char *end_char) {
363 return r.ec == std::errc() && (r.ptr == end_char || char_is_zero_or_whitespace(*r.ptr));
364 }
365#endif
366
367bool is_integer(const char* begin, const char* end, int& value)
368{
369 if (begin == end)
370 return false;
371
372#if __cplusplus >= 201703L
373 return from_chars_success(std::from_chars(begin, end, value), end);
374#else
375 // skip trailing spaces
376 while (begin < end && *begin == ' ')
377 ++begin;
378 // check for hexadecimal case
379 if (end-begin>2 && begin[0] == '0' && to_upper(begin[1]) == 'X') {
380 int new_value = 0, b = 1;
381 const char* p;
382 for (p = end; p>begin+2; b *= 16) {
383 --p;
384 if (is_digit(*p))
385 new_value += (int)(*p - '0')*b;
386 else {
387 char c = to_upper(*p);
388 if (c >= 'A' && c <= 'F')
389 new_value += (int)(c - 'A' + 10)*b;
390 else
391 return false;
392 }
393 }
394 value = new_value;
395 return true;
396 }
397 int new_value = 0, b = 1;
398 const char* p;
399 for (p = end; p>begin; b *= 10) {
400 --p;
401 if (is_digit(*p))
402 new_value += (int)(*p - '0')*b;
403 else {
404 if (*p == '-') {
405 new_value = -new_value;
406 break;
407 }
408 if (*p != '+')
409 return false;
410 break;
411 }
412 }
413 if (p == begin) {
414 value = new_value;
415 return true;
416 }
417 return false;
418#endif
419}
420
421bool is_integer(const std::string& s, int& value)
422{
423 return is_integer(&s[0], &s[0]+s.size(), value);
424}
425
426bool is_double(const char* begin, const char* end, double& value)
427{
428 if (begin == end)
429 return false;
430
431#if __cplusplus >= 201703L
432 return from_chars_success(std::from_chars(begin, end, value), end);
433#else
434 bool found_digit = false;
435 int nr_dots = 0;
436 int nr_exp = 0;
437 bool sign_may_follow = true;
438 const char* p = begin;
439 while (p < end && *p == ' ')
440 ++p;
441 for (; p<end; ++p) {
442 switch (*p) {
443 case '0' :
444 case '1' :
445 case '2' :
446 case '3' :
447 case '4' :
448 case '5' :
449 case '6' :
450 case '7' :
451 case '8' :
452 case '9' :
453 found_digit = true;
454 sign_may_follow = false;
455 break;
456 case '+' :
457 case '-' :
458 if (!sign_may_follow)
459 return false;
460 sign_may_follow = false;
461 break;
462 case '.' :
463 if (++nr_dots > 1)
464 return false;
465 sign_may_follow = false;
466 break;
467 case 'e' :
468 case 'E' :
469 if (++nr_exp > 1)
470 return false;
471 sign_may_follow = true;
472 break;
473 default:
474 return false;
475 }
476 }
477 if (!found_digit)
478 return false;
479 value = atof(std::string(begin,end-begin).c_str());
480 return true;
481#endif
482}
483
484bool is_double(const std::string& s, double& value)
485{
486 return is_double(&s[0], &s[0]+s.size(), value);
487}
488
489
490bool is_year(const char* begin, const char* end, unsigned short& year, bool short_allowed)
491{
492 int i;
493 unsigned int size = (unsigned int) (end-begin);
494 if ((size == 2 && short_allowed) ||
495 ((size == 4) && is_integer(begin, end, i))) {
496 year = i;
497 return true;
498 }
499 return false;
500}
501
502bool is_year(const std::string& s, unsigned short& year, bool short_allowed)
503{
504 return is_year(&s[0], &s[0]+s.size(), year, short_allowed);
505}
506
507bool find_name(const std::string& s, const char* names[], int& idx)
508{
509 unsigned int i=0;
510 while (names[i]) {
511 if (s == names[i]) {
512 idx = i;
513 return true;
514 }
515 ++i;
516 }
517 return false;
518}
519
520bool is_month(const char* begin, const char* end, unsigned char& month)
521{
522 static const char* months_short[] = {
523 "jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec", 0
524 };
525 static const char* months_english[] = {
526 "january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december", 0
527 };
528 static const char* months_german[] = {
529 "januar", "februar", "maerz", "april", "mai", "juni", "juli", "august", "september", "oktober", "november", "dezember", 0
530 };
531 int i;
532 if (is_integer(begin,end,i)) {
533 if (i > 0 && i <= 12) {
534 month = i+1;
535 return true;
536 }
537 }
538 std::string s = to_lower(replace_special(std::string(begin,end-begin)));
539 if (find_name(s, months_short, i) || find_name(s, months_english, i) || find_name(s, months_german, i) ) {
540 month = i+1;
541 return true;
542 }
543 return false;
544}
545
546bool is_month(const std::string& s, unsigned char& month)
547{
548 return is_month(&s[0], &s[0]+s.size(), month);
549}
550
551bool is_time(const std::string& s, cgv::utils::time& t, const char **new_end)
552{
553 if (s.size() == 0)
554 return false;
555 size_t end = s.size();
556 while (end > 0 && is_url_special(s[end-1]))
557 --end;
558 size_t pos = s.find_first_of(':');
559 if (pos == std::string::npos)
560 return false;
561 int i;
562 if (!(is_integer(&s[0], &s[pos], i) && i >= 0 && i < 24))
563 return false;
564 t.h = (unsigned char) i;
565 if (pos >= end)
566 return false;
567 ++pos;
568 size_t pos2 = s.find_first_of(':', pos);
569 size_t pos3 = pos2+1;
570 if (pos2 == std::string::npos)
571 pos3 = pos2 = end;
572 if (!(is_integer(&s[pos], &s[pos2], i) && i >= 0 && i < 60))
573 return false;
574 t.minutes = (unsigned char) i;
575 if (pos2 >= end) {
576 if (new_end)
577 *new_end = &s[0]+pos3;
578 return true;
579 }
580 pos = ++pos2;
581 while (pos2 < end && is_digit(s[pos2]))
582 ++pos2;
583 if (!(is_integer(&s[pos], &s[pos2], i) && i >= 0 && i < 60))
584 return false;
585 t.sec = i;
586 if (new_end)
587 *new_end = &s[0]+pos2;
588 return true;
589}
590
591bool is_date(const std::string& s, cgv::utils::date& d, const char **new_end)
592{
593 if (s.size() == 0)
594 return false;
595 size_t end = s.size();
596 while (end > 0 && is_url_special(s[end-1]))
597 --end;
598 size_t pos = s.find_first_of('.');
599 if (pos == std::string::npos)
600 return false;
601 int i;
602 if (!(is_integer(&s[0], &s[pos], i) && i > 0 && i < 32))
603 return false;
604 d.day = (unsigned char)i;
605 if (pos >= end) {
606 if (new_end)
607 *new_end = &s[0]+pos+1;
608 return true;
609 }
610 ++pos;
611 size_t pos2 = s.find_first_of('.', pos);
612 if (pos2 == std::string::npos)
613 return false;
614 if (!is_month(&s[pos], &s[pos2], d.month))
615 return false;
616 if (pos2 >= end) {
617 if (new_end)
618 *new_end = &s[0]+pos2+1;
619 return true;
620 }
621 pos = ++pos2;
622 while (pos2 < end && is_digit(s[pos2]))
623 ++pos2;
624 if (!is_year(&s[pos],&s[pos2],d.year))
625 return false;
626 if (new_end)
627 *new_end = &s[0]+pos2;
628 return true;
629}
630
631bool is_time(const char* begin, const char* end, cgv::utils::time& t, const char **new_end)
632{
633 std::string s(begin,end-begin);
634 if (is_time(s, t, new_end)) {
635 if (new_end)
636 *new_end = end + (*new_end - (&s[0]+s.length()));
637 return true;
638 }
639 return false;
640}
641
642bool is_date(const char* begin, const char* end, cgv::utils::date& d, const char **new_end)
643{
644 std::string s(begin,end-begin);
645 if (is_date(s, d, new_end)) {
646 if (new_end)
647 *new_end = end + (*new_end - (&s[0]+s.length()));
648 return true;
649 }
650 return false;
651}
652
653bool is_url(const std::string& s, const char** end)
654{
655 if (s.substr(0,8) == "https://" ||
656 s.substr(0,7) == "http://" ||
657 s.substr(0,6) == "ftp://" ||
658 s.substr(0,6) == "smb://" ||
659 s.substr(0,6) == "svn://" ||
660 s.substr(0,7) == "file://") {
661 if (end) {
662 *end = &s[s.length()-1];
663 while (is_url_special(**end))
664 --*end;
665 ++*end;
666 }
667 return true;
668 }
669 return false;
670}
671
672bool is_url(const char* begin, const char* end, const char** new_end)
673{
674 std::string s(begin,end-begin);
675 if (is_url(s, new_end)) {
676 if (new_end)
677 *new_end = end + (*new_end - (&s[0]+s.length()));
678 return true;
679 }
680 return false;
681}
682
683const char* skip_spaces(const char* begin, const char* end)
684{
685 while (begin < end && is_space(*begin))
686 ++begin;
687 return begin;
688}
689
690const char* cutoff_spaces(const char* begin, const char* end)
691{
692 while (begin < end && is_space(*(end-1)))
693 --end;
694 return end;
695}
696
697std::string& ltrim(std::string& str, const std::string& chars)
698{
699 str.erase(0, str.find_first_not_of(chars));
700 return str;
701}
702
703std::string& rtrim(std::string& str, const std::string& chars)
704{
705 str.erase(str.find_last_not_of(chars) + 1);
706 return str;
707}
708
709std::string& trim(std::string& str, const std::string& chars)
710{
711 return ltrim(rtrim(str, chars), chars);
712}
713
714std::string ltrim(const std::string& str, const std::string& chars)
715{
716 std::string s = str;
717 s.erase(0, str.find_first_not_of(chars));
718 return s;
719}
720
721std::string rtrim(const std::string& str, const std::string& chars)
722{
723 std::string s = str;
724 s.erase(str.find_last_not_of(chars) + 1);
725 return s;
726}
727
728std::string trim(const std::string& str, const std::string& chars)
729{
730 return ltrim(rtrim(str, chars), chars);
731}
732
733std::string join(const std::vector<std::string>::const_iterator first, const std::vector<std::string>::const_iterator last, const std::string& sep, bool trailing_sep)
734{
735 if(last < first)
736 return "";
737
738 std::string res = "";
739
740 for(auto curr = first; curr != last; ++curr) {
741 res += *curr;
742 if(last - curr > 1 || trailing_sep)
743 res += sep;
744 }
745 return res;
746}
747
748std::string join(const std::vector<std::string>& strs, const std::string& sep, bool trailing_sep)
749{
750 return join(strs.begin(), strs.end(), sep, trailing_sep);
751}
752
753std::string join(const std::vector<cgv::utils::token>::const_iterator first, const std::vector<cgv::utils::token>::const_iterator last, const std::string& sep, bool trailing_sep)
754{
755 std::vector<std::string> strs = to_strings(first, last);
756 return join(strs.begin(), strs.end(), sep, trailing_sep);
757}
758
759unsigned int levenshtein_distance(const std::string& s1, const std::string& s2)
760{
761 // create two work vectors of integer distances
762 std::vector<int> v0(s2.length() + 1);
763 std::vector<int> v1(s2.length() + 1);
764
765 // initialize v0 (the previous row of distances)
766 // this row is A[0][i]: edit distance from an empty s to t;
767 // that distance is the number of characters to append to s to make t.
768 for (size_t i = 0; i <= s2.length(); ++i) {
769 v0[i] = int(i);
770 }
771
772 for (size_t i = 0; i < s1.length(); ++i) {
773 // calculate v1 (current row distances) from the previous row v0
774
775 // first element of v1 is A[i + 1][0]
776 // edit distance is delete (i + 1) chars from s to match empty t
777 v1[0] = int(i + 1);
778
779 // use formula to fill in the rest of the row
780 for (size_t j = 0; j < s2.length(); ++j) {
781 // calculating costs for A[i + 1][j + 1]
782 int deletion_cost = v0[j + 1] + 1;
783 int insertion_cost = v1[j] + 1;
784 int substitution_cost = 0;
785 if (s1[i] == s2[j])
786 substitution_cost = v0[j];
787 else
788 substitution_cost = v0[j] + 1;
789
790 v1[j + 1] = std::min(std::min(deletion_cost, insertion_cost), substitution_cost);
791 }
792
793 // copy v1 (current row) to v0 (previous row) for next iteration
794 // since data in v1 is always invalidated, a swap without copy could be more efficient
795 std::swap(v0, v1);
796 }
797 // after the last swap, the results of v1 are now in v0
798 return v0[s2.length()];
799}
800
801 }
802}
bool is_digit(char c)
check if char is a digit
Definition scan.cxx:20
std::vector< std::string > to_strings(const std::vector< token >::const_iterator first, const std::vector< token >::const_iterator last)
convert to strings
Definition token.h:62
unsigned int replace(std::string &s, char c1, char c2)
replace char c1 with c2 in the given string _s and return number of replacements
Definition scan.cxx:159
std::string to_hex(uint8_t v, bool use_upper_case)
convert to hex
Definition scan.cxx:52
std::string get_element(const std::string &s, int element_index, char sep)
interpret s as a list separated by sep and return the element with the given element index.
Definition scan.cxx:301
bool is_url(const std::string &s, const char **end)
check and extract end of valid url from string s
Definition scan.cxx:653
std::string & rtrim(std::string &str, const std::string &chars)
trim white space or other characters from end of string
Definition scan.cxx:703
std::string interpret_special(const std::string &s)
interprets the C++ special characters \a, \b, \f, \n, \r, \t, \v, \\', \", \\, \?,...
Definition scan.cxx:227
bool is_integer(const char *begin, const char *end, int &value)
check if the text range (begin,end( defines an integer value. If yes, store the value in the passed r...
Definition scan.cxx:367
std::string escape_special(const std::string &s)
escapes the C++ special characters \a, \b, \f, \n, \r, \t, \v, \\', \", \\, \?
Definition scan.cxx:205
bool is_month(const char *begin, const char *end, unsigned char &month)
check and extract month from string token [begin, end]
Definition scan.cxx:520
std::string & trim(std::string &str, const std::string &chars)
trim white space or other characters from start and end of string
Definition scan.cxx:709
bool is_year(const char *begin, const char *end, unsigned short &year, bool short_allowed)
check and extract year from string token [begin, end]
Definition scan.cxx:490
std::string & ltrim(std::string &str, const std::string &chars)
trim white space or other characters from start of string
Definition scan.cxx:697
bool is_url_special(char c)
check if char is a special character from an url
Definition scan.cxx:16
char to_lower(char c)
convert char to lower case
Definition scan.cxx:39
bool is_date(const std::string &s, cgv::utils::date &d, const char **new_end)
check and extract date from string s
Definition scan.cxx:591
char to_upper(char c)
convert char to upper case
Definition scan.cxx:106
std::string remove_copy(const std::string &s, char c)
return a copy of the given string s with all occurences of char removed
Definition scan.cxx:134
bool is_space(char c)
check if char is a whitespace
Definition scan.cxx:12
bool find_name(const std::string &s, const char *names[], int &idx)
check if string s is contained in the given array of names and in case of success store name index in...
Definition scan.cxx:507
std::string join(const std::vector< std::string >::const_iterator first, const std::vector< std::string >::const_iterator last, const std::string &sep, bool trailing_sep)
joins a given range of strings, separating them by the given separator; if trailing_sep is true,...
Definition scan.cxx:733
std::string replace_special(const std::string &_s)
replaces the german special characters ä,ö,ü,ß,Ä,Ö,Ü
Definition scan.cxx:141
bool is_letter(char c)
check if char is a letter
Definition scan.cxx:24
bool is_double(const char *begin, const char *end, double &value)
check if the text range (begin,end( defines a double value. If yes, store the value in the passed ref...
Definition scan.cxx:426
bool is_time(const std::string &s, cgv::utils::time &t, const char **new_end)
check and extract time from string s
Definition scan.cxx:551
bool is_element(char c, const std::string &s)
check if char c arises in string s
Definition scan.cxx:291
const char * cutoff_spaces(const char *begin, const char *end)
return new end pointer by cutting off spaces at the end
Definition scan.cxx:690
uint8_t from_hex(char c)
convert from hex character
Definition scan.cxx:60
std::string & remove(std::string &s, char c)
remove char c from the given string s and return a reference to the same string object
Definition scan.cxx:127
int get_element_index(const std::string &e, const std::string &s, char sep)
check if the string e is contained as element in the string s, which is a list separated by sep and r...
Definition scan.cxx:323
const char * skip_spaces(const char *begin, const char *end)
return new start pointer by skipping spaces at begin
Definition scan.cxx:683
std::vector< uint8_t > parse_hex_bytes(const std::string &byte_str)
parse bytes hex coded bytes
Definition scan.cxx:91
unsigned int levenshtein_distance(const std::string &s1, const std::string &s2)
compute the levenshtein distance between two strings s1 and s2
Definition scan.cxx:759
the cgv namespace
Definition print.h:11
Helper functions to process strings.