StringUtils.hpp
Go to the documentation of this file.
1 //==============================================================================
2 //
3 // This file is part of GNSSTk, the ARL:UT GNSS Toolkit.
4 //
5 // The GNSSTk is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published
7 // by the Free Software Foundation; either version 3.0 of the License, or
8 // any later version.
9 //
10 // The GNSSTk is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with GNSSTk; if not, write to the Free Software Foundation,
17 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
18 //
19 // This software was developed by Applied Research Laboratories at the
20 // University of Texas at Austin.
21 // Copyright 2004-2022, The Board of Regents of The University of Texas System
22 //
23 //==============================================================================
24 
25 //==============================================================================
26 //
27 // This software was developed by Applied Research Laboratories at the
28 // University of Texas at Austin, under contract to an agency or agencies
29 // within the U.S. Department of Defense. The U.S. Government retains all
30 // rights to use, duplicate, distribute, disclose, or release this software.
31 //
32 // Pursuant to DoD Directive 523024
33 //
34 // DISTRIBUTION STATEMENT A: This software has been approved for public
35 // release, distribution is unlimited.
36 //
37 //==============================================================================
38 
44 #ifndef GNSSTK_STRINGUTILS_HPP
45 #define GNSSTK_STRINGUTILS_HPP
46 
47 #include <string>
48 #include <sstream>
49 #include <iomanip>
50 #include <iostream>
51 #include <list>
52 #include <vector>
53 #include <cstdio>
54 #include <cctype>
55 #include <limits>
56 
57 #ifdef _WIN32
58 #if _MSC_VER < 1700
59 // For lower version of visual studio 2012 use gnu regex
60 #include <regex.h>
61 #pragma comment(lib, "regex.lib")
62 #else
63 // visual studio 2012 support c++ 0x, and we use std::regex
64 #include <regex>
65 #endif
66 #else
67 // TODO: we should use std::regex for upper than g++ 4.6
68 #include <regex.h>
69 #endif
70 
71 #include "Exception.hpp"
72 #include "HexDumpDataConfig.hpp"
73 
74 namespace gnsstk
75 {
95  namespace StringUtils
96  {
97  // Most of the functionality here is inlined since they are
98  // fairly small functions.
99 
101 
102 
106  NEW_EXCEPTION_CLASS(StringException, Exception);
107 
109  enum class FFLead
110  {
111  Zero,
112  Decimal,
113  NonZero
114  };
115 
117  enum class FFSign
118  {
119  NegOnly,
120  NegSpace,
121  NegPos
122  };
123 
125  enum class FFAlign
126  {
127  Left,
128  Right
129  };
130 
142  void hexDumpData(const std::string& data,
143  std::ostream& s,
145 
158  inline void hexDumpData(std::ostream& s,
159  const std::string& data,
160  unsigned indent = 0,
162 
175  inline void hexDumpData(std::ostream& s,
176  const std::string& data,
177  const std::string& tag,
179 
190  inline
191  std::string& stripLeading(std::string& s,
192  const std::string& aString,
193  std::string::size_type num = std::string::npos);
194 
205  inline std::string stripLeading(const std::string& s,
206  const std::string& aString,
207  std::string::size_type num = std::string::npos)
208  { std::string t(s); stripLeading(t, aString, num); return t; }
209 
220  inline std::string& stripLeading(std::string& s,
221  const char* pString,
222  std::string::size_type num = std::string::npos)
223  { return stripLeading(s, std::string(pString), num); }
224 
235  inline std::string stripLeading(const std::string& s,
236  const char* pString,
237  std::string::size_type num = std::string::npos)
238  { std::string t(s); stripLeading(t, std::string(pString), num); return t; }
239 
250  inline std::string& stripLeading(std::string& s,
251  const char aCharacter,
252  std::string::size_type num = std::string::npos)
253  { return stripLeading(s, std::string(1,aCharacter), num); }
254 
265  inline std::string stripLeading(const std::string& s,
266  const char aCharacter,
267  std::string::size_type num = std::string::npos)
268  { std::string t(s); stripLeading(t, std::string(1,aCharacter), num); return t; }
269 
279  inline std::string& stripLeading(std::string& s,
280  std::string::size_type num = std::string::npos)
281  { return stripLeading(s,std::string(1,' '),num); }
282 
292  inline std::string stripLeading(const std::string& s,
293  std::string::size_type num = std::string::npos)
294  { std::string t(s); stripLeading(t,std::string(1,' '),num); return t; }
295 
306  inline std::string& stripTrailing(std::string& s,
307  const std::string& aString,
308  std::string::size_type num = std::string::npos);
309 
320  inline std::string stripTrailing(const std::string& s,
321  const std::string& aString,
322  std::string::size_type num = std::string::npos)
323  { std::string t(s); stripTrailing(t, aString, num); return t;}
324 
335  inline std::string& stripTrailing(std::string& s,
336  const char* pString,
337  std::string::size_type num = std::string::npos)
338  { return stripTrailing(s, std::string(pString), num); }
339 
350  inline std::string stripTrailing(const std::string& s,
351  const char* pString,
352  std::string::size_type num = std::string::npos)
353  { std::string t(s); stripTrailing(t, std::string(pString), num); return t; }
354 
365  inline std::string& stripTrailing(std::string& s,
366  const char aCharacter,
367  std::string::size_type num = std::string::npos)
368  { return stripTrailing(s, std::string(1,aCharacter), num); }
369 
380  inline std::string stripTrailing(const std::string& s,
381  const char aCharacter,
382  std::string::size_type num = std::string::npos)
383  { std::string t(s); stripTrailing(t, std::string(1,aCharacter), num); return t; }
384 
394  inline std::string& stripTrailing(std::string& s,
395  std::string::size_type num = std::string::npos)
396  { return stripTrailing(s, std::string(1,' '), num); }
397 
407  inline std::string stripTrailing(const std::string& s,
408  std::string::size_type num = std::string::npos)
409  { std::string t(s); stripTrailing(t, std::string(1,' '), num); return t;}
410 
421  inline std::string& strip(std::string& s,
422  const std::string& aString,
423  std::string::size_type num = std::string::npos);
424 
425 
436  inline std::string strip(const std::string& s,
437  const std::string& aString,
438  std::string::size_type num = std::string::npos)
439  { std::string t(s); strip(t, aString, num); return t; }
440 
441 
452  inline std::string& strip(std::string& s,
453  const char* pString,
454  std::string::size_type num = std::string::npos)
455  { return strip(s, std::string(pString), num); }
456 
467  inline std::string strip(const std::string& s,
468  const char* pString,
469  std::string::size_type num = std::string::npos)
470  { std::string t(s); strip(t, std::string(pString), num); return t; }
471 
482  inline std::string& strip(std::string& s,
483  const char aCharacter,
484  std::string::size_type num = std::string::npos)
485  { return strip(s, std::string(1,aCharacter), num); }
486 
497  inline std::string strip(const std::string& s,
498  const char aCharacter,
499  std::string::size_type num = std::string::npos)
500  { std::string t(s); strip(t, std::string(1,aCharacter), num); return t;}
501 
511  inline std::string& strip(std::string& s,
512  std::string::size_type num = std::string::npos)
513  { return strip(s, std::string(1, ' '), num); }
514 
524  inline std::string strip(const std::string& s,
525  std::string::size_type num = std::string::npos)
526  { std::string t(s); strip(t, std::string(1, ' '), num); return t;}
527 
539  inline std::string translate(const std::string& aString,
540  const std::string& inputChars,
541  const std::string& outputChars,
542  const char pad = ' ');
543 
563  inline std::string change(const std::string& aString,
564  const std::string& inputString,
565  const std::string& outputString,
566  std::string::size_type startPos = 0,
567  unsigned numChanges = (std::numeric_limits<unsigned>().max()));
568 
588  inline std::string& change(std::string& aString,
589  const std::string& inputString,
590  const std::string& outputString,
591  std::string::size_type startPos = 0,
592  unsigned numChanges = (std::numeric_limits<unsigned>::max)());
593 
605  inline std::string& rightJustify(std::string& s,
606  const std::string::size_type length,
607  const char pad = ' ');
608 
620  inline std::string rightJustify(const std::string& s,
621  const std::string::size_type length,
622  const char pad = ' ')
623  { std::string t(s); return rightJustify(t, length, pad); }
624 
636  inline std::string& leftJustify(std::string& s,
637  const std::string::size_type length,
638  const char pad = ' ');
639 
651  inline std::string leftJustify(const std::string& s,
652  const std::string::size_type length,
653  const char pad = ' ')
654  { std::string t(s); return leftJustify(t, length, pad); }
655 
673  inline std::string& center(std::string& s,
674  const std::string::size_type length,
675  const char pad = ' ');
676 
695  inline std::string center(const std::string& s,
696  const std::string::size_type length,
697  const char pad = ' ')
698  { std::string t(s); return center(t, length, pad); }
699 
705  inline double asDouble(const std::string& s)
706  { return strtod(s.c_str(), 0); }
707 
713  inline long asInt(const std::string& s)
714  { return strtol(s.c_str(), 0, 10); }
715 
721  inline unsigned long asUnsigned(const std::string& s)
722  { return strtoul(s.c_str(), 0, 10); }
723 
730  inline float asFloat(const std::string& s);
731 
738  inline long double asLongDouble(const std::string& s);
739 
748  template <class X>
749  inline X asData(const std::string& s);
750 
757  inline std::string asString(const long double x,
758  const std::string::size_type precision = 21);
759 
766  inline std::string asString(const double x,
767  const std::string::size_type precision = 17);
768 
775  template <class X>
776  inline std::string asString(const X x);
777 
787  inline std::string& d2x(std::string& s);
788 
799  inline std::string d2x(const std::string& s)
800  { std::string t(s); return d2x(t); }
801 
811  inline std::string& x2d(std::string& s);
812 
823  inline std::string x2d(const std::string& s)
824  { std::string t(s); return x2d(t); }
825 
834  inline std::string& c2x(std::string& s);
835 
842  inline std::string c2x(const std::string& s)
843  { std::string t(s); return c2x(t); }
844 
852  inline unsigned int x2uint(const std::string& s);
853 
860  inline std::string int2x(const unsigned int& i);
861 
870  inline std::string& replaceAll(std::string& s,
871  const std::string& oldString,
872  const std::string& newString );
873 
881  inline bool isDigitString(const std::string& s);
882 
889  inline bool isDecimalString(const std::string& s);
890 
898  inline bool isScientificString(const std::string& s);
899 
907  inline bool isAlphaString(const std::string& s);
908 
926  inline std::string matches(const std::string& s,
927  const std::string& aPattern,
928  const char zeroOrMore = '*',
929  const char oneOrMore = '+',
930  const char anyChar = '.' );
931 
948  inline bool isLike(const std::string& s,
949  const std::string& aPattern,
950  const char zeroOrMore = '*',
951  const char oneOrMore = '+',
952  const char anyChar = '.' )
953  { return matches(s, aPattern, zeroOrMore, oneOrMore, anyChar) !=
954  std::string(); }
955 
956 
973  inline bool isLike(const std::string& s,
974  const char* pPattern,
975  const char zeroOrMore = '*',
976  const char oneOrMore = '+',
977  const char anyChar = '.' )
978  { return matches(s, std::string(pPattern),
979  zeroOrMore, oneOrMore, anyChar) != std::string(); }
980 
981 
998  template <class T>
999  std::string formattedPrint(const std::string& fmt,
1000  const std::string& pat,
1001  const std::string& rep,
1002  T to);
1003 
1010  inline std::string subString(const std::string& s,
1011  const std::string::size_type startPos = 0,
1012  const std::string::size_type length = std::string::npos,
1013  const char pad = ' ' );
1014 
1021  inline std::string& lowerCase(std::string& s);
1022 
1029  inline std::string lowerCase(const std::string& s)
1030  { std::string t(s); return lowerCase(t); }
1031 
1038  inline std::string& upperCase(std::string& s);
1039 
1046  inline std::string upperCase(const std::string& s)
1047  { std::string t(s); return upperCase(t); }
1048 
1058  inline std::string memToString(const void* p,
1059  const std::string::size_type size);
1060 
1069  inline std::string firstWord(const std::string& s,
1070  const char delimiter = ' ');
1071 
1080  inline int numWords(const std::string& s,
1081  const char delimiter = ' ');
1082 
1096  inline std::string words(const std::string& s,
1097  const std::string::size_type firstWord = 0,
1098  const std::string::size_type numWords = std::string::npos,
1099  const char delimiter = ' ');
1100 
1112  inline std::string word(const std::string& s,
1113  const std::string::size_type wordNum = 0,
1114  const char delimiter = ' ')
1115  { return words(s, wordNum, 1, delimiter); }
1116 
1126  inline std::string stripFirstWord(std::string& s,
1127  const char delimiter = ' ');
1128 
1136  inline std::vector<std::string> split(const std::string& str,
1137  const char delimiter = ' ');
1138 
1155  inline std::string& removeWords(std::string& s,
1156  const std::string::size_type first = 0,
1157  const std::string::size_type wordsToReplace = std::string::npos,
1158  const char delimiter = ' ');
1159 
1173  inline std::string doub2sci(const double& d,
1174  const std::string::size_type length,
1175  const std::string::size_type expLen,
1176  const bool showSign = true,
1177  const bool checkSwitch = true);
1178 
1190  inline std::string doubleToScientific(const double& d,
1191  const std::string::size_type length,
1192  const std::string::size_type precision,
1193  const std::string::size_type explen,
1194  bool showPlus=false);
1195 
1217  inline std::string& sci2for(std::string& aStr,
1218  const std::string::size_type startPos = 0,
1219  const std::string::size_type length = std::string::npos,
1220  const std::string::size_type expLen = 3,
1221  const bool checkSwitch = true);
1222 
1240  inline std::string doub2for(const double& d,
1241  const std::string::size_type length,
1242  const std::string::size_type expLen,
1243  const bool checkSwitch = true);
1244 
1257  inline double for2doub(const std::string& aStr,
1258  const std::string::size_type startPos = 0,
1259  const std::string::size_type length = std::string::npos);
1260 
1287  std::string floatFormat(double d, FFLead lead, unsigned mantissa,
1288  unsigned exponent, unsigned width = 0,
1289  char expChar = 'e',
1290  FFSign sign = FFSign::NegOnly,
1291  FFAlign align = FFAlign::Left);
1292 
1302  inline std::string printable(const std::string& aStr);
1303 
1316  inline std::string& prettyPrint(std::string& aStr,
1317  const std::string& lineDelim = "\n",
1318  const std::string& indent = "",
1319  const std::string& firstIndent = " ",
1320  const std::string::size_type len = 80,
1321  const char wordDelim = ' ');
1322 
1335  inline std::string prettyPrint(const std::string& aStr,
1336  const std::string& lineDelim = "\n",
1337  const std::string& indent = "",
1338  const std::string& firstIndent = " ",
1339  const std::string::size_type len = 80,
1340  const char wordDelim = ' ')
1341  {
1342  std::string temp(aStr);
1343  prettyPrint(temp, lineDelim, indent, firstIndent, len, wordDelim);
1344  return temp;
1345  }
1346 
1358  inline std::string tabularize(const std::vector<std::string>& cells,
1359  std::string::size_type width = 80,
1360  bool force = false);
1361 
1368  inline std::vector<std::string> split(const std::string& aStr,
1369  const std::string& theDelimiters,
1370  bool trimWhitespace = false,
1371  bool ignoreEmpty = true);
1372 
1380  inline std::vector<std::string> splitWithQuotes(const std::string& aStr,
1381  const char delimiter = ' ',
1382  bool trimWhitespace = true,
1383  bool ignoreEmpty = true);
1384 
1392  inline std::vector<std::string> splitWithDoubleQuotes(const std::string& aStr,
1393  const char delimiter = ' ',
1394  bool trimWhitespace = true,
1395  bool ignoreEmpty = true);
1396  } // namespace StringUtils
1397 
1398 } // namespace gnsstk
1399 
1400 // ################################################
1401 // Implementations of inline functions follow
1402 // ################################################
1403 
1404 namespace gnsstk
1405 {
1406 
1407  namespace StringUtils
1408  {
1409  inline void hexDumpData(std::ostream& s, const std::string& data,
1410  unsigned indent, const HexDumpDataConfig& cfg)
1411  {
1412  std::string tagstr(indent, ' ');
1413  hexDumpData(s, data, tagstr, cfg);
1414  }
1415 
1416  inline void hexDumpData(std::ostream& s, const std::string& data,
1417  const std::string& tag,
1419  {
1420  cfg.prefix = tag;
1421  hexDumpData(data, s, cfg);
1422  }
1423 
1424  // Keep searching for aString at the start of s
1425  // until num == 0 or aString is not found at the start of s
1426  inline std::string& stripLeading(std::string& s,
1427  const std::string& aString,
1428  std::string::size_type num)
1429  {
1430  try
1431  {
1432  if (aString == "")
1433  return s;
1434 
1435  while((num > 0) &&
1436  (s.find(aString,0) == 0) &&
1437  (s.length() > 0))
1438  {
1439  s.erase(0,aString.length());
1440  --num;
1441  }
1442  return s;
1443  }
1444  catch(std::exception &e)
1445  {
1446  StringException strexc("Exception thrown: " + std::string(e.what()));
1447  GNSSTK_THROW(strexc);
1448  }
1449  }
1450 
1451  // keep searching for aString at the end of s
1452  // until aString isn't found there or num == 0
1453  inline std::string& stripTrailing(std::string& s,
1454  const std::string& aString,
1455  std::string::size_type num)
1456  {
1457  try
1458  {
1459  // empty string, etc.; cannot let (size_type) pos = negative
1460  if (s.length() < aString.length() || (aString == ""))
1461  return s;
1462 
1463  std::string::size_type pos = s.length() - aString.length();
1464 
1465  while((num > 0) &&
1466  (s.length() >= aString.length()) &&
1467  (s.rfind(aString,pos) == pos))
1468  {
1469  s.erase(pos, std::string::npos);
1470  --num;
1471  pos = s.length() - aString.length();
1472  }
1473  return s;
1474  }
1475  catch(std::exception &e)
1476  {
1477  StringException strexc("Exception thrown: " + std::string(e.what()));
1478  GNSSTK_THROW(strexc);
1479  }
1480  }
1481 
1482  inline std::string& strip(std::string& s,
1483  const std::string& aString,
1484  std::string::size_type num)
1485  {
1486  stripLeading(s, aString, num);
1487  stripTrailing(s, aString, num);
1488  return s;
1489  }
1490 
1491  inline std::string translate(const std::string& aString,
1492  const std::string& inputChars,
1493  const std::string& outputChars,
1494  const char pad)
1495  {
1496  std::string rv = aString;
1497  std::string::size_type aspos = 0;
1498  std::string::size_type inpos = std::string::npos;
1499  char toc = pad;
1500 
1501  // By starting at the last position, we avoid infinite
1502  // loops in case someone did something dumb, like, for
1503  // example, setting inputChars=outputChars.
1504  while ((aspos = rv.find_first_of(inputChars, aspos))
1505  != std::string::npos)
1506  {
1507  // figure out which char we found;
1508  inpos = inputChars.find(rv[aspos]);
1509  if (outputChars.length()-1 < inpos)
1510  toc = pad;
1511  else
1512  toc = outputChars[inpos];
1513  rv[aspos] = toc;
1514 
1515  aspos++; // try to guarantee no infinite loops
1516  }
1517 
1518  return rv;
1519  }
1520 
1521  inline std::string change(const std::string& aString,
1522  const std::string& inputString,
1523  const std::string& outputString,
1524  std::string::size_type startPos, unsigned numChanges)
1525  {
1526  std::string rv(aString);
1527  change(rv, inputString, outputString, startPos, numChanges);
1528  return rv;
1529  }
1530 
1531  inline std::string& change(std::string& aString, const std::string& inputString,
1532  const std::string& outputString,
1533  std::string::size_type startPos, unsigned numChanges)
1534  {
1535  if(inputString.empty() || aString.empty()) return aString;
1536  unsigned count = 0;
1537  std::string::size_type opos = startPos;
1538 
1539  while (count < numChanges)
1540  {
1541  std::string::size_type pos = aString.find(inputString, opos);
1542  if (pos != std::string::npos)
1543  {
1544  count++;
1545  aString.replace(pos, inputString.length(), outputString);
1546  opos = pos + outputString.length();
1547  }
1548  else
1549  break;
1550  }
1551 
1552  return aString;
1553  }
1554 
1555  // if the string is bigger than length, truncate it from the left.
1556  // otherwise, add pad characters to it's left.
1557  inline std::string& rightJustify(std::string& s,
1558  const std::string::size_type length,
1559  const char pad)
1560  {
1561  try
1562  {
1563  if(length < s.length())
1564  {
1565  s = s.substr(s.length()-length, std::string::npos);
1566  }
1567  else
1568  {
1569  s.insert((std::string::size_type)0, length-s.length(), pad);
1570  }
1571  return s;
1572  }
1573  catch(std::exception &e)
1574  {
1575  StringException strexc("Exception thrown: " + std::string(e.what()));
1576  GNSSTK_THROW(strexc);
1577  }
1578  }
1579 
1580  // if the string is bigger than length, truncate it from the right.
1581  // otherwise, add pad characters to it's right.
1582  inline std::string& leftJustify(std::string& s,
1583  const std::string::size_type length,
1584  const char pad)
1585  {
1586  try
1587  {
1588  if(length < s.length())
1589  {
1590  s = s.substr(0, length);
1591  }
1592  else
1593  {
1594  s.append(length-s.length(), pad);
1595  }
1596  return s;
1597  }
1598  catch(std::exception &e)
1599  {
1600  StringException strexc("Exception thrown: " + std::string(e.what()));
1601  GNSSTK_THROW(strexc);
1602  }
1603  }
1604 
1605  // leftJustify if s is bigger than length.
1606  // otherwise, add pad to the left and right of s.
1607  inline std::string& center(std::string& s,
1608  const std::string::size_type length,
1609  const char pad)
1610  {
1611  try
1612  {
1613  if(length < s.length())
1614  {
1615  leftJustify(s, length, pad);
1616  }
1617  else {
1618  std::string::size_type leftOff = s.length() + (length - s.length()) / 2;
1619  leftJustify(s, leftOff, pad);
1620  rightJustify(s, length, pad);
1621  }
1622  return s;
1623  }
1624  catch(StringException &e)
1625  {
1626  GNSSTK_RETHROW(e);
1627  }
1628  catch(std::exception &e)
1629  {
1630  StringException strexc("Exception thrown: " + std::string(e.what()));
1631  GNSSTK_THROW(strexc);
1632  }
1633  }
1634 
1635 
1636  inline float asFloat(const std::string& s)
1637  {
1638  try
1639  {
1640  std::istringstream is(s);
1641  float f;
1642  is >> f;
1643  return f;
1644  }
1645  catch(std::exception &e)
1646  {
1647  StringException strexc("Exception thrown: " + std::string(e.what()));
1648  GNSSTK_THROW(strexc);
1649  }
1650  }
1651 
1652  inline long double asLongDouble(const std::string& s)
1653  {
1654  try
1655  {
1656  std::istringstream is(s);
1657  long double x;
1658  is >> x;
1659  return x;
1660  }
1661  catch(std::exception &e)
1662  {
1663  StringException strexc("Exception thrown: " + std::string(e.what()));
1664  GNSSTK_THROW(strexc);
1665  }
1666  }
1667 
1668  template <class X>
1669  inline X asData(const std::string& s)
1670  {
1671  try
1672  {
1673  std::istringstream is(s);
1674  X x;
1675  is >> x;
1676  return x;
1677  }
1678  catch(std::exception &e)
1679  {
1680  StringException strexc("Exception thrown: " + std::string(e.what()));
1681  GNSSTK_THROW(strexc);
1682  }
1683  }
1684 
1685  inline std::string asString(const long double x, const std::string::size_type precision)
1686  {
1687  std::ostringstream ss;
1688  ss << std::fixed << std::setprecision(precision) << x ;
1689  return ss.str();
1690  }
1691 
1692  inline std::string asString(const double x, const std::string::size_type precision)
1693  {
1694  std::ostringstream ss;
1695  ss << std::fixed << std::setprecision(precision) << x;
1696  return ss.str();
1697  }
1698 
1699  template<class X>
1700  inline std::string asString(const X x)
1701  {
1702  std::ostringstream ss;
1703  ss << x;
1704  return ss.str();
1705  }
1706 
1707  // decimal to hex...
1708  inline std::string& d2x(std::string& s)
1709  {
1710  try
1711  {
1712  // remove the integer from s, including
1713  // leading spaces and 0's
1714  long l = asInt(s);
1715  stripLeading(s);
1716  stripLeading(s, "0");
1717  stripLeading(s, asString<long>(l));
1718 
1719  // put the int in a stringstream to convert it
1720  std::ostringstream st;
1721  st << std::hex << l << std::dec;
1722 
1723  // add the new hex to s
1724  s.insert(0, upperCase(st.str()) );
1725 
1726  return s;
1727  }
1728  catch(StringException &e)
1729  {
1730  GNSSTK_RETHROW(e);
1731  }
1732  catch(std::exception &e)
1733  {
1734  StringException strexc("Exception thrown: " + std::string(e.what()));
1735  GNSSTK_THROW(strexc);
1736  }
1737  }
1738 
1739  // character to hex...
1740  inline std::string& c2x(std::string& s)
1741  {
1742  const char hexDigits[] = "0123456789ABCDEF";
1743  try
1744  {
1745  std::string old(s);
1746  const unsigned char *pSource = (unsigned char *)old.c_str();
1747  unsigned n = old.length();
1748 
1749  s.resize(n * 2, 0);
1750 
1751  for (int i = 0; i < (int)n * 2;)
1752  {
1753  unsigned char c = *pSource++;
1754  s[i++] = hexDigits[ c / 16 ];
1755  s[i++] = hexDigits[ c % 16 ];
1756  }
1757 
1758  return s;
1759  }
1760  catch(StringException &e)
1761  {
1762  GNSSTK_RETHROW(e);
1763  }
1764  catch(std::exception &e)
1765  {
1766  StringException strexc("Exception thrown: " + std::string(e.what()));
1767  GNSSTK_THROW(strexc);
1768  }
1769  }
1770 
1772  // hex to a long.
1773  inline unsigned int x2uint(const std::string& s)
1774  {
1775  try
1776  {
1777  // make the stringstream, get the integer, and
1778  // remove it from the string
1779  std::istringstream iss(s);
1780  unsigned int ui;
1781  iss >> std::hex >> ui;
1782  return ui;
1783  }
1784  catch(StringException &e)
1785  {
1786  GNSSTK_RETHROW(e);
1787  }
1788  catch(std::exception &e)
1789  {
1790  StringException strexc("Exception thrown: " + std::string(e.what()));
1791  GNSSTK_THROW(strexc);
1792  }
1793  }
1794 
1796  // hex to decimal
1797  inline std::string& x2d(std::string& s)
1798  {
1799  try
1800  {
1801  // remove the "0x" part, leading zeros and spaces from the
1802  // string
1803  // ex. ' 0x003' -> '3'
1804  stripLeading(s);
1805  stripLeading(s, "0x", 1);
1806  stripLeading(s, "0");
1807 
1808  // make the stringstream, get the integer, and
1809  // remove it from the string
1810  std::istringstream strstr(s);
1811  int i = 0;
1812  strstr >> std::hex >> i;
1813  stripLeading(s, asString<int>(asInt(s)), 1);
1814 
1815  // append the decimal to the existing string
1816  s.insert(0,asString<int>(i));
1817  return s;
1818  }
1819  catch(StringException &e)
1820  {
1821  GNSSTK_RETHROW(e);
1822  }
1823  catch(std::exception &e)
1824  {
1825  StringException strexc("Exception thrown: " + std::string(e.what()));
1826  GNSSTK_THROW(strexc);
1827  }
1828  }
1829 
1830  inline std::string int2x(const unsigned int& i)
1831  {
1832  try
1833  {
1834  std::ostringstream ss;
1835  ss << std::hex << i;
1836  return ss.str();
1837  }
1838  catch(StringException &e)
1839  {
1840  GNSSTK_RETHROW(e);
1841  }
1842  catch(std::exception &e)
1843  {
1844  StringException strexc("Exception thrown: " + std::string(e.what()));
1845  GNSSTK_THROW(strexc);
1846  }
1847  }
1848 
1849  inline std::string& replaceAll(std::string& s,
1850  const std::string& oldString,
1851  const std::string& newString)
1852  {
1853  try
1854  {
1855  int spot = s.find(oldString, 0);
1856  while (spot != (int)std::string::npos)
1857  {
1858  s.replace(spot, oldString.length(), newString);
1859  spot += newString.length();
1860  spot = s.find(oldString, spot);
1861  }
1862  return s;
1863  }
1864  catch(std::exception &e)
1865  {
1866  StringException strexc("Exception thrown: " + std::string(e.what()));
1867  GNSSTK_THROW(strexc);
1868  }
1869  }
1870 
1871  inline bool isDigitString(const std::string& s)
1872  {
1873  if (s.size() == 0)
1874  return false;
1875 
1876  std::string::size_type index = 0;
1877  if((s[0] == '-') || (s[0] == '+'))
1878  index++;
1879  for( ; index < s.size(); index++)
1880  if (!isdigit(s[index]))
1881  return false;
1882  return true;
1883  }
1884 
1885  inline bool isDecimalString(const std::string& s)
1886  {
1887  if (s.size() == 0)
1888  return false;
1889 
1890  std::string::size_type index = 0;
1891  bool sawdot = false;
1892  if((s[0] == '-') || (s[0] == '+'))
1893  index++;
1894  for( ; index < s.size(); index++)
1895  {
1896  if (s[index] == '.')
1897  {
1898  if (sawdot)
1899  return false;
1900  else sawdot = true;
1901  }
1902  else if (!isdigit(s[index]))
1903  return false;
1904  }
1905  return true;
1906  }
1907 
1908  inline bool isScientificString(const std::string& s)
1909  {
1910  if(s.size() == 0)
1911  return false;
1912 
1913  std::string::size_type pos = s.find_first_of("EeDd");
1914  if(pos == std::string::npos)
1915  return isDecimalString(s);
1916 
1917  std::string mant=s.substr(0,pos);
1918  std::string exp=s.substr(pos+1);
1919  return (isDecimalString(mant) && (exp.size()==0 || isDigitString(exp)));
1920  }
1921 
1922  inline bool isAlphaString(const std::string& s)
1923  {
1924  if (s.size() == 0)
1925  return false;
1926 
1927  std::string::size_type index;
1928  for(index = 0; index < s.size(); index++)
1929  if (!isalpha(s[index]))
1930  return false;
1931  return true;
1932  }
1933 
1934  inline std::string matches(const std::string& s,
1935  const std::string& aPattern,
1936  const char zeroOrMore,
1937  const char oneOrMore,
1938  const char anyChar)
1939  {
1940  std::string thisPattern(aPattern);
1941  std::string thisStr(s);
1942 
1943  // check if something other than the regex standard
1944  // characters (*,+,.) is used for those variables
1945  if (zeroOrMore != '*')
1946  {
1947  replaceAll(thisPattern, "*", "\\*");
1948  replaceAll(thisPattern, std::string(1, zeroOrMore), "*");
1949  }
1950  if (oneOrMore != '+')
1951  {
1952  replaceAll(thisPattern, "+", "\\+");
1953  replaceAll(thisPattern, std::string(1, oneOrMore), "+");
1954  }
1955  if (anyChar != '.')
1956  {
1957  replaceAll(thisPattern, ".", "\\.");
1958  replaceAll(thisPattern, std::string(1, anyChar), ".");
1959  }
1960 
1961 #if defined(_WIN32) && _MSC_VER >= 1700
1962  try
1963  {
1964  std::regex reg (thisPattern);
1965 
1966  std::smatch sm;
1967  if(std::regex_search(thisStr,sm,reg,
1968  std::regex_constants::match_not_bol|
1969  std::regex_constants::match_not_eol))
1970  {
1971  return sm.str();
1972  }
1973  else
1974  {
1975  return std::string();
1976  }
1977  }
1978  catch(std::regex_error& e)
1979  {
1980  Exception E(std::string("std::regex_error: ") + e.what() );
1981  GNSSTK_THROW(E);
1982  }
1983 
1984 #else
1985 
1986  const std::string::size_type regErrorBufSize = 512;
1987 
1988 
1989  regmatch_t matches;
1990  regex_t regExp;
1991  char errorMsg[regErrorBufSize];
1992  int rc = regcomp(&regExp, thisPattern.c_str(), REG_EXTENDED);
1993 
1994  if (rc != 0)
1995  {
1996  regerror(rc, NULL, errorMsg, regErrorBufSize - 1);
1997  regfree(&regExp);
1998  StringException strerr("Regexp error: " + std::string(errorMsg));
1999  GNSSTK_THROW(strerr);
2000  }
2001  rc = regexec(&regExp, thisStr.c_str(), 1, &matches,
2002  REG_NOTBOL | REG_NOTEOL);
2003  if ( (rc != 0) && (rc != REG_NOMATCH) )
2004  {
2005  regerror(rc, &regExp, errorMsg, regErrorBufSize - 1);
2006  regfree(&regExp);
2007  StringException strerr("Regexp error: " + std::string(errorMsg));
2008  GNSSTK_THROW(strerr);
2009  }
2010 
2011  regfree(&regExp);
2012  if (rc == REG_NOMATCH)
2013  return std::string();
2014  else
2015  return thisStr.substr(matches.rm_so, matches.rm_eo - matches.rm_so);
2016 #endif
2017  }
2018 
2019  template <class T>
2020  inline std::string formattedPrint(const std::string& fmt,
2021  const std::string& pat,
2022  const std::string& rep,
2023  T to)
2024  {
2025 #if defined(_WIN32) && _MSC_VER >= 1700
2026 
2027  std::string rv(fmt);
2028 
2029  try
2030  {
2031  std::regex reg(pat);
2032 
2033  std::smatch m;
2034  while (std::regex_search (rv,m,reg))
2035  {
2036  std::string mac = m.str();
2037  mac = StringUtils::replaceAll(mac, rep.substr(0,1), rep.substr(1));
2038 
2039  char buffer[1024];
2040  sprintf(buffer, mac.c_str(), to);
2041 
2042  rv.replace(m.position(), m.length(), std::string(buffer));
2043  }
2044  }
2045  catch(std::regex_error& e)
2046  {
2047  Exception E(std::string("std::regex_error:")+e.what());
2048  GNSSTK_THROW(E);
2049  }
2050 
2051  return rv;
2052 #else
2053  regex_t re;
2054  const size_t bufferSize = 513;
2055  char buffer[bufferSize];
2056  int rc = regcomp(&re, pat.c_str(), REG_EXTENDED);
2057  // if the regex doesnt compile, toast =)
2058  if ( rc != 0)
2059  {
2060  regerror(rc, NULL, buffer, bufferSize - 1);
2061  regfree(&re);
2062  StringException se("Regexp error: " + std::string(buffer));
2063  GNSSTK_THROW(se);
2064  }
2065 
2066  regmatch_t r;
2067  std::string rv = fmt;
2068 
2069  while ( regexec(&re, rv.c_str(), 1, &r, 0) == 0 )
2070  {
2071  size_t len = r.rm_eo - r.rm_so;
2072  std::string mac = rv.substr(r.rm_so, len);
2073  mac = replaceAll(mac, rep.substr(0,1), rep.substr(1));
2074  sprintf(buffer, mac.c_str(), to);
2075  rv.replace(r.rm_so, len, std::string(buffer));
2076  }
2077 
2078  regfree(&re);
2079  return rv;
2080 #endif
2081  }
2082 
2083  inline std::string subString(const std::string& s,
2084  const std::string::size_type startPos,
2085  const std::string::size_type length,
2086  const char pad)
2087  {
2088  try
2089  {
2090  if(startPos >= s.length())
2091  {
2092  return std::string(length, pad);
2093  }
2094  std::string temp = s.substr(startPos, length);
2095  return leftJustify(temp, length, pad);
2096  }
2097  catch(StringException &e)
2098  {
2099  GNSSTK_RETHROW(e);
2100  }
2101  catch(std::exception &e)
2102  {
2103  StringException strexc("Exception thrown: " + std::string(e.what()));
2104  GNSSTK_THROW(strexc);
2105  }
2106  }
2107 
2108  inline std::string& lowerCase(std::string& s)
2109  {
2110  for(std::string::size_type i = 0; i < s.length(); i++)
2111  {
2112  s[i] = tolower(s[i]);
2113  }
2114  return s;
2115  }
2116 
2117  inline std::string& upperCase(std::string& s)
2118  {
2119  for(std::string::size_type i = 0; i < s.length(); i++)
2120  {
2121  s[i] = toupper(s[i]);
2122  }
2123  return s;
2124  }
2125 
2126  inline std::string memToString(const void* p,
2127  const std::string::size_type size)
2128  {
2129  unsigned char* q = (unsigned char*)p;
2130  std::string s(size,'\0');
2131  for (int i=0; i<(int)size; i++)
2132  {
2133  s[i] = (unsigned char)(*q++);
2134  }
2135  return s;
2136  }
2137 
2138  inline std::string firstWord(const std::string& s,
2139  const char delimiter)
2140  {
2141  try
2142  {
2143  // return s if there are no delimiters
2144  std::string::size_type pos = s.find_first_not_of(delimiter);
2145  if (pos == std::string::npos)
2146  {
2147  return s;
2148  }
2149  // find the end delimiter (if any) and return the string
2150  std::string::size_type endPos = s.find(delimiter, pos);
2151  if (endPos == std::string::npos)
2152  {
2153  return std::string(s, pos, endPos);
2154  }
2155  else
2156  {
2157  return std::string(s, pos, endPos - pos);
2158  }
2159  }
2160  catch(StringException &e)
2161  {
2162  GNSSTK_RETHROW(e);
2163  }
2164  catch(std::exception &e)
2165  {
2166  StringException strexc("Exception thrown: " + std::string(e.what()));
2167  GNSSTK_THROW(strexc);
2168  }
2169  }
2170 
2171  inline int numWords(const std::string& s,
2172  const char delimiter)
2173  {
2174  try
2175  {
2176  std::string t(s);
2177  stripTrailing(t, delimiter);
2178 
2179  int words = 0;
2180  while(t.length())
2181  {
2182  stripLeading(t, delimiter);
2183  stripLeading(t, firstWord(t, delimiter));
2184  words++;
2185  }
2186  return words;
2187  }
2188  catch(StringException &e)
2189  {
2190  GNSSTK_RETHROW(e);
2191  }
2192  catch(std::exception &e)
2193  {
2194  StringException strexc("Exception thrown: " + std::string(e.what()));
2195  GNSSTK_THROW(strexc);
2196  }
2197  }
2198 
2199  inline std::string words(const std::string& s,
2200  const std::string::size_type firstWord,
2201  const std::string::size_type numWords,
2202  const char delimiter)
2203  {
2204  try
2205  {
2206  if ((firstWord == 0) && (numWords == 1))
2207  return StringUtils::firstWord(s, delimiter);
2208 
2209  if (numWords == 0)
2210  return "";
2211 
2212  std::string::size_type wordNum = 0;
2213  std::string::size_type pos = 0, startPos = std::string::npos;
2214 
2215  std::string toReturn;
2216 
2217  // get position of word wordNum
2218  pos = s.find_first_not_of(delimiter, pos);
2219  while ((pos != std::string::npos) && (pos <= s.length()))
2220  {
2221  if (wordNum == firstWord)
2222  startPos = pos;
2223 
2224  // get first delimter after word wordNum
2225  pos = s.find(delimiter, pos);
2226  if (((int)numWords != -1)
2227  && ((int)wordNum == (int)(firstWord + (numWords-1))))
2228  break;
2229 
2230  pos = s.find_first_not_of(delimiter, pos);
2231  wordNum++;
2232  }
2233 
2234  if (startPos == std::string::npos)
2235  return ""; // never found the start of the word
2236  if (pos == std::string::npos)
2237  return ((wordNum >= firstWord) ? s.substr(startPos) : "");
2238 
2239  return s.substr(startPos, pos-startPos);
2240  }
2241  catch(StringException &e)
2242  {
2243  GNSSTK_RETHROW(e);
2244  }
2245  catch(std::exception &e)
2246  {
2247  StringException strexc("Exception thrown: " +
2248  std::string(e.what()));
2249  GNSSTK_THROW(strexc);
2250  }
2251  }
2252 
2253  inline std::string stripFirstWord(std::string& s,
2254  const char delimiter)
2255  {
2256  try
2257  {
2258  stripLeading(s, delimiter);
2259  std::string toReturn = firstWord(s, delimiter);
2260  stripLeading(s, toReturn);
2261  stripLeading(s, delimiter);
2262  return toReturn;
2263  }
2264  catch(StringException &e)
2265  {
2266  GNSSTK_RETHROW(e);
2267  }
2268  catch(std::exception &e)
2269  {
2270  StringException strexc("Exception thrown: " + std::string(e.what()));
2271  GNSSTK_THROW(strexc);
2272  }
2273  }
2274 
2275  inline std::vector<std::string> split(const std::string& str,
2276  const char delimiter)
2277  {
2278  try {
2279  std::vector<std::string> rvec; // vector to return
2280  std::string tempStr(str); // copy the input string
2281  stripLeading(tempStr,delimiter); // remove leading delimiters
2282  while(tempStr.size() > 0)
2283  rvec.push_back(stripFirstWord(tempStr,delimiter));
2284  return rvec;
2285  }
2286  catch(StringException &e)
2287  {
2288  GNSSTK_RETHROW(e);
2289  }
2290  catch(std::exception &e)
2291  {
2292  StringException strexc("Exception thrown: " + std::string(e.what()));
2293  GNSSTK_THROW(strexc);
2294  }
2295  }
2296 
2297  inline std::vector<std::string> split(const std::string& aStr,
2298  const std::string& theDelimiters,
2299  bool trimWhitespace,
2300  bool ignoreEmpty)
2301  {
2302  std::vector<std::string> toReturn;
2303 
2304  std::string::size_type lastPos = aStr.find_first_not_of(theDelimiters, 0);
2305  std::string::size_type pos = aStr.find_first_of(theDelimiters, lastPos);
2306 
2307  while (std::string::npos != pos || std::string::npos != lastPos)
2308  {
2309  std::string token = aStr.substr(lastPos, pos - lastPos);
2310 
2311  if(trimWhitespace) token = StringUtils::strip(token);
2312 
2313  if(!token.empty() || !ignoreEmpty) toReturn.push_back(token);
2314 
2315  lastPos = aStr.find_first_not_of(theDelimiters, pos);
2316  pos = aStr.find_first_of(theDelimiters, lastPos);
2317  }
2318 
2319  return toReturn;
2320  }
2321 
2322  inline std::vector<std::string> splitWithQuotes(const std::string& aStr,
2323  const char delimiter,
2324  bool trimWhitespace,
2325  bool ignoreEmpty)
2326  {
2327  std::vector<std::string> toReturn;
2328  std::string::size_type begPos = 0;
2329  std::string::size_type endPos = 0;
2330  std::string::size_type tokenLength;
2331  char currentDelimiter;
2332 
2333  if(delimiter == '\'' || delimiter == '"')
2334  GNSSTK_THROW(StringException("Delimiter must not be quote"));
2335 
2336  while(endPos != std::string::npos && endPos <= aStr.length())
2337  {
2338  currentDelimiter = delimiter;
2339 
2340  // if first character is a quote, set current delimiter to it
2341  if(aStr.compare(begPos,1,"\"") == 0) currentDelimiter = '"';
2342  if(aStr.compare(begPos,1,"\'") == 0) currentDelimiter = '\'';
2343 
2344  // find next delimiter
2345  endPos = aStr.find_first_of(currentDelimiter,
2346  begPos + (currentDelimiter == delimiter ? 0 : 1));
2347 
2348  // if this token is quoted, make sure to capture the trailing quote
2349  // if(delimiter is a quote and second quote is found) include it
2350  if(currentDelimiter != delimiter && std::string::npos != endPos) endPos++;
2351 
2352  // length of new field
2353  tokenLength = endPos - begPos;
2354  // copy out the field
2355  std::string token = aStr.substr(begPos, tokenLength);
2356 
2357  // if quoted, remove the quotes
2358  if(currentDelimiter != delimiter)
2359  token = gnsstk::StringUtils::strip(token,currentDelimiter);
2360 
2361  // remove whitespace at beginning and end
2362  if(trimWhitespace) token = gnsstk::StringUtils::strip(token);
2363 
2364  // save it
2365  if(!token.empty() || !ignoreEmpty) toReturn.push_back(token);
2366 
2367  // find the next token, and go back to delimiter
2368  begPos = endPos;
2369  if(begPos != std::string::npos) begPos++;
2370  endPos = begPos;
2371  }
2372 
2373  return toReturn;
2374  }
2375 
2376  inline std::vector<std::string> splitWithDoubleQuotes(const std::string& aStr,
2377  const char delimiter,
2378  bool trimWhitespace,
2379  bool ignoreEmpty)
2380  {
2381  std::vector<std::string> toReturn;
2382  std::string::size_type begPos = 0;
2383  std::string::size_type endPos = 0;
2384  std::string::size_type tokenLength;
2385  char currentDelimiter;
2386 
2387  if(delimiter == '"')
2388  GNSSTK_THROW(StringException("Delimiter must not be quote"));
2389 
2390  while(endPos != std::string::npos && endPos <= aStr.length())
2391  {
2392  currentDelimiter = delimiter;
2393 
2394  // if first character is a quote, set current delimiter to it
2395  if(aStr.compare(begPos,1,"\"") == 0) currentDelimiter = '"';
2396 
2397  // find next delimiter
2398  endPos = aStr.find_first_of(currentDelimiter,
2399  begPos + (currentDelimiter == delimiter ? 0 : 1));
2400 
2401  // if this token is quoted, make sure to capture the trailing quote
2402  // if(delimiter is a quote and second quote is found) include it
2403  if(currentDelimiter != delimiter && std::string::npos != endPos) endPos++;
2404 
2405  // length of new field
2406  tokenLength = endPos - begPos;
2407  // copy out the field
2408  std::string token = aStr.substr(begPos, tokenLength);
2409 
2410  // if quoted, remove the quotes
2411  if(currentDelimiter != delimiter)
2412  token = gnsstk::StringUtils::strip(token,currentDelimiter);
2413 
2414  // remove whitespace at beginning and end
2415  if(trimWhitespace) token = gnsstk::StringUtils::strip(token);
2416 
2417  // save it
2418  if(!token.empty() || !ignoreEmpty) toReturn.push_back(token);
2419 
2420  // find the next token, and go back to delimiter
2421  begPos = endPos;
2422  if(begPos != std::string::npos) begPos++;
2423  endPos = begPos;
2424  }
2425 
2426  return toReturn;
2427  }
2428 
2429  inline std::string& removeWords(std::string& s,
2430  const std::string::size_type first,
2431  const std::string::size_type wordsToReplace,
2432  const char delimiter)
2433  {
2434  try
2435  {
2436  std::string::size_type rmStart = std::string::npos;
2437  std::string::size_type rmCount = std::string::npos;
2438 
2439  // Find start of word 0
2440  std::string::size_type sPos = s.find_first_not_of(delimiter);
2441 
2442  for (std::string::size_type thisWord = 0;
2443  sPos != std::string::npos;
2444  thisWord++)
2445  {
2446  // Check for start and end of range to remove
2447  if (thisWord == first)
2448  {
2449  rmStart = sPos;
2450  if (wordsToReplace == std::string::npos)
2451  {
2452  break;
2453  }
2454  }
2455  else if ( (wordsToReplace != std::string::npos)
2456  && (thisWord >= first + wordsToReplace))
2457  {
2458  rmCount = sPos - rmStart;
2459  break;
2460  }
2461  // Find the end of the current word
2462  sPos = s.find(delimiter, sPos);
2463  if (sPos != std::string::npos)
2464  {
2465  // Find start of next word
2466  sPos = s.find_first_not_of(delimiter, sPos);
2467  }
2468  }
2469  // Remove the words if they were present
2470  if (rmStart != std::string::npos)
2471  {
2472  s.erase(rmStart, rmCount);
2473  if (rmCount == std::string::npos)
2474  {
2475  stripTrailing(s, delimiter);
2476  }
2477  }
2478  return s;
2479  }
2480  catch(StringException &e)
2481  {
2482  GNSSTK_RETHROW(e);
2483  }
2484  catch(std::exception &e)
2485  {
2486  StringException strexc("Exception thrown: " + std::string(e.what()));
2487  GNSSTK_THROW(strexc);
2488  }
2489  }
2490 
2491  inline std::string doub2sci(const double& d,
2492  const std::string::size_type length,
2493  const std::string::size_type expLen,
2494  const bool showSign,
2495  const bool checkSwitch)
2496  {
2497  std::string toReturn;
2498  short exponentLength = expLen;
2499 
2500  /* Validate the assumptions regarding the input arguments */
2501  if (exponentLength < 0) exponentLength = 1;
2502  if (exponentLength > 3 && checkSwitch) exponentLength = 3;
2503 
2504  std::stringstream c;
2505  c.setf(std::ios::scientific, std::ios::floatfield);
2506 
2507  // length - 3 for special characters ('.', 'e', '+' or '-')
2508  // - exponentlength (e04)
2509  // - 1 for the digit before the decimal (2.)
2510  // and if showSign == true,
2511  // an extra -1 for '-' or ' ' if it's positive or negative
2512  int expSize = 0;
2513  if (showSign)
2514  expSize = 1;
2515  c.precision(length - 3 - exponentLength - 1 - expSize);
2516 
2517 
2518  c << d;
2519 
2520  c >> toReturn;
2521 
2522  return toReturn;
2523  }
2524 
2525  inline std::string doubleToScientific(const double& d,
2526  const std::string::size_type length,
2527  const std::string::size_type precision,
2528  const std::string::size_type explen,
2529  bool showPlus)
2530  {
2531  // get final exp length, precision and total length
2532  std::string::size_type elen = (explen > 0 ? (explen < 3 ? explen : 3) : 1);
2533  std::string::size_type prec = (precision > 0 ? precision : 1);
2534  std::string::size_type leng = (length > 0 ? length : 1);
2535 
2536  // i will be minimum length required with prec==1: force leng if necessary
2537  size_t i = (int(leng) - int(elen) - 4);
2538  if(showPlus) i--;
2539  if(i > 0 && leng < i) leng = std::string::size_type(i);
2540 
2541  // set up the stream for writing
2542  std::stringstream ss;
2543  ss << std::scientific << std::setprecision(prec);
2544  if(showPlus) ss << std::showpos;
2545 
2546  // write d to a string with precision, sign and in scientific notation
2547  ss << d;
2548 
2549  // now read that string
2550  std::string str1,str2;
2551  ss >> str1;
2552  std::string::size_type pos = str1.find_first_of("EDed"); // find exponent
2553  str2 = str1.substr(0,pos+2); // str2 = +123.2345e+
2554  str1 = str1.substr(pos+2); // str1 = exponent only
2555 
2556  // make the exponent length elen
2559 
2560  // pad if necessary
2561  if(str2.length() < leng) str2 = StringUtils::rightJustify(str2,leng);
2562 
2563  return str2;
2564  }
2565 
2566  inline std::string& sci2for(std::string& aStr,
2567  const std::string::size_type startPos,
2568  const std::string::size_type length,
2569  const std::string::size_type expLen,
2570  const bool checkSwitch)
2571  {
2572  try
2573  {
2574  std::string::size_type idx = aStr.find('.', startPos);
2575  int expAdd = 0;
2576  std::string exp;
2577  long iexp;
2578  //If checkSwitch is false, always redo the exponential. Otherwise,
2579  //set it to false.
2580  bool redoexp=!checkSwitch;
2581 
2582  // Check for decimal place within specified boundaries
2583  if ((idx == 0) || (idx >= (startPos + length - expLen - 1)))
2584  {
2585  StringException e("sci2for: no decimal point in string");
2586  GNSSTK_THROW(e);
2587  }
2588 
2589  // Here, account for the possibility that there are
2590  // no numbers to the left of the decimal, but do not
2591  // account for the possibility of non-scientific
2592  // notation (more than one digit to the left of the
2593  // decimal)
2594  if (idx > startPos)
2595  {
2596  redoexp = true;
2597  // Swap digit and decimal.
2598  aStr[idx] = aStr[idx-1];
2599  aStr[idx-1] = '.';
2600  // Only add one to the exponent if the number is non-zero
2601  if (asDouble(aStr.substr(startPos, length)) != 0.0)
2602  expAdd = 1;
2603  }
2604 
2605  idx = aStr.find('e', startPos);
2606  if (idx == std::string::npos)
2607  {
2608  idx = aStr.find('E', startPos);
2609  if (idx == std::string::npos)
2610  {
2611  StringException e("sci2for:no 'e' or 'E' in string");
2612  GNSSTK_THROW(e);
2613  }
2614  }
2615  // Change the exponent character to D normally, or E of checkSwitch is false.
2616  if (checkSwitch)
2617  aStr[idx] = 'D';
2618  else
2619  aStr[idx] = 'E';
2620 
2621  // Change the exponent itself
2622  if (redoexp)
2623  {
2624  exp = aStr.substr(idx + 1, std::string::npos);
2625  iexp = asInt(exp);
2626  iexp += expAdd;
2627 
2628  aStr.erase(idx + 1);
2629  if (iexp < 0)
2630  {
2631  aStr += "-";
2632  iexp -= iexp*2;
2633  }
2634  else
2635  aStr += "+";
2636  aStr += rightJustify(asString(iexp),expLen,'0');
2637 
2638  }
2639 
2640  // if the number is positive, append a space
2641  // (if it's negative, there's a leading '-'
2642  if (aStr[0] == '.')
2643  {
2644  aStr.insert((std::string::size_type)0, 1, ' ');
2645  }
2646 
2647  //If checkSwitch is false, add on one leading zero to the string
2648  if (!checkSwitch)
2649  {
2650  aStr.insert((std::string::size_type)1, 1, '0');
2651  }
2652 
2653 
2654  return aStr;
2655  }
2656  catch(StringException &e)
2657  {
2658  GNSSTK_RETHROW(e);
2659  }
2660  catch(std::exception &e)
2661  {
2662  StringException strexc("Exception thrown: " + std::string(e.what()));
2663  GNSSTK_THROW(strexc);
2664  }
2665  } // end sci2for
2666 
2667 
2668  inline std::string doub2for(const double& d,
2669  const std::string::size_type length,
2670  const std::string::size_type expLen,
2671  const bool checkSwitch)
2672  {
2673  try
2674  {
2675  short exponentLength = expLen;
2676 
2677  /* Validate the assumptions regarding the input arguments */
2678  if (exponentLength < 0) exponentLength = 1;
2679  if (exponentLength > 3 && checkSwitch) exponentLength = 3;
2680 
2681  std::string toReturn = doub2sci(d, length, exponentLength, true, checkSwitch);
2682  sci2for(toReturn, 0, length, exponentLength, checkSwitch);
2683 
2684  return toReturn;
2685  }
2686  catch(StringException &e)
2687  {
2688  GNSSTK_RETHROW(e);
2689  }
2690  catch(std::exception &e)
2691  {
2692  StringException strexc("Exception thrown: " + std::string(e.what()));
2693  GNSSTK_THROW(strexc);
2694  }
2695  }
2696 
2697 
2698  inline double for2doub(const std::string& aStr,
2699  const std::string::size_type startPos,
2700  const std::string::size_type length)
2701  {
2702  std::string s(aStr, startPos, length);
2703  strip(s);
2704 
2705  // you can blame Rinex for these special checks
2706  if (s.empty())
2707  {
2708  return 0;
2709  }
2710 
2711  std::string::size_type pos = s.find_first_of("EDd");
2712  if (pos != std::string::npos)
2713  {
2714  s[pos] = 'e';
2715  }
2716  else
2717  {
2718  // just treat it like a double
2719  return asDouble(aStr.substr(startPos, length));
2720  }
2721 
2722  std::stringstream st;
2723  st << s;
2724 
2725  double d;
2726  st >> d;
2727 
2728  return d;
2729  }
2730 
2731  inline std::string printable(const std::string& aStr)
2732  {
2733  try
2734  {
2735  std::string rv;
2736  size_t len = aStr.length();
2737  rv.reserve(len);
2738 
2739  for (int i = 0; i < len; i++)
2740  {
2741  char c = aStr[i];
2742  if (c > 31 && c < 127) // Handle printable ASCII characters
2743  {
2744  rv.append(1,c);
2745  }
2746  else
2747  {
2748  if (c < 0 || c > 127) // Handle non-ASCII characters
2749  {
2750  rv.append("<" + c2x(aStr.substr(i,1)) + ">");
2751  }
2752  else // Handle control characters
2753  {
2754  char ctrl = (int)c ^ 0x40; // Flip the 7th bit
2755  rv.append(1,'^');
2756  rv.append(1,ctrl);
2757  }
2758  }
2759  }
2760 
2761  return rv;
2762  }
2763  catch(StringException &e)
2764  {
2765  GNSSTK_RETHROW(e);
2766  }
2767  catch(std::exception &e)
2768  {
2769  StringException strexc("Exception thrown: " + std::string(e.what()));
2770  GNSSTK_THROW(strexc);
2771  }
2772  }
2773 
2774  inline std::string& prettyPrint(std::string& aStr,
2775  const std::string& lineDelim,
2776  const std::string& indent,
2777  const std::string& firstIndent,
2778  const std::string::size_type len,
2779  const char wordDelim)
2780  {
2781  try
2782  {
2783  std::string newStr(firstIndent);
2784  // positions of word and line delimiters in aStr
2785  std::string::size_type wordPos = 0, linePos = 0, curPos = 0,
2786  curLineLen = newStr.length(), minPos = 0, wordLen = 0;
2787  bool wordDelimited = false;
2788  while (curPos != std::string::npos)
2789  {
2790  wordPos = aStr.find(wordDelim, curPos);
2791  if (wordPos == curPos)
2792  {
2793  // ignore the word delimeter
2794  curPos++;
2795  continue;
2796  }
2797  // no longer processing a word delimiter
2798  wordDelimited = false;
2799  linePos = aStr.find(lineDelim, curPos);
2800  if (linePos == curPos)
2801  {
2802  curPos += lineDelim.length();
2803  // line delimiters are NOT compressed.
2804  newStr += lineDelim + indent;
2805  curLineLen = indent.length();
2806  continue;
2807  }
2808  // add a word
2809  minPos = std::min(wordPos, linePos);
2810  if (minPos != std::string::npos)
2811  wordLen = minPos - curPos;
2812  else
2813  wordLen = aStr.length() - curPos;
2814  if ((curLineLen + wordLen + 1) > len)
2815  {
2816  newStr += lineDelim + indent;
2817  curLineLen = indent.length();
2818  }
2819  newStr += wordDelim;
2820  newStr += aStr.substr(curPos, wordLen);
2821  curLineLen += wordLen + 1;
2822  curPos = minPos;
2823  }
2824  aStr = newStr + lineDelim;
2825  return aStr;
2826  }
2827  catch (std::exception &e)
2828  {
2829  StringException strexc("Exception thrown: " +
2830  std::string(e.what()));
2831  GNSSTK_THROW(strexc);
2832  }
2833  }
2834 
2835  inline std::string tabularize(const std::vector<std::string>& cells,
2836  std::string::size_type width,
2837  bool force)
2838  {
2839  std::string rv;
2840  // get maximum cell size;
2841  std::string::size_type maxWidth = 0;
2842  for (unsigned i = 0; i < cells.size(); i++)
2843  {
2844  maxWidth = std::max(maxWidth, cells[i].size());
2845  }
2846  maxWidth++; // for a separator
2847  // check the console width
2848  if (!force)
2849  {
2850  char *colch = getenv("COLUMNS");
2851  if (colch)
2852  {
2853  std::string colStr(colch);
2854  width = asInt(colStr);
2855  }
2856  }
2857  // how many columns can we have?
2858  std::string::size_type numCols = width / maxWidth;
2859  for (unsigned i = 0; i < cells.size(); i++)
2860  {
2861  rv += leftJustify(cells[i], maxWidth);
2862  if (((i % numCols) == (numCols-1)) ||
2863  (i == (cells.size() - 1)))
2864  {
2865  rv += '\n';
2866  }
2867  }
2868  return rv;
2869  }
2870 
2872 
2873  } // namespace StringUtils
2874 
2875 } // namespace gnsstk
2876 #endif // GNSSTK_STRINGUTILS_HPP
gnsstk::StringUtils::replaceAll
std::string & replaceAll(std::string &s, const std::string &oldString, const std::string &newString)
Definition: StringUtils.hpp:1849
getenv
char * getenv()
gnsstk::StringUtils::upperCase
std::string & upperCase(std::string &s)
Definition: StringUtils.hpp:2117
gnsstk::StringUtils::asInt
long asInt(const std::string &s)
Definition: StringUtils.hpp:713
se
double se
obliquity cos, T*cos, sin coefficients
Definition: IERS2003NutationData.hpp:48
gnsstk::StringUtils::HexDumpDataConfig
Class for configuring the appearance of hexDumpData() output.
Definition: HexDumpDataConfig.hpp:58
gnsstk::StringUtils::FFAlign::Left
@ Left
Formatted output will be left-aligned.
gnsstk::StringUtils::word
std::string word(const std::string &s, const std::string::size_type wordNum=0, const char delimiter=' ')
Definition: StringUtils.hpp:1112
cfg
#define cfg(a)
Definition: DiscCorr.cpp:624
gnsstk::StringUtils::center
std::string & center(std::string &s, const std::string::size_type length, const char pad=' ')
Definition: StringUtils.hpp:1607
gnsstk::StringUtils::isAlphaString
bool isAlphaString(const std::string &s)
Definition: StringUtils.hpp:1922
gnsstk::StringUtils::removeWords
std::string & removeWords(std::string &s, const std::string::size_type first=0, const std::string::size_type wordsToReplace=std::string::npos, const char delimiter=' ')
Definition: StringUtils.hpp:2429
gnsstk::max
T max(const SparseMatrix< T > &SM)
Maximum element - return 0 if empty.
Definition: SparseMatrix.hpp:881
gnsstk::StringUtils::asFloat
float asFloat(const std::string &s)
Definition: StringUtils.hpp:1636
gnsstk::StringUtils::asLongDouble
long double asLongDouble(const std::string &s)
Definition: StringUtils.hpp:1652
gnsstk::StringUtils::NEW_EXCEPTION_CLASS
NEW_EXCEPTION_CLASS(StringException, Exception)
gnsstk::StringUtils::printable
std::string printable(const std::string &aStr)
Definition: StringUtils.hpp:2731
gnsstk::StringUtils::asString
std::string asString(IonexStoreStrategy e)
Convert a IonexStoreStrategy to a whitespace-free string name.
Definition: IonexStoreStrategy.cpp:46
NULL
#define NULL
Definition: getopt1.c:64
gnsstk::StringUtils::sci2for
std::string & sci2for(std::string &aStr, const std::string::size_type startPos=0, const std::string::size_type length=std::string::npos, const std::string::size_type expLen=3, const bool checkSwitch=true)
Definition: StringUtils.hpp:2566
gnsstk::StringUtils::for2doub
double for2doub(const std::string &aStr, const std::string::size_type startPos=0, const std::string::size_type length=std::string::npos)
Definition: StringUtils.hpp:2698
gnsstk::StringUtils::memToString
std::string memToString(const void *p, const std::string::size_type size)
Definition: StringUtils.hpp:2126
gnsstk::StringUtils::c2x
std::string & c2x(std::string &s)
Definition: StringUtils.hpp:1740
gnsstk::StringUtils::FFSign::NegPos
@ NegPos
Prefix output with a minus sign (neg) or plus sign (pos)
gnsstk
For Sinex::InputHistory.
Definition: BasicFramework.cpp:50
gnsstk::StringUtils::stripLeading
std::string & stripLeading(std::string &s, const std::string &aString, std::string::size_type num=std::string::npos)
Definition: StringUtils.hpp:1426
gnsstk::StringUtils::FFAlign::Right
@ Right
Formatted output will be right-aligned.
gnsstk::StringUtils::split
std::vector< std::string > split(const std::string &str, const char delimiter=' ')
Definition: StringUtils.hpp:2275
gnsstk::StringUtils::words
std::string words(const std::string &s, const std::string::size_type firstWord=0, const std::string::size_type numWords=std::string::npos, const char delimiter=' ')
Definition: StringUtils.hpp:2199
gnsstk::StringUtils::x2uint
unsigned int x2uint(const std::string &s)
Definition: StringUtils.hpp:1773
example4.temp
temp
Definition: example4.py:35
gnsstk::StringUtils::FFLead
FFLead
Leading character for floatFormat(), after any whitespace or sign.
Definition: StringUtils.hpp:109
gnsstk::Exception
Definition: Exception.hpp:151
gnsstk::StringUtils::floatFormat
std::string floatFormat(double d, FFLead lead, unsigned mantissa, unsigned exponent, unsigned width, char expChar, FFSign sign, FFAlign align)
Definition: StringUtils.cpp:210
gnsstk::StringUtils::stripTrailing
std::string & stripTrailing(std::string &s, const std::string &aString, std::string::size_type num=std::string::npos)
Definition: StringUtils.hpp:1453
gnsstk::StringUtils::subString
std::string subString(const std::string &s, const std::string::size_type startPos=0, const std::string::size_type length=std::string::npos, const char pad=' ')
Definition: StringUtils.hpp:2083
gnsstk::StringUtils::numWords
int numWords(const std::string &s, const char delimiter=' ')
Definition: StringUtils.hpp:2171
gnsstk::StringUtils::FFSign::NegOnly
@ NegOnly
Prefix output with a minus sign (neg) or nothing (pos)
gnsstk::StringUtils::FFLead::Zero
@ Zero
Start with zero, e.g. 0.12345.
gnsstk::StringUtils::doub2for
std::string doub2for(const double &d, const std::string::size_type length, const std::string::size_type expLen, const bool checkSwitch=true)
Definition: StringUtils.hpp:2668
gnsstk::StringUtils::FFSign::NegSpace
@ NegSpace
Prefix output with a minus sign (neg) or space (pos)
gnsstk::StringUtils::splitWithDoubleQuotes
std::vector< std::string > splitWithDoubleQuotes(const std::string &aStr, const char delimiter=' ', bool trimWhitespace=true, bool ignoreEmpty=true)
Definition: StringUtils.hpp:2376
gnsstk::StringUtils::d2x
std::string & d2x(std::string &s)
Definition: StringUtils.hpp:1708
gnsstk::StringUtils::doubleToScientific
std::string doubleToScientific(const double &d, const std::string::size_type length, const std::string::size_type precision, const std::string::size_type explen, bool showPlus=false)
Definition: StringUtils.hpp:2525
gnsstk::StringUtils::hexDumpData
void hexDumpData(const std::string &data, std::ostream &s, const HexDumpDataConfig &cfg)
Definition: StringUtils.cpp:62
gnsstk::StringUtils::asData
X asData(const std::string &s)
Definition: StringUtils.hpp:1669
gnsstk::StringUtils::FFLead::Decimal
@ Decimal
Start with decimal, e.g. .12345.
gnsstk::StringUtils::FFLead::NonZero
@ NonZero
Start with the first non-zero digit, e.g. 1.2345.
gnsstk::min
T min(const SparseMatrix< T > &SM)
Maximum element - return 0 if empty.
Definition: SparseMatrix.hpp:858
gnsstk::StringUtils::stripFirstWord
std::string stripFirstWord(std::string &s, const char delimiter=' ')
Definition: StringUtils.hpp:2253
gnsstk::StringUtils::int2x
std::string int2x(const unsigned int &i)
Definition: StringUtils.hpp:1830
gnsstk::StringUtils::asDouble
double asDouble(const std::string &s)
Definition: StringUtils.hpp:705
gnsstk::StringUtils::tabularize
std::string tabularize(const std::vector< std::string > &cells, std::string::size_type width=80, bool force=false)
Definition: StringUtils.hpp:2835
gnsstk::glo::str1
@ str1
Definition: GLOFBits.hpp:53
GNSSTK_RETHROW
#define GNSSTK_RETHROW(exc)
Definition: Exception.hpp:369
example4.pos
pos
Definition: example4.py:125
gnsstk::StringUtils::x2d
std::string & x2d(std::string &s)
Definition: StringUtils.hpp:1797
example3.data
data
Definition: example3.py:22
gnsstk::StringUtils::doub2sci
std::string doub2sci(const double &d, const std::string::size_type length, const std::string::size_type expLen, const bool showSign=true, const bool checkSwitch=true)
Definition: StringUtils.hpp:2491
gnsstk::StringUtils::isLike
bool isLike(const std::string &s, const std::string &aPattern, const char zeroOrMore=' *', const char oneOrMore='+', const char anyChar='.')
Definition: StringUtils.hpp:948
gnsstk::StringUtils::rightJustify
std::string & rightJustify(std::string &s, const std::string::size_type length, const char pad=' ')
Definition: StringUtils.hpp:1557
gnsstk::StringUtils::asUnsigned
unsigned long asUnsigned(const std::string &s)
Definition: StringUtils.hpp:721
Exception.hpp
gnsstk::StringUtils::firstWord
std::string firstWord(const std::string &s, const char delimiter=' ')
Definition: StringUtils.hpp:2138
HexDumpDataConfig.hpp
gnsstk::StringUtils::FFSign
FFSign
How to handle sign in floatFormat()
Definition: StringUtils.hpp:117
gnsstk::StringUtils::change
std::string change(const std::string &aString, const std::string &inputString, const std::string &outputString, std::string::size_type startPos=0, unsigned numChanges=(std::numeric_limits< unsigned >().max()))
Definition: StringUtils.hpp:1521
gnsstk::StringUtils::strip
std::string & strip(std::string &s, const std::string &aString, std::string::size_type num=std::string::npos)
Definition: StringUtils.hpp:1482
gnsstk::StringUtils::isDecimalString
bool isDecimalString(const std::string &s)
Definition: StringUtils.hpp:1885
gnsstk::StringUtils::leftJustify
std::string & leftJustify(std::string &s, const std::string::size_type length, const char pad=' ')
Definition: StringUtils.hpp:1582
GNSSTK_THROW
#define GNSSTK_THROW(exc)
Definition: Exception.hpp:366
gnsstk::glo::str2
@ str2
Definition: GLOFBits.hpp:54
gnsstk::StringUtils::matches
std::string matches(const std::string &s, const std::string &aPattern, const char zeroOrMore=' *', const char oneOrMore='+', const char anyChar='.')
Definition: StringUtils.hpp:1934
gnsstk::StringUtils::formattedPrint
std::string formattedPrint(const std::string &fmt, const std::string &pat, const std::string &rep, T to)
Definition: StringUtils.hpp:2020
gnsstk::StringUtils::isScientificString
bool isScientificString(const std::string &s)
Definition: StringUtils.hpp:1908
gnsstk::StringUtils::lowerCase
std::string & lowerCase(std::string &s)
Definition: StringUtils.hpp:2108
gnsstk::StringUtils::FFAlign
FFAlign
Alignment of data for floatFormat()
Definition: StringUtils.hpp:125
gnsstk::StringUtils::isDigitString
bool isDigitString(const std::string &s)
Definition: StringUtils.hpp:1871
gnsstk::StringUtils::prettyPrint
std::string & prettyPrint(std::string &aStr, const std::string &lineDelim="\n", const std::string &indent="", const std::string &firstIndent=" ", const std::string::size_type len=80, const char wordDelim=' ')
Definition: StringUtils.hpp:2774
gnsstk::StringUtils::splitWithQuotes
std::vector< std::string > splitWithQuotes(const std::string &aStr, const char delimiter=' ', bool trimWhitespace=true, bool ignoreEmpty=true)
Definition: StringUtils.hpp:2322
gnsstk::StringUtils::translate
std::string translate(const std::string &aString, const std::string &inputChars, const std::string &outputChars, const char pad=' ')
Definition: StringUtils.hpp:1491


gnsstk
Author(s):
autogenerated on Wed Oct 25 2023 02:40:41