Home  · Classes  · Annotated Classes  · Modules  · Members  · Namespaces  · Related Pages
StringUtils.h
Go to the documentation of this file.
1 // --------------------------------------------------------------------------
2 // OpenMS -- Open-Source Mass Spectrometry
3 // --------------------------------------------------------------------------
4 // Copyright The OpenMS Team -- Eberhard Karls University Tuebingen,
5 // ETH Zurich, and Freie Universitaet Berlin 2002-2017.
6 //
7 // This software is released under a three-clause BSD license:
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of any author or any participating institution
14 // may be used to endorse or promote products derived from this software
15 // without specific prior written permission.
16 // For a full list of authors, refer to the file AUTHORS.
17 // --------------------------------------------------------------------------
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 // ARE DISCLAIMED. IN NO EVENT SHALL ANY OF THE AUTHORS OR THE CONTRIBUTING
22 // INSTITUTIONS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 //
30 // --------------------------------------------------------------------------
31 // $Maintainer: Timo Sachsenberg, Chris Bielow $
32 // $Authors: Marc Sturm, Stephan Aiche, Chris Bielow $
33 // --------------------------------------------------------------------------
34 
35 #ifndef OPENMS_DATASTRUCTURES_STRINGUTILS_H
36 #define OPENMS_DATASTRUCTURES_STRINGUTILS_H
37 
38 #include <OpenMS/CONCEPT/Types.h>
42 
43 #include <QtCore/QString>
44 #include <boost/spirit/include/qi.hpp>
45 
46 #include <string>
47 #include <vector>
48 
49 
50 namespace OpenMS
51 {
52  class String;
53 
54  namespace StringConversions
55  {
56 
58  template <typename T>
59  inline String floatToString(T f)
60  {
61  std::stringstream s;
62  s.precision(writtenDigits(f));
63  s << f;
64  return s.str();
65  }
66 
68  template <typename T>
69  inline String toString(T i)
70  {
71  std::stringstream s;
72  s << i;
73  return s.str();
74  }
75 
76  template <>
77  inline String toString<const char>(const char c)
78  {
79  return std::string(1,c);
80  }
81 
82  template <>
83  inline String toString(const std::string& s)
84  {
85  return s;
86  }
87 
88  template <>
89  inline String toString(const char* s)
90  {
91  return std::string(s);
92  }
93 
94  template <>
95  inline String toString(float f)
96  {
97  return floatToString(f);
98  }
99 
100  template <>
101  inline String toString(double f)
102  {
103  return floatToString(f);
104  }
105 
106  template <>
107  inline String toString(long double f)
108  {
109  return floatToString(f);
110  }
111 
112  template <>
113  inline String toString(const DataValue& d)
114  {
115  return d.toString();
116  }
117 
119  inline String toString()
120  {
121  return String();
122  }
123 
124  inline String toString(const char* s, size_t length)
125  {
126  String res;
127  size_t count = 0;
128  while (count < length && *(s + count) != 0)
129  {
130  res += *(s + count);
131  ++count;
132  }
133  return res;
134  }
135  }
136 
137  class OPENMS_DLLAPI StringUtils
138  {
139 
140 public:
141 
142  //
144  //
145  static String numberLength(double d, UInt n)
146  {
147  std::stringstream s;
148  //reserve one space for the minus sign
149  Int sign = 0;
150  if (d < 0)
151  sign = 1;
152  d = fabs(d);
153 
154  if (d < pow(10.0, Int(n - sign - 2)))
155  {
156  s.precision(writtenDigits(d));
157  if (sign == 1)
158  s << "-";
159  s << d;
160  }
161  else
162  {
163  UInt exp = 0;
164  while (d > pow(10.0, Int(n - sign - 4)))
165  {
166  d /= 10;
167  ++exp;
168  }
169  d = Int(d) / 10.0;
170  exp += 1;
171  if (sign == 1)
172  s << "-";
173  s << d << "e";
174  if (exp < 10)
175  s << "0";
176  s << exp;
177  }
178  return s.str().substr(0, n);
179  }
180 
181  static String number(double d, UInt n)
182  {
183  return QString::number(d, 'f', n);
184  }
185 
186  static String& fillLeft(String & this_s, char c, UInt size)
187  {
188  if (this_s.size() < size)
189  {
190  this_s.std::string::operator=(String(size - this_s.size(), c) + this_s);
191  }
192  return this_s;
193  }
194 
195  static String& fillRight(String & this_s, char c, UInt size)
196  {
197  if (this_s.size() < size)
198  {
199  this_s.std::string::operator=(this_s + String(size - this_s.size(), c));
200  }
201  return this_s;
202  }
203 
204  /*
206  static String toString(const char * s, size_t length)
207  {
208  std::string res;
209  size_t count = 0;
210  while (count < length && *(s + count) != 0)
211  {
212  res += *(s + count);
213  ++count;
214  }
215  return String(res);
216  }
217 
219  static String toString(size_t len, char c)
220  {
221  return String(std::string(len, c));
222  }
223  */
224 
225  static bool hasPrefix(const String & this_s, const String & string)
226  {
227  if (string.size() > this_s.size())
228  {
229  return false;
230  }
231  if (string.empty())
232  {
233  return true;
234  }
235  return this_s.compare(0, string.size(), string) == 0;
236  }
237 
238  static bool hasSuffix(const String & this_s, const String& string)
239  {
240  if (string.size() > this_s.size())
241  {
242  return false;
243  }
244  if (string.empty())
245  {
246  return true;
247  }
248  return this_s.compare(this_s.size() - string.size(), string.size(), string) == 0;
249  }
250 
251  static bool hasSubstring(const String & this_s, const String& string)
252  {
253  return this_s.find(string) != std::string::npos;
254  }
255 
256  static bool has(const String & this_s, Byte byte)
257  {
258  return this_s.find(char(byte)) != std::string::npos;
259  }
260 
261  static String prefix(const String & this_s, size_t length)
262  {
263  if (length > this_s.size())
264  {
265  throw Exception::IndexOverflow(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, length, this_s.size());
266  }
267  return this_s.substr(0, length);
268  }
269 
270  static String suffix(const String & this_s, size_t length)
271  {
272  if (length > this_s.size())
273  {
274  throw Exception::IndexOverflow(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, length, this_s.size());
275  }
276  return this_s.substr(this_s.size() - length, length);
277  }
278 
279  static String prefix(const String & this_s, Int length)
280  {
281  if (length < 0)
282  {
283  throw Exception::IndexUnderflow(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, length, 0);
284  }
285  if (length > Int(this_s.size()))
286  {
287  throw Exception::IndexOverflow(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, length, this_s.size());
288  }
289  return this_s.substr(0, length);
290  }
291 
292  static String suffix(const String & this_s, Int length)
293  {
294  if (length < 0)
295  {
296  throw Exception::IndexUnderflow(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, length, 0);
297  }
298  if (length > Int(this_s.size()))
299  {
300  throw Exception::IndexOverflow(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, length, this_s.size());
301  }
302  return this_s.substr(this_s.size() - length, length);
303  }
304 
305  static String prefix(const String & this_s, char delim)
306  {
307  Size pos = this_s.find(delim);
308  if (pos == std::string::npos) //char not found
309  {
310  throw Exception::ElementNotFound(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
311  String(delim));
312  }
313  return this_s.substr(0, pos);
314  }
315 
316  static String suffix(const String & this_s, char delim)
317  {
318  Size pos = this_s.rfind(delim);
319  if (pos == std::string::npos) //char not found
320  {
321  throw Exception::ElementNotFound(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
322  String(delim));
323  }
324  return this_s.substr(++pos);
325  }
326 
327  static String substr(const String & this_s, size_t pos, size_t n)
328  {
329  Size begin = std::min(pos, this_s.size());
330  return static_cast<String>(this_s.std::string::substr(begin, n));
331  }
332 
333  static String chop(const String & this_s, Size n)
334  {
335  Size end = 0;
336  if (n < this_s.size())
337  {
338  end = this_s.size() - n;
339  }
340  return String(this_s.begin(), this_s.begin() + end);
341  }
342 
343  static String& trim(String & this_s)
344  {
345  //search for the begin of truncated string
346  std::string::iterator begin = this_s.begin();
347  while (begin != this_s.end() && (*begin == ' ' || *begin == '\t' || *begin == '\n' || *begin == '\r'))
348  {
349  ++begin;
350  }
351 
352  //all characters are whitespaces
353  if (begin == this_s.end())
354  {
355  this_s.clear();
356  return this_s;
357  }
358 
359  //search for the end of truncated string
360  std::string::iterator end = this_s.end();
361  end--;
362  while (end != begin && (*end == ' ' || *end == '\n' || *end == '\t' || *end == '\r'))
363  {
364  --end;
365  }
366  ++end;
367 
368  //no characters are whitespaces
369  if (begin == this_s.begin() && end == this_s.end())
370  {
371  return this_s;
372  }
373 
374  // TODO:
375  // string::operator=(std::string(begin, end));
376  this_s.std::string::operator=(std::string(begin, end));
377 
378  return this_s;
379  }
380 
381  static String& quote(String & this_s, char q, String::QuotingMethod method)
382  {
383  if (method == String::ESCAPE)
384  {
385  this_s.substitute(String("\\"), String("\\\\"));
386  this_s.substitute(String(q), "\\" + String(q));
387  }
388  else if (method == String::DOUBLE)
389  this_s.substitute(String(q), String(q) + String(q));
390  this_s.std::string::operator=(q + this_s + q);
391  return this_s;
392  }
393 
394  static String& unquote(String & this_s, char q, String::QuotingMethod method)
395  {
396  // check if input string matches output format of the "quote" method:
397  if ((this_s.size() < 2) || (this_s[0] != q) || (this_s[this_s.size() - 1] != q))
398  {
400  __FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
401  "'" + this_s + "' does not have the expected format of a quoted string");
402  }
403  this_s.std::string::operator=(this_s.substr(1, this_s.size() - 2)); // remove quotation marks
404  if (method == String::ESCAPE)
405  {
406  this_s.substitute("\\" + String(q), String(q));
407  this_s.substitute(String("\\\\"), String("\\"));
408  }
409  else if (method == String::DOUBLE)
410  this_s.substitute(String(q) + String(q), String(q));
411  return this_s;
412  }
413 
414  static String& simplify(String & this_s)
415  {
416  String simple;
417 
418  bool last_was_whitespace = false;
419  for (std::string::iterator it = this_s.begin(); it != this_s.end(); ++it)
420  {
421  if (*it == ' ' || *it == '\n' || *it == '\t' || *it == '\r')
422  {
423  if (!last_was_whitespace)
424  {
425  simple += ' ';
426  }
427  last_was_whitespace = true;
428  }
429  else
430  {
431  simple += *it;
432  last_was_whitespace = false;
433  }
434  }
435 
436  this_s.swap(simple);
437  return this_s;
438  }
439 
440  static String random(UInt length)
441  {
442  srand(time(0));
443  String tmp(length, '.');
444  size_t random;
445  for (Size i = 0; i < length; ++i)
446  {
447  random = static_cast<size_t>(floor((static_cast<double>(rand()) / (double(RAND_MAX) + 1)) * 62.0));
448  if (random < 10)
449  {
450  tmp[i] = static_cast<char>(random + 48);
451  }
452  else if (random < 36)
453  {
454  tmp[i] = static_cast<char>(random + 55);
455  }
456  else
457  {
458  tmp[i] = static_cast<char>(random + 61);
459  }
460  }
461  return tmp;
462  }
463 
464  static String& reverse(String & this_s)
465  {
466  String tmp = this_s;
467  for (Size i = 0; i != this_s.size(); ++i)
468  {
469  this_s[i] = tmp[this_s.size() - 1 - i];
470  }
471  return this_s;
472  }
473 
474  static bool split(const String & this_s, const char splitter, std::vector<String>& substrings,
475  bool quote_protect)
476  {
477  substrings.clear();
478  if (this_s.empty())
479  return false;
480 
481  Size nsplits = count(this_s.begin(), this_s.end(), splitter);
482 
483  if (!quote_protect && (nsplits == 0))
484  {
485  substrings.push_back(this_s);
486  return false;
487  }
488 
489  // splitter(s) found
490  substrings.reserve(nsplits + 1);
491 
492  // why is "this_s." needed here?
493  std::string::const_iterator begin = this_s.begin();
494  std::string::const_iterator end = this_s.begin();
495 
496  if (quote_protect)
497  {
498  Int quote_count(0);
499  for (; end != this_s.end(); ++end)
500  {
501  if (*end == '"')
502  {
503  ++quote_count;
504  }
505  if ((quote_count % 2 == 0) && (*end == splitter))
506  {
507  String block = String(begin, end);
508  block.trim();
509  if ((block.size() >= 2) && ((block.prefix(1) == String("\"")) ^
510  (block.suffix(1) == String("\""))))
511  { // block has start or end quote, but not both
512  // (one quote is somewhere in the middle)
514  __FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
515  String("Could not dequote string '") + block +
516  "' due to wrongly placed '\"'.");
517  }
518  else if ((block.size() >= 2) && (block.prefix(1) == String("\"")) &&
519  (block.suffix(1) == String("\"")))
520  { // block has start and end quotes --> remove them
521  block = block.substr(1, block.size() - 2);
522  }
523  substrings.push_back(block);
524  begin = end + 1;
525  }
526  }
527  // no valid splitter found - return empty list
528  if (substrings.empty())
529  {
530  substrings.push_back(this_s);
531  return false;
532  }
533 
534  String block = String(begin, end);
535  block.trim();
536  if ((block.size() >= 2) && ((block.prefix(1) == String("\"")) ^
537  (block.suffix(1) == String("\""))))
538  { // block has start or end quote but not both
539  // (one quote is somewhere in the middle)
541  __FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
542  String("Could not dequote string '") + block +
543  "' due to wrongly placed '\"'.");
544  }
545  else if ((block.size() >= 2) && (block.prefix(1) == String("\"")) &&
546  (block.suffix(1) == String("\"")))
547  { // block has start and end quotes --> remove them
548  block = block.substr(1, block.size() - 2);
549  }
550  substrings.push_back(block);
551  }
552  else // do not honor quotes
553  {
554  for (; end != this_s.end(); ++end)
555  {
556  if (*end == splitter)
557  {
558  substrings.push_back(String(begin, end));
559  begin = end + 1;
560  }
561  }
562  substrings.push_back(String(begin, end));
563  }
564 
565  // at this point we are sure that there are at least two components
566  return true;
567  }
568 
569  static bool split(const String & this_s, const String& splitter, std::vector<String>& substrings)
570  {
571  substrings.clear();
572  if (this_s.empty())
573  return false;
574 
575  if (splitter.empty()) // split after every character:
576  {
577  substrings.resize(this_s.size());
578  for (Size i = 0; i < this_s.size(); ++i)
579  substrings[i] = this_s[i];
580  return true;
581  }
582 
583  Size len = splitter.size(), start = 0, pos = this_s.find(splitter);
584  if (len == 0)
585  len = 1;
586  while (pos != std::string::npos)
587  {
588  substrings.push_back(this_s.substr(start, pos - start));
589  start = pos + len;
590  pos = this_s.find(splitter, start);
591  }
592  substrings.push_back(this_s.substr(start, this_s.size() - start));
593  return substrings.size() > 1;
594  }
595 
596  static bool split_quoted(const String & this_s, const String& splitter, std::vector<String>& substrings,
597  char q, String::QuotingMethod method)
598  {
599  substrings.clear();
600  if (this_s.empty() || splitter.empty())
601  return false;
602 
603  bool in_quote = false;
604  char targets[2] = {q, splitter[0]}; // targets for "find_first_of"
605  std::string rest = splitter.substr(1, splitter.size() - 1);
606  Size start = 0;
607  for (Size i = 0; i < this_s.size(); ++i)
608  {
609  if (in_quote) // skip to closing quotation mark
610  {
611  bool embedded = false;
612  if (method == String::ESCAPE)
613  {
614  for (; i < this_s.size(); ++i)
615  {
616  if (this_s[i] == '\\')
617  embedded = !embedded;
618  else if ((this_s[i] == q) && !embedded)
619  break;
620  else
621  embedded = false;
622  }
623  }
624  else // method: NONE or DOUBLE
625  {
626  for (; i < this_s.size(); ++i)
627  {
628  if (this_s[i] == q)
629  {
630  if (method == String::NONE)
631  break; // found
632  // next character is also closing quotation mark:
633  if ((i < this_s.size() - 1) && (this_s[i + 1] == q))
634  embedded = !embedded;
635  // even number of subsequent quotes (doubled) => found
636  else if (!embedded)
637  break;
638  // odd number of subsequent quotes => belongs to a pair
639  else
640  embedded = false;
641  }
642  }
643  }
644  in_quote = false; // end of quote reached
645  }
646  else
647  {
648  i = this_s.find_first_of(targets, i, 2);
649  if (i == std::string::npos)
650  break; // nothing found
651  if (this_s[i] == q)
652  in_quote = true;
653  else if (this_s.compare(i + 1, rest.size(), rest) == 0) // splitter found
654  {
655  substrings.push_back(this_s.substr(start, i - start));
656  start = i + splitter.size();
657  i = start - 1; // increased by loop
658  }
659  }
660  }
661  if (in_quote) // reached end without finding closing quotation mark
662  {
664  __FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
665  "unbalanced quotation marks in string '" + this_s + "'");
666  }
667  substrings.push_back(this_s.substr(start, this_s.size() - start));
668  return substrings.size() > 1;
669  }
670 
671  static QString toQString(const String & this_s)
672  {
673  return QString(this_s.c_str());
674  }
675 
676  static Int toInt(const String & this_s)
677  {
678  Int ret;
679 
680  // boost::spirit::qi was found to be vastly superior to boost::lexical_cast or stringstream extraction (especially for VisualStudio),
681  // so don't change this unless you have benchmarks for all platforms!
682  String::ConstIterator it = this_s.begin();
683  if (!boost::spirit::qi::phrase_parse(it, this_s.end(), boost::spirit::qi::int_, boost::spirit::ascii::space, ret))
684  {
685  throw Exception::ConversionError(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, String("Could not convert string '") + this_s + "' to an integer value");
686  }
687  // was the string parsed (white spaces are skipped automatically!) completely? If not, we have a problem because a previous split might have used the wrong split char
688  if (it != this_s.end())
689  {
690  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));
691  }
692  return ret;
693  }
694 
695  static float toFloat(const String& this_s)
696  {
697  float ret;
698 
699  // boost::spirit::qi was found to be vastly superior to boost::lexical_cast or stringstream extraction (especially for VisualStudio),
700  // so don't change this unless you have benchmarks for all platforms!
701  String::ConstIterator it = this_s.begin();
702  if (!boost::spirit::qi::phrase_parse(it, this_s.end(), parse_float_, boost::spirit::ascii::space, ret))
703  {
704  throw Exception::ConversionError(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, String("Could not convert string '") + this_s + "' to a float value");
705  }
706  // was the string parsed (white spaces are skipped automatically!) completely? If not, we have a problem because a previous split might have used the wrong split char
707  if (it != this_s.end())
708  {
709  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));
710  }
711  return ret;
712  }
713 
714  static double toDouble(const String& this_s)
715  {
716  double ret;
717  // boost::spirit::qi was found to be vastly superior to boost::lexical_cast or stringstream extraction (especially for VisualStudio),
718  // so don't change this unless you have benchmarks for all platforms!
719  String::ConstIterator it = this_s.begin();
720  if (!boost::spirit::qi::phrase_parse(it, this_s.end(), parse_double_, boost::spirit::ascii::space, ret))
721  {
722  throw Exception::ConversionError(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, String("Could not convert string '") + this_s + "' to a double value");
723  }
724  // was the string parsed (white spaces are skipped automatically!) completely? If not, we have a problem because a previous split might have used the wrong split char
725  if (it != this_s.end())
726  {
727  throw Exception::ConversionError(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, String("Prefix of string '") + this_s + "' successfully converted to a double value. Additional characters found at position " + (int)(distance(this_s.begin(), it) + 1));
728  }
729  return ret;
730  }
731 
732 
733  static String& toUpper(String & this_s)
734  {
735  std::transform(this_s.begin(), this_s.end(), this_s.begin(), (int (*)(int))toupper);
736  return this_s;
737  }
738 
739  static String& firstToUpper(String & this_s)
740  {
741  if (this_s.size() != 0)
742  {
743  this_s[0] = toupper(this_s[0]);
744  }
745  return this_s;
746  }
747 
748  static String& toLower(String & this_s)
749  {
750  std::transform(this_s.begin(), this_s.end(), this_s.begin(), (int (*)(int))tolower);
751  return this_s;
752  }
753 
754  static String& substitute(String & this_s, char from, char to)
755  {
756  std::replace(this_s.begin(), this_s.end(), from, to);
757  return this_s;
758  }
759 
760  static String& substitute(String & this_s, const String& from, const String& to)
761  {
762  if (!from.empty())
763  {
764  std::vector<String> parts;
765  this_s.split(from, parts);
766  this_s.concatenate(parts.begin(), parts.end(), to);
767  }
768  return this_s;
769  }
770 
771  static String& remove(String & this_s, char what)
772  {
773  this_s.erase(std::remove(this_s.begin(), this_s.end(), what), this_s.end());
774  return this_s;
775  }
776 
777  static String& ensureLastChar(String & this_s, char end)
778  {
779  if (!this_s.hasSuffix(end))
780  this_s.append(1, end);
781  return this_s;
782  }
783 
784  static String& removeWhitespaces(String & this_s)
785  {
786  bool contains_ws = false;
787  for (std::string::const_iterator it = this_s.begin(); it != this_s.end(); ++it)
788  {
789  char c = *it;
790  if (c == ' ' || c == '\t' || c == '\n' || c == '\r')
791  {
792  contains_ws = true;
793  break;
794  }
795  }
796 
797  if (contains_ws)
798  {
799  std::string tmp;
800  tmp.reserve(this_s.size());
801  for (std::string::const_iterator it = this_s.begin(); it != this_s.end(); ++it)
802  {
803  char c = *it;
804  if (c != ' ' && c != '\t' && c != '\n' && c != '\r')
805  tmp += c;
806  }
807  this_s.swap(tmp);
808  }
809 
810  return this_s;
811  }
812 
813  private:
814 
815  /*
816  @brief A fixed Boost:pi real parser policy, capable of dealing with 'nan' without crashing
817 
818  The original Boost implementation has a bug, see https://svn.boost.org/trac/boost/ticket/6955.
819  Can be removed if Boost 1.60 or above is required
820 
821  */
822  template <typename T>
823  struct real_policies_NANfixed_ : boost::spirit::qi::real_policies<T>
824  {
825  template <typename Iterator, typename Attribute>
826  static bool
827  parse_nan(Iterator& first, Iterator const& last, Attribute& attr_)
828  {
829  if (first == last)
830  return false; // end of input reached
831 
832  if (*first != 'n' && *first != 'N')
833  return false; // not "nan"
834 
835  // nan[(...)] ?
836  if (boost::spirit::qi::detail::string_parse("nan", "NAN", first, last, boost::spirit::qi::unused))
837  {
838  if (first != last && *first == '(') /* this check is broken in boost 1.49 - (at least) 1.54; fixed in 1.60 */
839  {
840  // skip trailing (...) part
841  Iterator i = first;
842 
843  while (++i != last && *i != ')')
844  ;
845  if (i == last)
846  return false; // no trailing ')' found, give up
847 
848  first = ++i;
849  }
850  attr_ = std::numeric_limits<T>::quiet_NaN();
851  return true;
852  }
853  return false;
854  }
855  };
856 
857  // Qi parsers using the 'real_policies_NANfixed_' template which allows for 'nan'
858  // (the original Boost implementation has a bug, see https://svn.boost.org/trac/boost/ticket/6955)
859  static boost::spirit::qi::real_parser<double, real_policies_NANfixed_<double> > parse_double_;
860  static boost::spirit::qi::real_parser<float, real_policies_NANfixed_<float> > parse_float_;
861 
862  };
863 
864 } // namespace OPENMS
865 
866 #endif // OPENMS_DATASTRUCTURES_STRINGUTILS_H
static bool split(const String &this_s, const String &splitter, std::vector< String > &substrings)
Definition: StringUtils.h:569
static boost::spirit::qi::real_parser< float, real_policies_NANfixed_< float > > parse_float_
Definition: StringUtils.h:860
Int underflow exception.
Definition: Exception.h:217
static String numberLength(double d, UInt n)
Functions.
Definition: StringUtils.h:145
static String & fillRight(String &this_s, char c, UInt size)
Definition: StringUtils.h:195
A more convenient string class.
Definition: String.h:57
static String number(double d, UInt n)
Definition: StringUtils.h:181
Definition: StringUtils.h:137
Element could not be found exception.
Definition: Exception.h:663
static String & fillLeft(String &this_s, char c, UInt size)
Definition: StringUtils.h:186
static bool hasPrefix(const String &this_s, const String &string)
Definition: StringUtils.h:225
Int overflow exception.
Definition: Exception.h:255
String floatToString(T f)
toString functions (for floating point types)
Definition: StringUtils.h:59
Definition: String.h:80
unsigned int UInt
Unsigned integer type.
Definition: Types.h:95
Int writtenDigits(const FloatingPointType &=FloatingPointType())
Number of digits commonly used for writing a floating point type (a.k.a. precision). Specializations are defined for float, double, long double.
Definition: Types.h:295
static String & removeWhitespaces(String &this_s)
Definition: StringUtils.h:784
static QString toQString(const String &this_s)
Definition: StringUtils.h:671
void concatenate(StringIterator first, StringIterator last, const String &glue="")
Concatenates all elements from first to last-1 and inserts glue between the elements.
Definition: String.h:458
const double c
Main OpenMS namespace.
Definition: FeatureDeconvolution.h:47
static String & trim(String &this_s)
Definition: StringUtils.h:343
static String & substitute(String &this_s, char from, char to)
Definition: StringUtils.h:754
String toString() const
Conversion to String.
static String suffix(const String &this_s, Int length)
Definition: StringUtils.h:292
static double toDouble(const String &this_s)
Definition: StringUtils.h:714
Class to hold strings, numeric values, lists of strings and lists of numeric values.
Definition: DataValue.h:57
static bool split(const String &this_s, const char splitter, std::vector< String > &substrings, bool quote_protect)
Definition: StringUtils.h:474
String substr(size_t pos=0, size_t n=npos) const
Wrapper for the STL substr() method. Returns a String object with its contents initialized to a subst...
static bool split_quoted(const String &this_s, const String &splitter, std::vector< String > &substrings, char q, String::QuotingMethod method)
Definition: StringUtils.h:596
static boost::spirit::qi::real_parser< double, real_policies_NANfixed_< double > > parse_double_
Definition: StringUtils.h:859
QuotingMethod
How to handle embedded quotes when quoting strings.
Definition: String.h:80
const_iterator ConstIterator
Const Iterator.
Definition: String.h:71
static bool parse_nan(Iterator &first, Iterator const &last, Attribute &attr_)
Definition: StringUtils.h:827
static String prefix(const String &this_s, char delim)
Definition: StringUtils.h:305
static String & toLower(String &this_s)
Definition: StringUtils.h:748
String suffix(SizeType length) const
returns the suffix of length length
static String random(UInt length)
Definition: StringUtils.h:440
static String substr(const String &this_s, size_t pos, size_t n)
Definition: StringUtils.h:327
static String prefix(const String &this_s, Int length)
Definition: StringUtils.h:279
Definition: String.h:80
String & trim()
removes whitespaces (space, tab, line feed, carriage return) at the beginning and the end of the stri...
static String suffix(const String &this_s, size_t length)
Definition: StringUtils.h:270
static bool hasSubstring(const String &this_s, const String &string)
Definition: StringUtils.h:251
static String chop(const String &this_s, Size n)
Definition: StringUtils.h:333
static String & toUpper(String &this_s)
Definition: StringUtils.h:733
static String & substitute(String &this_s, const String &from, const String &to)
Definition: StringUtils.h:760
static String & ensureLastChar(String &this_s, char end)
Definition: StringUtils.h:777
static String & quote(String &this_s, char q, String::QuotingMethod method)
Definition: StringUtils.h:381
Invalid conversion exception.
Definition: Exception.h:363
static String & firstToUpper(String &this_s)
Definition: StringUtils.h:739
static bool has(const String &this_s, Byte byte)
Definition: StringUtils.h:256
Definition: String.h:80
static String & reverse(String &this_s)
Definition: StringUtils.h:464
static String suffix(const String &this_s, char delim)
Definition: StringUtils.h:316
size_t Size
Size type e.g. used as variable which can hold result of size()
Definition: Types.h:128
static float toFloat(const String &this_s)
Definition: StringUtils.h:695
static String & unquote(String &this_s, char q, String::QuotingMethod method)
Definition: StringUtils.h:394
String & substitute(char from, char to)
Replaces all occurrences of the character from by the character to.
String prefix(SizeType length) const
returns the prefix of length length
OPENMS_BYTE_TYPE Byte
Byte type.
Definition: Types.h:112
static String prefix(const String &this_s, size_t length)
Definition: StringUtils.h:261
static String & simplify(String &this_s)
Definition: StringUtils.h:414
String toString(T i)
toString functions (single argument)
Definition: StringUtils.h:69
int Int
Signed integer type.
Definition: Types.h:103
bool split(const char splitter, std::vector< String > &substrings, bool quote_protect=false) const
Splits a string into substrings using splitter as delimiter.
static Int toInt(const String &this_s)
Definition: StringUtils.h:676
String toString< const char >(const char c)
Definition: StringUtils.h:77
bool hasSuffix(const String &string) const
true if String ends with string, false otherwise
static bool hasSuffix(const String &this_s, const String &string)
Definition: StringUtils.h:238

OpenMS / TOPP release 2.3.0 Documentation generated on Tue Jan 9 2018 18:22:04 using doxygen 1.8.13