43 #include <QtCore/QString>
44 #include <boost/spirit/include/qi.hpp>
45 #include <boost/spirit/include/karma.hpp>
55 namespace StringConversions
63 static unsigned int precision(T) {
return writtenDigits<T>(T()); }
79 std::back_insert_iterator<std::string> sink(target);
80 boost::spirit::karma::generate(sink, i);
100 std::back_insert_iterator<std::string> sink(target);
101 boost::spirit::karma::generate(sink, f);
116 std::back_insert_iterator<std::string> sink(target);
117 boost::spirit::karma::generate(sink, d);
131 std::back_insert_iterator<std::string> sink(target);
132 boost::spirit::karma::generate(sink, ld);
147 std::back_insert_iterator<std::string> sink(target);
163 std::back_insert_iterator<std::string> sink(target);
178 std::back_insert_iterator<std::string> sink(target);
192 target += d.
toString(full_precision);
203 return std::string(1,
c);
213 return std::string(s);
226 while (count < length)
252 if (d < pow(10.0,
Int(n - sign - 2)))
262 while (d > pow(10.0,
Int(n - sign - 4)))
276 return s.str().substr(0, n);
281 return QString::number(d,
'f', n);
286 if (this_s.size() < size)
288 this_s.std::string::operator=(
String(size - this_s.size(),
c) + this_s);
295 if (this_s.size() < size)
297 this_s.std::string::operator=(this_s +
String(size - this_s.size(),
c));
305 if (
string.size() > this_s.size())
313 return this_s.compare(0,
string.size(),
string) == 0;
318 if (
string.size() > this_s.size())
326 return this_s.compare(this_s.size() -
string.size(),
string.size(), string) == 0;
331 return this_s.find(
string) != std::string::npos;
336 return this_s.find(
char(
byte)) != std::string::npos;
341 if (length > this_s.size())
345 return this_s.
substr(0, length);
350 if (length > this_s.size())
354 return this_s.
substr(this_s.size() - length, length);
363 if (length >
Int(this_s.size()))
367 return this_s.
substr(0, length);
376 if (length >
Int(this_s.size()))
380 return this_s.
substr(this_s.size() - length, length);
385 Size pos = this_s.find(delim);
386 if (pos == std::string::npos)
391 return this_s.
substr(0, pos);
396 Size pos = this_s.rfind(delim);
397 if (pos == std::string::npos)
402 return this_s.
substr(++pos);
407 Size begin = std::min(pos, this_s.size());
408 return static_cast<String>(this_s.std::string::substr(begin, n));
414 if (n < this_s.size())
416 end = this_s.size() - n;
418 return String(this_s.begin(), this_s.begin() + end);
424 std::string::iterator begin = this_s.begin();
425 while (begin != this_s.end() && (*begin ==
' ' || *begin ==
'\t' || *begin ==
'\n' || *begin ==
'\r'))
431 if (begin == this_s.end())
438 std::string::iterator end = this_s.end();
440 while (end != begin && (*end ==
' ' || *end ==
'\n' || *end ==
'\t' || *end ==
'\r'))
447 if (begin == this_s.begin() && end == this_s.end())
454 this_s.std::string::operator=(std::string(begin, end));
468 this_s.std::string::operator=(q + this_s + q);
475 if ((this_s.size() < 2) || (this_s[0] != q) || (this_s[this_s.size() - 1] != q))
478 __FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
479 "'" + this_s +
"' does not have the expected format of a quoted string");
481 this_s.std::string::operator=(this_s.
substr(1, this_s.size() - 2));
496 bool last_was_whitespace =
false;
497 for (std::string::iterator it = this_s.begin(); it != this_s.end(); ++it)
499 if (*it ==
' ' || *it ==
'\n' || *it ==
'\t' || *it ==
'\r')
501 if (!last_was_whitespace)
505 last_was_whitespace =
true;
510 last_was_whitespace =
false;
520 srand(time(
nullptr));
523 for (
Size i = 0; i < length; ++i)
525 random = static_cast<size_t>(floor((static_cast<double>(rand()) / (
double(RAND_MAX) + 1)) * 62.0));
528 tmp[i] = static_cast<char>(random + 48);
530 else if (random < 36)
532 tmp[i] = static_cast<char>(random + 55);
536 tmp[i] = static_cast<char>(random + 61);
545 for (
Size i = 0; i != this_s.size(); ++i)
547 this_s[i] = tmp[this_s.size() - 1 - i];
552 static bool split(
const String & this_s,
const char splitter, std::vector<String>& substrings,
559 Size nsplits = count(this_s.begin(), this_s.end(), splitter);
561 if (!quote_protect && (nsplits == 0))
563 substrings.push_back(this_s);
568 substrings.reserve(nsplits + 1);
571 std::string::const_iterator begin = this_s.begin();
572 std::string::const_iterator end = this_s.begin();
577 for (; end != this_s.end(); ++end)
583 if ((quote_count % 2 == 0) && (*end == splitter))
587 if ((block.size() >= 2) && ((block.
prefix(1) ==
String(
"\"")) ^
592 __FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
593 String(
"Could not dequote string '") + block +
594 "' due to wrongly placed '\"'.");
596 else if ((block.size() >= 2) && (block.
prefix(1) ==
String(
"\"")) &&
599 block = block.
substr(1, block.size() - 2);
601 substrings.push_back(block);
606 if (substrings.empty())
608 substrings.push_back(this_s);
614 if ((block.size() >= 2) && ((block.
prefix(1) ==
String(
"\"")) ^
619 __FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
620 String(
"Could not dequote string '") + block +
621 "' due to wrongly placed '\"'.");
623 else if ((block.size() >= 2) && (block.
prefix(1) ==
String(
"\"")) &&
626 block = block.
substr(1, block.size() - 2);
628 substrings.push_back(block);
632 for (; end != this_s.end(); ++end)
634 if (*end == splitter)
636 substrings.push_back(
String(begin, end));
640 substrings.push_back(
String(begin, end));
647 static bool split(
const String & this_s,
const String& splitter, std::vector<String>& substrings)
653 if (splitter.empty())
655 substrings.resize(this_s.size());
656 for (
Size i = 0; i < this_s.size(); ++i)
657 substrings[i] = this_s[i];
661 Size len = splitter.size(), start = 0, pos = this_s.find(splitter);
664 while (pos != std::string::npos)
666 substrings.push_back(this_s.
substr(start, pos - start));
668 pos = this_s.find(splitter, start);
670 substrings.push_back(this_s.
substr(start, this_s.size() - start));
671 return substrings.size() > 1;
678 if (this_s.empty() || splitter.empty())
681 bool in_quote =
false;
682 char targets[2] = {q, splitter[0]};
683 std::string rest = splitter.
substr(1, splitter.size() - 1);
685 for (
Size i = 0; i < this_s.size(); ++i)
689 bool embedded =
false;
692 for (; i < this_s.size(); ++i)
694 if (this_s[i] ==
'\\')
695 embedded = !embedded;
696 else if ((this_s[i] == q) && !embedded)
704 for (; i < this_s.size(); ++i)
711 if ((i < this_s.size() - 1) && (this_s[i + 1] == q))
712 embedded = !embedded;
726 i = this_s.find_first_of(targets, i, 2);
727 if (i == std::string::npos)
731 else if (this_s.compare(i + 1, rest.size(), rest) == 0)
733 substrings.push_back(this_s.
substr(start, i - start));
734 start = i + splitter.size();
742 __FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
743 "unbalanced quotation marks in string '" + this_s +
"'");
745 substrings.push_back(this_s.
substr(start, this_s.size() - start));
746 return substrings.size() > 1;
751 return QString(this_s.c_str());
761 if (!boost::spirit::qi::phrase_parse(it, this_s.end(), boost::spirit::qi::int_, boost::spirit::ascii::space, ret))
766 if (it != this_s.end())
768 throw Exception::ConversionError(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
String(
"Prefix of string '") + this_s +
"' successfully converted to an integer value. Additional characters found at position " + (
int)(distance(this_s.begin(), it) + 1));
780 if (!boost::spirit::qi::phrase_parse(it, this_s.end(), parse_float_, boost::spirit::ascii::space, ret))
785 if (it != this_s.end())
787 throw Exception::ConversionError(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
String(
"Prefix of string '") + this_s +
"' successfully converted to a float value. Additional characters found at position " + (
int)(distance(this_s.begin(), it) + 1));
805 if (!boost::spirit::qi::phrase_parse(it, s.end(), parse_double_, boost::spirit::ascii::space, ret))
812 throw Exception::ConversionError(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
String(
"Prefix of string '") + s +
"' successfully converted to a double value. Additional characters found at position " + (
int)(distance(s.begin(), it) + 1));
821 template <
typename IteratorT>
822 static bool extractDouble(IteratorT& begin,
const IteratorT& end,
double& target)
828 return boost::spirit::qi::parse(begin, end, parse_double_, target);
834 std::transform(this_s.begin(), this_s.end(), this_s.begin(), (
int (*)(
int))toupper);
840 if (this_s.size() != 0)
842 this_s[0] = toupper(this_s[0]);
849 std::transform(this_s.begin(), this_s.end(), this_s.begin(), (
int (*)(
int))tolower);
855 std::replace(this_s.begin(), this_s.end(), from, to);
863 std::vector<String> parts;
864 this_s.
split(from, parts);
865 this_s.
concatenate(parts.begin(), parts.end(), to);
872 this_s.erase(std::remove(this_s.begin(), this_s.end(), what), this_s.end());
879 this_s.append(1, end);
885 std::string::const_iterator it = this_s.begin();
886 std::string::iterator dest = this_s.begin();
887 std::string::const_iterator it_end = this_s.end();
888 bool has_spaces(
false);
892 if (
c ==
' ' ||
c ==
'\t' ||
c ==
'\n' ||
c ==
'\r')
899 if (has_spaces) *dest = *it;
906 if (has_spaces) this_s.resize(dest - this_s.begin());
920 template <
typename T>
923 template <
typename Iterator,
typename Attribute>
930 if (*first !=
'n' && *first !=
'N')
934 if (boost::spirit::qi::detail::string_parse(
"nan",
"NAN", first, last, boost::spirit::qi::unused))
936 if (first != last && *first ==
'(')
941 while (++i != last && *i !=
')')
948 attr_ = std::numeric_limits<T>::quiet_NaN();
957 static boost::spirit::qi::real_parser<double, real_policies_NANfixed_<double> >
parse_double_;
958 static boost::spirit::qi::real_parser<float, real_policies_NANfixed_<float> >
parse_float_;