5#if __cplusplus >= 201703L
13 return c ==
' ' || c ==
'\t' || c ==
'\n' || c ==
'\r';
17 return c ==
'.' || c ==
',' || c ==
';' || c ==
':';
21 return c >=
'0' && c <=
'9';
27 return c >=
'a' && c <=
'z';
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);
41 if (c >=
'A' && c <=
'Z')
42 return (c -
'A') +
'a';
45 case OE:
return (
char)oe;
46 case UE:
return (
char)ue;
47 case AE:
return (
char)ae;
52std::string
to_hex(uint8_t v,
bool use_upper_case)
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);
93 std::vector<uint8_t> bytes;
94 for (
size_t i = 0; i < byte_str.size(); i += 2)
101 for (
unsigned int i = 0; i < s.size(); ++i)
108 if (c >=
'a' && c <=
'z')
109 return (c -
'a') +
'A';
110 unsigned char uc = c;
112 case oe:
return (
char)OE;
113 case ue:
return (
char)UE;
114 case ae:
return (
char)AE;
122 for (
unsigned int i = 0; i < s.size(); ++i)
127std::string&
remove(std::string& s,
char c)
129 s.erase(std::remove(s.begin(), s.end(), c), s.end());
137 std::remove_copy(s.begin(), s.end(), std::back_inserter(r), c);
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;
159unsigned int replace(std::string& s,
char c1,
char c2)
161 unsigned int count = 0;
162 for (
unsigned int i=0; i<s.size(); ++i) {
171unsigned int replace(std::string& _s,
const std::string& s1,
const std::string& s2)
175 size_t l = _s.size();
176 size_t l1 = s1.size();
179 size_t l2 = s2.size();
182 for (
size_t pos = 0; pos <= l - l1; ++pos) {
185 if (_s[pos+i] != s1[i])
193 _s = _s.substr(0, pos) + s2 + _s.substr(pos+l1);
208 for (
unsigned int i = 0; i < s.size(); ++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;
230 for (
unsigned int i = 0; i < s.size(); ++i) {
232 if (i+1 < s.size()) {
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;
255 r += char((s[i]-
'0')*64+(s[i+1]-
'0')*8+(s[i+2]-
'0'));
262 if (i+2 < s.size()) {
265 c += (s[i+1]-
'0')*16;
278 default: r += s[i];
break;
293 return s.find_first_of(c) != std::string::npos;
296bool is_element(
const std::string& e,
const std::string& s,
char sep)
301std::string
get_element(
const std::string& s,
int element_index,
char sep)
303 size_t end_pos, start_pos = 0;
308 start_pos = end_pos + 1;
309 if (start_pos == s.size())
312 end_pos = s.find_first_of(sep, start_pos);
313 if (end_pos == std::string::npos) {
317 }
while (ei < element_index);
318 if (ei < element_index)
320 return s.substr(start_pos, end_pos - start_pos);
325 if (e.empty() && s.empty())
329 bool at_start =
true;
333 for (
size_t i = 0; i<n; ++i) {
335 if (k == e.size() && match)
344 if (k == e.size() || s[i] != e[k])
351 if (k == e.size() && match)
356#if __cplusplus >= 201703L
358 inline const bool char_is_zero_or_whitespace (
const char ch) {
359 return ch == 0 || ch ==
'\r' || ch ==
'\n' || ch ==
' ' || ch ==
'\t';
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));
367bool is_integer(
const char* begin,
const char* end,
int& value)
372#if __cplusplus >= 201703L
373 return from_chars_success(std::from_chars(begin, end, value), end);
376 while (begin < end && *begin ==
' ')
379 if (end-begin>2 && begin[0] ==
'0' &&
to_upper(begin[1]) ==
'X') {
380 int new_value = 0, b = 1;
382 for (p = end; p>begin+2; b *= 16) {
385 new_value += (int)(*p -
'0')*b;
388 if (c >=
'A' && c <=
'F')
389 new_value += (int)(c -
'A' + 10)*b;
397 int new_value = 0, b = 1;
399 for (p = end; p>begin; b *= 10) {
402 new_value += (
int)(*p -
'0')*b;
405 new_value = -new_value;
423 return is_integer(&s[0], &s[0]+s.size(), value);
426bool is_double(
const char* begin,
const char* end,
double& value)
431#if __cplusplus >= 201703L
432 return from_chars_success(std::from_chars(begin, end, value), end);
434 bool found_digit =
false;
437 bool sign_may_follow =
true;
438 const char* p = begin;
439 while (p < end && *p ==
' ')
454 sign_may_follow =
false;
458 if (!sign_may_follow)
460 sign_may_follow =
false;
465 sign_may_follow =
false;
471 sign_may_follow =
true;
479 value = atof(std::string(begin,end-begin).c_str());
486 return is_double(&s[0], &s[0]+s.size(), value);
490bool is_year(
const char* begin,
const char* end,
unsigned short& year,
bool short_allowed)
493 unsigned int size = (
unsigned int) (end-begin);
494 if ((size == 2 && short_allowed) ||
502bool is_year(
const std::string& s,
unsigned short& year,
bool short_allowed)
504 return is_year(&s[0], &s[0]+s.size(), year, short_allowed);
507bool find_name(
const std::string& s,
const char* names[],
int& idx)
520bool is_month(
const char* begin,
const char* end,
unsigned char& month)
522 static const char* months_short[] = {
523 "jan",
"feb",
"mar",
"apr",
"may",
"jun",
"jul",
"aug",
"sep",
"oct",
"nov",
"dec", 0
525 static const char* months_english[] = {
526 "january",
"february",
"march",
"april",
"may",
"june",
"july",
"august",
"september",
"october",
"november",
"december", 0
528 static const char* months_german[] = {
529 "januar",
"februar",
"maerz",
"april",
"mai",
"juni",
"juli",
"august",
"september",
"oktober",
"november",
"dezember", 0
533 if (i > 0 && i <= 12) {
546bool is_month(
const std::string& s,
unsigned char& month)
548 return is_month(&s[0], &s[0]+s.size(), month);
555 size_t end = s.size();
558 size_t pos = s.find_first_of(
':');
559 if (pos == std::string::npos)
562 if (!(
is_integer(&s[0], &s[pos], i) && i >= 0 && i < 24))
564 t.h = (
unsigned char) i;
568 size_t pos2 = s.find_first_of(
':', pos);
569 size_t pos3 = pos2+1;
570 if (pos2 == std::string::npos)
572 if (!(
is_integer(&s[pos], &s[pos2], i) && i >= 0 && i < 60))
574 t.minutes = (
unsigned char) i;
577 *new_end = &s[0]+pos3;
581 while (pos2 < end &&
is_digit(s[pos2]))
583 if (!(
is_integer(&s[pos], &s[pos2], i) && i >= 0 && i < 60))
587 *new_end = &s[0]+pos2;
595 size_t end = s.size();
598 size_t pos = s.find_first_of(
'.');
599 if (pos == std::string::npos)
602 if (!(
is_integer(&s[0], &s[pos], i) && i > 0 && i < 32))
604 d.day = (
unsigned char)i;
607 *new_end = &s[0]+pos+1;
611 size_t pos2 = s.find_first_of(
'.', pos);
612 if (pos2 == std::string::npos)
614 if (!
is_month(&s[pos], &s[pos2], d.month))
618 *new_end = &s[0]+pos2+1;
622 while (pos2 < end &&
is_digit(s[pos2]))
624 if (!
is_year(&s[pos],&s[pos2],d.year))
627 *new_end = &s[0]+pos2;
633 std::string s(begin,end-begin);
636 *new_end = end + (*new_end - (&s[0]+s.length()));
644 std::string s(begin,end-begin);
647 *new_end = end + (*new_end - (&s[0]+s.length()));
653bool is_url(
const std::string& s,
const char** end)
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://") {
662 *end = &s[s.length()-1];
672bool is_url(
const char* begin,
const char* end,
const char** new_end)
674 std::string s(begin,end-begin);
677 *new_end = end + (*new_end - (&s[0]+s.length()));
685 while (begin < end &&
is_space(*begin))
692 while (begin < end &&
is_space(*(end-1)))
697std::string&
ltrim(std::string& str,
const std::string& chars)
699 str.erase(0, str.find_first_not_of(chars));
703std::string&
rtrim(std::string& str,
const std::string& chars)
705 str.erase(str.find_last_not_of(chars) + 1);
709std::string&
trim(std::string& str,
const std::string& chars)
714std::string
ltrim(
const std::string& str,
const std::string& chars)
717 s.erase(0, str.find_first_not_of(chars));
721std::string
rtrim(
const std::string& str,
const std::string& chars)
724 s.erase(str.find_last_not_of(chars) + 1);
728std::string
trim(
const std::string& str,
const std::string& chars)
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)
738 std::string res =
"";
740 for(
auto curr = first; curr != last; ++curr) {
742 if(last - curr > 1 || trailing_sep)
748std::string
join(
const std::vector<std::string>& strs,
const std::string& sep,
bool trailing_sep)
750 return join(strs.begin(), strs.end(), sep, trailing_sep);
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)
755 std::vector<std::string> strs =
to_strings(first, last);
756 return join(strs.begin(), strs.end(), sep, trailing_sep);
762 std::vector<int> v0(s2.length() + 1);
763 std::vector<int> v1(s2.length() + 1);
768 for (
size_t i = 0; i <= s2.length(); ++i) {
772 for (
size_t i = 0; i < s1.length(); ++i) {
780 for (
size_t j = 0; j < s2.length(); ++j) {
782 int deletion_cost = v0[j + 1] + 1;
783 int insertion_cost = v1[j] + 1;
784 int substitution_cost = 0;
786 substitution_cost = v0[j];
788 substitution_cost = v0[j] + 1;
790 v1[j + 1] = std::min(std::min(deletion_cost, insertion_cost), substitution_cost);
798 return v0[s2.length()];
bool is_digit(char c)
check if char is a digit
std::vector< std::string > to_strings(const std::vector< token >::const_iterator first, const std::vector< token >::const_iterator last)
convert to strings
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
std::string to_hex(uint8_t v, bool use_upper_case)
convert to hex
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.
bool is_url(const std::string &s, const char **end)
check and extract end of valid url from string s
std::string & rtrim(std::string &str, const std::string &chars)
trim white space or other characters from end of string
std::string interpret_special(const std::string &s)
interprets the C++ special characters \a, \b, \f, \n, \r, \t, \v, \\', \", \\, \?,...
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...
std::string escape_special(const std::string &s)
escapes the C++ special characters \a, \b, \f, \n, \r, \t, \v, \\', \", \\, \?
bool is_month(const char *begin, const char *end, unsigned char &month)
check and extract month from string token [begin, end]
std::string & trim(std::string &str, const std::string &chars)
trim white space or other characters from start and end of string
bool is_year(const char *begin, const char *end, unsigned short &year, bool short_allowed)
check and extract year from string token [begin, end]
std::string & ltrim(std::string &str, const std::string &chars)
trim white space or other characters from start of string
bool is_url_special(char c)
check if char is a special character from an url
char to_lower(char c)
convert char to lower case
bool is_date(const std::string &s, cgv::utils::date &d, const char **new_end)
check and extract date from string s
char to_upper(char c)
convert char to upper case
std::string remove_copy(const std::string &s, char c)
return a copy of the given string s with all occurences of char removed
bool is_space(char c)
check if char is a whitespace
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...
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,...
std::string replace_special(const std::string &_s)
replaces the german special characters ä,ö,ü,ß,Ä,Ö,Ü
bool is_letter(char c)
check if char is a letter
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...
bool is_time(const std::string &s, cgv::utils::time &t, const char **new_end)
check and extract time from string s
bool is_element(char c, const std::string &s)
check if char c arises in string s
const char * cutoff_spaces(const char *begin, const char *end)
return new end pointer by cutting off spaces at the end
uint8_t from_hex(char c)
convert from hex character
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
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...
const char * skip_spaces(const char *begin, const char *end)
return new start pointer by skipping spaces at begin
std::vector< uint8_t > parse_hex_bytes(const std::string &byte_str)
parse bytes hex coded bytes
unsigned int levenshtein_distance(const std::string &s1, const std::string &s2)
compute the levenshtein distance between two strings s1 and s2
Helper functions to process strings.