StringUtils.hpp

Go to the documentation of this file.
00001 #pragma ident "$Id: StringUtils.hpp 2917 2011-10-05 08:49:57Z yanweignss $"
00002 
00003 //============================================================================
00004 //
00005 //  This file is part of GPSTk, the GPS Toolkit.
00006 //
00007 //  The GPSTk is free software; you can redistribute it and/or modify
00008 //  it under the terms of the GNU Lesser General Public License as published
00009 //  by the Free Software Foundation; either version 2.1 of the License, or
00010 //  any later version.
00011 //
00012 //  The GPSTk is distributed in the hope that it will be useful,
00013 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 //  GNU Lesser General Public License for more details.
00016 //
00017 //  You should have received a copy of the GNU Lesser General Public
00018 //  License along with GPSTk; if not, write to the Free Software Foundation,
00019 //  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 //  
00021 //  Copyright 2004, The University of Texas at Austin
00022 //
00023 //============================================================================
00024 
00025 //============================================================================
00026 //
00027 //This software developed by Applied Research Laboratories at the University of
00028 //Texas at Austin, under contract to an agency or agencies within the U.S. 
00029 //Department of Defense. The U.S. Government retains all rights to use,
00030 //duplicate, distribute, disclose, or release this software. 
00031 //
00032 //Pursuant to DoD Directive 523024 
00033 //
00034 // DISTRIBUTION STATEMENT A: This software has been approved for public 
00035 //                           release, distribution is unlimited.
00036 //
00037 //=============================================================================
00038 
00044 #ifndef GPSTK_STRINGUTILS_HPP
00045 #define GPSTK_STRINGUTILS_HPP
00046 
00047 #include <string>
00048 #include <sstream>
00049 #include <iomanip>
00050 #include <iostream>
00051 #include <list>
00052 
00054 #include <cstdio>
00055 #include <cstdlib>
00056 #include <regex.h>
00057 #include <cctype>
00058 #include <limits>
00059 
00060 #include "Exception.hpp"
00061 
00062 namespace gpstk
00063 {
00082    namespace StringUtils
00083    {
00086 
00090       NEW_EXCEPTION_CLASS(StringException, Exception);
00091 
00093       class HexDumpDataConfig
00094       {
00095       public:
00096          HexDumpDataConfig()
00097                : showIndex(true), hexIndex(true), upperHex(false),
00098                  idxDigits(4), indexWS(1), groupBy(1), groupWS(1),
00099                  group2By(8), group2WS(2), bytesPerLine(16), showText(true),
00100                  separator(0), textWS(4)
00101          {}
00102          HexDumpDataConfig(bool ashowIndex, bool ahexIndex, bool aupperHex,
00103                            unsigned aidxDigits, unsigned aindexWS,
00104                            unsigned agroupBy, unsigned agroupWS,
00105                            unsigned agroup2By, unsigned agroup2WS,
00106                            unsigned abytesPerLine, bool ashowText,
00107                            char aseparator, unsigned atextWS)
00108                : showIndex(ashowIndex), hexIndex(ahexIndex),
00109                  upperHex(aupperHex), idxDigits(aidxDigits),
00110                  indexWS(aindexWS), groupBy(agroupBy), groupWS(agroupWS),
00111                  group2By(agroup2By), group2WS(agroup2WS),
00112                  bytesPerLine(abytesPerLine), showText(ashowText),
00113                  separator(aseparator), textWS(atextWS)
00114          {}
00115          bool showIndex; 
00116          bool hexIndex; 
00117          bool upperHex; 
00118          unsigned idxDigits; 
00119          unsigned indexWS; 
00120          unsigned groupBy; 
00121          unsigned groupWS; 
00122          unsigned group2By; 
00123          unsigned group2WS; 
00124          unsigned bytesPerLine; 
00125          bool showText; 
00126          char separator; 
00127          unsigned textWS; 
00128       };
00129 
00138       inline void hexDumpData(std::ostream& s,
00139                               const std::string& data,
00140                               unsigned indent = 0,
00141                               HexDumpDataConfig cfg = HexDumpDataConfig());
00142       
00151       inline void hexDumpData(std::ostream& s,
00152                               const std::string& data,
00153                               const std::string& tag,
00154                               HexDumpDataConfig cfg = HexDumpDataConfig());
00155 
00166       inline 
00167       std::string& stripLeading(std::string& s,
00168                                 const std::string& aString,
00169                                 std::string::size_type num = std::string::npos)
00170          throw(StringException);
00171 
00182       inline std::string stripLeading(const std::string& s,
00183                                       const std::string& aString,
00184                                       std::string::size_type num = std::string::npos)
00185          throw(StringException)
00186       { std::string t(s); stripLeading(t, aString, num); return t; }
00187 
00198       inline std::string& stripLeading(std::string& s, 
00199                                        const char* pString,
00200                                        std::string::size_type num = std::string::npos)
00201          throw(StringException)
00202       { return stripLeading(s, std::string(pString), num); }
00203 
00214       inline std::string stripLeading(const std::string& s, 
00215                                       const char* pString,
00216                                       std::string::size_type num = std::string::npos)
00217          throw(StringException)
00218       { std::string t(s); stripLeading(t, std::string(pString), num); return t; }
00219 
00230       inline std::string& stripLeading(std::string& s, 
00231                                        const char aCharacter,
00232                                        std::string::size_type num = std::string::npos)
00233          throw(StringException)
00234       { return stripLeading(s, std::string(1,aCharacter), num); }
00235      
00246       inline std::string stripLeading(const std::string& s, 
00247                                       const char aCharacter,
00248                                       std::string::size_type num = std::string::npos)
00249          throw(StringException)
00250       { std::string t(s); stripLeading(t, std::string(1,aCharacter), num); return t; }
00251      
00261       inline std::string& stripLeading(std::string& s, 
00262                                        std::string::size_type num = std::string::npos)
00263          throw(StringException)
00264       { return stripLeading(s,std::string(1,' '),num); }
00265 
00275       inline std::string stripLeading(const std::string& s, 
00276                                       std::string::size_type num = std::string::npos)
00277          throw(StringException)
00278       { std::string t(s); stripLeading(t,std::string(1,' '),num); return t; }
00279      
00290       inline std::string& stripTrailing(std::string& s,
00291                                         const std::string& aString,
00292                                         std::string::size_type num = std::string::npos)
00293          throw(StringException);
00294 
00305       inline std::string stripTrailing(const std::string& s,
00306                                        const std::string& aString,
00307                                        std::string::size_type num = std::string::npos)
00308          throw(StringException)
00309       { std::string t(s); stripTrailing(t, aString, num); return t;}
00310 
00321       inline std::string& stripTrailing(std::string& s, 
00322                                         const char* pString, 
00323                                         std::string::size_type num = std::string::npos)
00324          throw(StringException)
00325       { return stripTrailing(s, std::string(pString), num); }
00326 
00337       inline std::string stripTrailing(const std::string& s, 
00338                                        const char* pString, 
00339                                        std::string::size_type num = std::string::npos)
00340          throw(StringException)
00341       { std::string t(s); stripTrailing(t, std::string(pString), num); return t; }
00342 
00353       inline std::string& stripTrailing(std::string& s, 
00354                                         const char aCharacter,
00355                                         std::string::size_type num = std::string::npos)
00356          throw(StringException)
00357       { return stripTrailing(s, std::string(1,aCharacter), num); }
00358 
00369       inline std::string stripTrailing(const std::string& s, 
00370                                        const char aCharacter,
00371                                        std::string::size_type num = std::string::npos)
00372          throw(StringException)
00373       { std::string t(s); stripTrailing(t, std::string(1,aCharacter), num); return t; }
00374 
00384       inline std::string& stripTrailing(std::string& s, 
00385                                         std::string::size_type num = std::string::npos)
00386          throw(StringException)
00387       { return stripTrailing(s, std::string(1,' '), num); }
00388 
00398       inline std::string stripTrailing(const std::string& s, 
00399                                        std::string::size_type num = std::string::npos)
00400          throw(StringException)
00401       { std::string t(s); stripTrailing(t, std::string(1,' '), num); return t;}
00402 
00413       inline std::string& strip(std::string& s, 
00414                                 const std::string& aString, 
00415                                 std::string::size_type num = std::string::npos)
00416          throw(StringException);
00417 
00418 
00429       inline std::string strip(const std::string& s, 
00430                                const std::string& aString, 
00431                                std::string::size_type num = std::string::npos)
00432          throw(StringException)
00433       { std::string t(s);  strip(t, aString, num); return t; }
00434 
00435 
00446       inline std::string& strip(std::string& s, 
00447                                 const char* pString,
00448                                 std::string::size_type num = std::string::npos)
00449          throw(StringException)
00450       { return strip(s, std::string(pString), num); }
00451 
00462       inline std::string strip(const std::string& s, 
00463                                const char* pString,
00464                                std::string::size_type num = std::string::npos)
00465          throw(StringException)
00466       { std::string t(s); strip(t, std::string(pString), num); return t; }
00467 
00478       inline std::string& strip(std::string& s, 
00479                                 const char aCharacter,
00480                                 std::string::size_type num = std::string::npos)
00481          throw(StringException)
00482       { return strip(s, std::string(1,aCharacter), num); }
00483 
00494       inline std::string strip(const std::string& s, 
00495                                const char aCharacter,
00496                                std::string::size_type num = std::string::npos)
00497          throw(StringException)
00498       { std::string t(s);  strip(t, std::string(1,aCharacter), num); return t;}
00499 
00509       inline std::string& strip(std::string& s, 
00510                                 std::string::size_type num = std::string::npos)
00511          throw(StringException)
00512       { return strip(s, std::string(1, ' '), num); }
00513 
00523       inline std::string strip(const std::string& s, 
00524                                std::string::size_type num = std::string::npos)
00525          throw(StringException)
00526       { std::string t(s);  strip(t, std::string(1, ' '), num); return t;}
00527 
00539       inline std::string translate(const std::string& aString,
00540                                    const std::string& inputChars,
00541                                    const std::string& outputChars,
00542                                    const char pad = ' ');
00543       
00563       inline std::string change(const std::string& aString,
00564                                 const std::string& inputString,
00565                                 const std::string& outputString,
00566                                 std::string::size_type startPos = 0,
00567                                 unsigned numChanges = (std::numeric_limits<unsigned>::max)());
00568 
00588       inline std::string& change(std::string& aString,
00589                                  const std::string& inputString,
00590                                  const std::string& outputString,
00591                                  std::string::size_type startPos = 0,
00592                                  unsigned numChanges = (std::numeric_limits<unsigned>::max)());
00593 
00605       inline std::string& rightJustify(std::string& s, 
00606                                        const std::string::size_type length, 
00607                                        const char pad = ' ')
00608          throw(StringException);
00609 
00621       inline std::string rightJustify(const std::string& s, 
00622                                       const std::string::size_type length, 
00623                                       const char pad = ' ')
00624          throw(StringException)
00625       { std::string t(s); return rightJustify(t, length, pad); }
00626 
00638       inline std::string& leftJustify(std::string& s,
00639                                       const std::string::size_type length,
00640                                       const char pad = ' ')
00641          throw(StringException);
00642 
00654       inline std::string leftJustify(const std::string& s,
00655                                      const std::string::size_type length,
00656                                      const char pad = ' ')
00657          throw(StringException)
00658       { std::string t(s); return leftJustify(t, length, pad); }
00659      
00677       inline std::string& center(std::string& s,
00678                                  const std::string::size_type length,
00679                                  const char pad = ' ')
00680          throw(StringException);
00681 
00700       inline std::string center(const std::string& s,
00701                                 const std::string::size_type length,
00702                                 const char pad = ' ')
00703          throw(StringException)
00704       { std::string t(s); return center(t, length, pad); }
00705 
00711       inline double asDouble(const std::string& s)
00712       { return strtod(s.c_str(), 0); }
00713      
00719       inline long asInt(const std::string& s)
00720       { return strtol(s.c_str(), 0, 10); }
00721      
00727       inline unsigned long asUnsigned(const std::string& s)
00728       { return strtoul(s.c_str(), 0, 10); }
00729      
00735       inline float asFloat(const std::string& s)
00736          throw(StringException);
00737 
00743       inline long double asLongDouble(const std::string& s)
00744          throw(StringException);
00745      
00753       template <class X>
00754       inline X asData(const std::string& s)
00755          throw(StringException);
00756 
00763       inline std::string asString(const long double x, 
00764                              const std::string::size_type precision = 21);
00765      
00772       inline std::string asString(const double x, 
00773                              const std::string::size_type precision = 17);
00774      
00781       template <class X>
00782       inline std::string asString(const X x);
00783      
00792       inline std::string& d2x(std::string& s)
00793          throw(StringException);
00794      
00804       inline std::string d2x(const std::string& s)
00805          throw(StringException)
00806       { std::string t(s);  return d2x(t); }
00807      
00816       inline std::string& x2d(std::string& s)
00817          throw(StringException);
00818      
00828       inline std::string x2d(const std::string& s)
00829          throw(StringException)
00830       { std::string t(s);  return x2d(t); }
00831      
00839       inline std::string& c2x(std::string& s)
00840          throw(StringException);
00841 
00847       inline std::string c2x(const std::string& s)
00848          throw(StringException)
00849       { std::string t(s);  return c2x(t); }
00850 
00857       inline unsigned int x2int(const std::string& s)
00858          throw(StringException);
00859 
00860 
00866       inline std::string int2x(const unsigned int& i)
00867          throw(StringException);
00868 
00876       inline std::string& replaceAll(std::string& s, 
00877                                      const std::string& oldString, 
00878                                      const std::string& newString )
00879          throw(StringException);
00880 
00888       inline bool isDigitString(const std::string& s);
00889 
00896       inline bool isDecimalString(const std::string& s);
00897 
00905       inline bool isScientificString(const std::string& s);
00906 
00914       inline bool isAlphaString(const std::string& s);
00915 
00932       inline std::string matches(const std::string& s,
00933                                  const std::string& aPattern,
00934                                  const char zeroOrMore = '*',
00935                                  const char oneOrMore = '+',
00936                                  const char anyChar = '.' )
00937          throw(StringException);
00938 
00954       inline bool isLike(const std::string& s, 
00955                          const std::string& aPattern,
00956                          const char zeroOrMore = '*', 
00957                          const char oneOrMore = '+',
00958                          const char anyChar = '.' )
00959          throw(StringException)
00960       { return matches(s, aPattern, zeroOrMore, oneOrMore, anyChar) !=
00961            std::string(); }
00962 
00963 
00979       inline bool isLike(const std::string& s, 
00980                          const char* pPattern,
00981                          const char zeroOrMore = '*', 
00982                          const char oneOrMore = '+',
00983                          const char anyChar = '.' )
00984          throw(StringException)
00985       { return matches(s, std::string(pPattern), 
00986                        zeroOrMore, oneOrMore, anyChar) !=  std::string(); }
00987      
00988      
01004       template <class T>
01005       std::string formattedPrint(const std::string& fmt, 
01006                                  const std::string& pat,
01007                                  const std::string& rep, 
01008                                  T to)
01009          throw(StringException);
01010 
01016       inline std::string subString(const std::string& s, 
01017                                    const std::string::size_type startPos = 0,
01018                                    const std::string::size_type length = std::string::npos,
01019                                    const char pad = ' ' )
01020          throw(StringException);
01021      
01028       inline std::string& lowerCase(std::string& s);
01029 
01036       inline std::string lowerCase(const std::string& s)
01037       { std::string t(s);  return lowerCase(t); }
01038 
01045       inline std::string& upperCase(std::string& s);
01046 
01053       inline std::string upperCase(const std::string& s)
01054       { std::string t(s);  return upperCase(t); }
01055 
01065       inline std::string memToString(const void* p, 
01066                                      const std::string::size_type size);
01067       
01075       inline std::string firstWord(const std::string& s, 
01076                                    const char delimiter = ' ')
01077          throw(StringException);
01078      
01086       inline int numWords(const std::string& s, 
01087                           const char delimiter = ' ')
01088          throw(StringException);
01089      
01102       inline std::string words(const std::string& s, 
01103                                const std::string::size_type firstWord = 0,
01104                                const std::string::size_type numWords = std::string::npos,
01105                                const char delimiter = ' ')
01106          throw(StringException);
01107      
01118       inline std::string word(const std::string& s, 
01119                               const std::string::size_type wordNum = 0,
01120                               const char delimiter = ' ')
01121          throw(StringException)
01122       { return words(s, wordNum, 1, delimiter); }
01123      
01132       inline std::string stripFirstWord(std::string& s, 
01133                                         const char delimiter = ' ')
01134          throw(StringException);
01135      
01146       inline std::string& removeWords(std::string& s, 
01147                                       const std::string::size_type first = 0, 
01148                                       const std::string::size_type wordsToReplace = std::string::npos,
01149                                       const char delimiter = ' ')
01150          throw(StringException);
01151 
01162       inline std::string doub2sci(const double& d, 
01163                                   const std::string::size_type length, 
01164                                   const std::string::size_type expLen,
01165                                   const bool showSign = true,
01166                                   const bool checkSwitch = true);
01167       
01183       inline std::string& sci2for(std::string& aStr, 
01184                                   const std::string::size_type startPos = 0,
01185                                   const std::string::size_type length = std::string::npos, 
01186                                   const std::string::size_type expLen = 3,
01187                                   const bool checkSwitch = true)
01188          throw(StringException);
01189 
01202       inline std::string doub2for(const double& d, 
01203                                   const std::string::size_type length, 
01204                                   const std::string::size_type expLen,
01205                                   const bool checkSwitch = true)
01206          throw(StringException);
01207 
01217       inline double for2doub(const std::string& aStr, 
01218                              const std::string::size_type startPos = 0,
01219                              const std::string::size_type length = std::string::npos);
01220       
01228       inline std::string printable(const std::string& aStr)
01229          throw(StringException);
01230 
01242       inline std::string& prettyPrint(std::string& aStr,
01243                                       const std::string& lineDelim = "\n",
01244                                       const std::string& indent = "",
01245                                       const std::string& firstIndent = "     ",
01246                                       const std::string::size_type len = 80,
01247                                       const char wordDelim = ' ')
01248          throw(StringException);
01249 
01261       inline std::string prettyPrint(const std::string& aStr,
01262                                      const std::string& lineDelim = "\n",
01263                                      const std::string& indent = "",
01264                                      const std::string& firstIndent = "     ",
01265                                      const std::string::size_type len = 80,
01266                                      const char wordDelim = ' ')
01267          throw(StringException)
01268       { 
01269          std::string temp(aStr); 
01270          prettyPrint(temp, lineDelim, indent, firstIndent, len, wordDelim); 
01271          return temp; 
01272       }
01273 
01280       inline std::vector<std::string> split(const std::string& aStr,
01281                                             const std::string& theDelimiters=" ",
01282                                             bool trimWhitespace = false, 
01283                                             bool ignoreEmpty = true)
01284       {
01285          std::vector<std::string> toReturn;
01286 
01287          std::string::size_type lastPos = aStr.find_first_not_of(theDelimiters, 0);         
01288          std::string::size_type pos     = aStr.find_first_of(theDelimiters, lastPos);      
01289 
01290          while (std::string::npos != pos || std::string::npos != lastPos)     
01291          {              
01292             std::string token = aStr.substr(lastPos, pos - lastPos);
01293 
01294             if(trimWhitespace) token = StringUtils::strip(token);
01295 
01296             if(!token.empty() || !ignoreEmpty) toReturn.push_back(token);  
01297 
01298             lastPos = aStr.find_first_not_of(theDelimiters, pos);              
01299             pos = aStr.find_first_of(theDelimiters, lastPos);     
01300          } 
01301 
01302          return toReturn;
01303       }
01304 
01305    } // namespace StringUtils
01306   
01307 } // namespace gpstk
01308 
01309 // ################################################
01310 //   Implementations of inline functions follow
01311 // ################################################
01312 
01313 namespace gpstk
01314 {
01315 
01316    namespace StringUtils
01317    {
01318       inline void hexDumpData(std::ostream& s, const std::string& data,
01319                               unsigned indent, HexDumpDataConfig cfg)
01320       {
01321          std::string instr(indent, ' ');
01322          hexDumpData(s, data, instr, cfg);
01323       }
01324 
01325       inline void hexDumpData(std::ostream& s, const std::string& data,
01326                               const std::string& tag, HexDumpDataConfig cfg)
01327       {
01328          std::string ascii="";
01329          unsigned indent = tag.length();
01330          int col = 0;
01331          int datasize=data.size();
01332          std::string groupws(cfg.groupWS, ' ');
01333          std::string group2ws(cfg.group2WS, ' ');
01334          std::string indexws(cfg.indexWS, ' ');
01335          std::string textws(cfg.textWS, ' ');
01336          unsigned linesize;
01337 
01338          if (cfg.groupBy && ((cfg.bytesPerLine % cfg.groupBy) != 0))
01339          {
01340             s << "hexDumpData: cfg.bytesPerLine % cfg.groupBy != 0"
01341               << std::endl;
01342             return;
01343          }
01344          if (cfg.group2By && ((cfg.bytesPerLine % cfg.group2By) != 0))
01345          {
01346             s << "hexDumpData: cfg.bytesPerLine % cfg.group2By != 0"
01347               << std::endl;
01348             return;
01349          }
01350          if (cfg.groupBy && ((cfg.group2By % cfg.groupBy) != 0))
01351          {
01352             s << "hexDumpData: cfg.group2By % cfg.groupBy != 0"
01353               << std::endl;
01354             return;
01355          }
01356 
01357             // line format:
01358             // <tag><index>:<indexws><group1byte1>...<group1byte[groupBy]><groupws>...<group[group2By]byte1>...<group[group2By]byte[groupBy]><group2ws>....<byte[bytesPerLine]><textws><separator><text><separator>\n
01359          linesize = indent;
01360          if (cfg.showIndex)
01361             linesize += cfg.idxDigits + 1 + cfg.indexWS;
01362          linesize += cfg.bytesPerLine * 2;
01363          unsigned w2 = 0;
01364          unsigned w1 = 0;
01365          if (cfg.group2By)
01366             w2 = (cfg.bytesPerLine / cfg.group2By) - 1;
01367          if (cfg.groupBy)
01368             w1 = (cfg.bytesPerLine / cfg.groupBy) - w2 - 1;
01369          if (cfg.groupBy > 0)
01370             linesize += cfg.groupWS * w1;
01371          if (cfg.group2By > 0)
01372             linesize += cfg.group2WS * w2;
01373             /*
01374               linesize doesn't include text stuff
01375          if (cfg.showText)
01376             linesize += cfg.textWS + cfg.bytesPerLine;
01377          if (cfg.separator)
01378             linesize += 2;
01379             */
01380 
01381          for (int i=0; i<datasize; i++)
01382          {
01383             if (i%cfg.bytesPerLine==0)
01384             {
01385                s << tag;
01386                col = indent;
01387                if (cfg.showIndex)
01388                {
01389                   if (cfg.hexIndex)
01390                   {
01391                      s << std::hex;
01392                      if (cfg.upperHex)
01393                         s << std::uppercase;
01394                      else
01395                         s << std::nouppercase;
01396                   }
01397                   else
01398                      s << std::dec;
01399                   s << std::setfill('0');
01400                   s << std::setw(cfg.idxDigits) << i << ":" << indexws;
01401                   s << std::dec << std::nouppercase;
01402                }
01403                col += cfg.idxDigits + 1 + cfg.indexWS;
01404             }
01405             unsigned char c=data[i];
01406             if (isprint(c))
01407                ascii += c;
01408             else
01409                ascii += '.';
01410             if (cfg.upperHex)
01411                s << std::uppercase;
01412             else
01413                s << std::nouppercase;
01414             s << std::hex << std::setw(2) << (int)c << std::dec
01415               << std::nouppercase;
01416             col += 2;
01417             if (((i % cfg.bytesPerLine) == (cfg.bytesPerLine-1)) ||
01418                 (i == (datasize-1)))
01419             {
01420                if (cfg.showText)
01421                {
01422                   int extra = linesize-col;
01423                   std::string space(extra, ' ');
01424                   s << space << textws;
01425                   if (cfg.separator)
01426                      s << cfg.separator;
01427                   s << ascii;
01428                   if (cfg.separator)
01429                      s << cfg.separator;
01430                   s << std::endl;
01431                }
01432                   // this *should* be updated at the beginning of the loop
01433                   //col=indent+6;
01434                ascii.erase();
01435             }
01436             else if (cfg.group2By && ((i % cfg.group2By) == (cfg.group2By-1)))
01437             {
01438                s << group2ws;
01439                col += cfg.group2WS;
01440             }
01441             else if (cfg.groupBy && ((i % cfg.groupBy) == (cfg.groupBy-1)))
01442             {
01443                s << groupws;
01444                col += cfg.groupWS;
01445             }
01446          }
01447       }
01448 
01449          // Keep searching for aString at the start of s
01450          // until num == 0 or aString is not found at the start of s
01451       inline std::string& stripLeading(std::string& s,
01452                                   const std::string& aString,
01453                                   std::string::size_type num)
01454          throw(StringException)
01455       {
01456          try
01457          {
01458             if (aString == "")
01459                return s;
01460 
01461             while((num > 0) &&
01462                   (s.find(aString,0) == 0) &&
01463                   (s.length() > 0))
01464             {      
01465                s.erase(0,aString.length());
01466                --num;
01467             }
01468             return s;
01469          }
01470          catch(std::exception &e)
01471          {
01472             StringException strexc("Exception thrown: " + std::string(e.what()));
01473             GPSTK_THROW(strexc);
01474          }
01475       }
01476 
01477          // keep searching for aString at the end of s
01478          // until aString isn't found there or num == 0
01479       inline std::string& stripTrailing(std::string& s,
01480                                    const std::string& aString,
01481                                    std::string::size_type num)
01482          throw(StringException)
01483       {
01484          try
01485          {
01486             std::string::size_type pos = s.length() - aString.length();
01487 
01488                // empty string, etc.
01489             if ((pos > s.length()) || (aString == ""))
01490                return s;
01491 
01492             while((num > 0) && 
01493                   (s.rfind(aString,pos) == pos) &&
01494                   (s.length() > 0))
01495             {
01496                s.erase(pos, std::string::npos);
01497                --num;
01498                pos = s.length() - aString.length();
01499             }
01500             return s;
01501          }
01502          catch(std::exception &e)
01503          {
01504             StringException strexc("Exception thrown: " + std::string(e.what()));
01505             GPSTK_THROW(strexc);
01506          }
01507       }
01508 
01509       inline std::string& strip(std::string& s, 
01510                            const std::string& aString, 
01511                            std::string::size_type num)
01512          throw(StringException)
01513       {
01514          stripLeading(s, aString, num);
01515          stripTrailing(s, aString, num);
01516          return s;
01517       }
01518 
01519       inline std::string translate(const std::string& aString,
01520                               const std::string& inputChars,
01521                               const std::string& outputChars,
01522                               const char pad)
01523       {
01524          std::string rv = aString;
01525          std::string::size_type aspos = 0;
01526          std::string::size_type inpos = std::string::npos;
01527          char toc = pad;
01528 
01529             // By starting at the last position, we avoid infinite
01530             // loops in case someone did something dumb, like, for
01531             // example, setting inputChars=outputChars.
01532          while ((aspos = rv.find_first_of(inputChars, aspos))
01533                 != std::string::npos)
01534          {
01535                // figure out which char we found;
01536             inpos = inputChars.find(rv[aspos]);
01537             if (outputChars.length()-1 < inpos)
01538                toc = pad;
01539             else
01540                toc = outputChars[inpos];
01541             rv[aspos] = toc;
01542 
01543             aspos++; // try to guarantee no infinite loops
01544          }
01545 
01546          return rv;
01547       }
01548 
01549       inline std::string change(const std::string& aString, const std::string& inputString,
01550                            const std::string& outputString,
01551                            std::string::size_type startPos, unsigned numChanges)
01552       {
01553          std::string rv(aString);
01554          change(rv, inputString, outputString, startPos, numChanges);
01555          return rv;
01556       }
01557 
01558       inline std::string& change(std::string& aString, const std::string& inputString,
01559                             const std::string& outputString,
01560                             std::string::size_type startPos, unsigned numChanges)
01561       { 
01562          unsigned count = 0;
01563          std::string::size_type opos = startPos;
01564 
01565          while (count < numChanges)
01566          {
01567             std::string::size_type pos = aString.find(inputString, opos);
01568             if (pos != std::string::npos)
01569             {
01570                count++;
01571                aString.replace(pos, inputString.length(), outputString);
01572                opos = pos + outputString.length();
01573             }
01574             else
01575                break;
01576          }
01577 
01578          return aString;
01579       }
01580 
01581          // if the string is bigger than length, truncate it from the left.
01582          // otherwise, add pad characters to it's left.
01583       inline std::string& rightJustify(std::string& s, 
01584                                   const std::string::size_type length, 
01585                                   const char pad)
01586          throw(StringException)
01587       {
01588          try
01589          {
01590             if(length < s.length())
01591             {
01592                s = s.substr(s.length()-length, std::string::npos);
01593             }
01594             else
01595             {
01596                s.insert((std::string::size_type)0, length-s.length(), pad);
01597             }
01598             return s;
01599          }
01600          catch(std::exception &e)
01601          {
01602             StringException strexc("Exception thrown: " + std::string(e.what()));
01603             GPSTK_THROW(strexc);
01604          }
01605       }
01606 
01607          // if the string is bigger than length, truncate it from the right.
01608          // otherwise, add pad characters to it's right.
01609       inline std::string& leftJustify(std::string& s,
01610                                  const std::string::size_type length,
01611                                  const char pad)
01612          throw(StringException)
01613       {
01614          try
01615          {
01616             if(length < s.length())
01617             {
01618                s = s.substr(0, length);
01619             }
01620             else
01621             {
01622                s.append(length-s.length(), pad);
01623             }
01624             return s;
01625          }
01626          catch(std::exception &e)
01627          {
01628             StringException strexc("Exception thrown: " + std::string(e.what()));
01629             GPSTK_THROW(strexc);
01630          }
01631       }
01632 
01633          // leftJustify if s is bigger than length.
01634          // otherwise, add pad to the left and right of s.
01635       inline std::string& center(std::string& s,
01636              const std::string::size_type length,
01637              const char pad)
01638          throw(StringException)
01639       { 
01640          try
01641          {
01642             if(length < s.length())
01643             {
01644                leftJustify(s, length, pad);
01645             }
01646             else {
01647                std::string::size_type leftOff = s.length() + (length - s.length()) / 2;
01648                leftJustify(s, leftOff, pad);
01649                rightJustify(s, length, pad);
01650             }
01651             return s;
01652          }
01653          catch(StringException &e)
01654          {
01655             GPSTK_RETHROW(e);
01656          }
01657          catch(std::exception &e)
01658          {
01659             StringException strexc("Exception thrown: " + std::string(e.what()));
01660             GPSTK_THROW(strexc);
01661          }
01662       } 
01663 
01664 
01665       inline float asFloat(const std::string& s)
01666          throw(StringException)
01667       {
01668          try
01669          {
01670             std::istringstream is(s);
01671             float f;
01672             is >> f;
01673             return f;
01674          }
01675          catch(std::exception &e)
01676          {
01677             StringException strexc("Exception thrown: " + std::string(e.what()));
01678             GPSTK_THROW(strexc);
01679          }
01680       }
01681 
01682       inline long double asLongDouble(const std::string& s)
01683          throw(StringException)
01684       {
01685          try
01686          {
01687             std::istringstream is(s);
01688             long double x;
01689             is >> x;
01690             return x;
01691          }
01692          catch(std::exception &e)
01693          {
01694             StringException strexc("Exception thrown: " + std::string(e.what()));
01695             GPSTK_THROW(strexc);
01696          }
01697       }
01698      
01699       template <class X>
01700       inline X asData(const std::string& s)
01701          throw(StringException)
01702       {
01703          try
01704          {
01705             std::istringstream is(s);
01706             X x;
01707             is >> x;
01708             return x;
01709          }
01710          catch(std::exception &e)
01711          {
01712             StringException strexc("Exception thrown: " + std::string(e.what()));
01713             GPSTK_THROW(strexc);
01714          }
01715       }
01716 
01717       inline std::string asString(const long double x, const std::string::size_type precision)
01718       {
01719          std::ostringstream ss;
01720          ss << std::fixed << std::setprecision(precision) << x ;
01721          return ss.str();
01722       }
01723      
01724       inline std::string asString(const double x, const std::string::size_type precision)
01725       {
01726          std::ostringstream ss;
01727          ss << std::fixed << std::setprecision(precision) << x;
01728          return ss.str();
01729       }
01730      
01731       template<class X>
01732       inline std::string asString(const X x) 
01733       {
01734          std::ostringstream ss;
01735          ss << x;
01736          return ss.str();
01737       }
01738      
01739          // decimal to hex...
01740       inline std::string& d2x(std::string& s)
01741          throw(StringException)
01742       {
01743          try
01744          {
01745                // remove the integer from s, including
01746                // leading spaces and 0's
01747             long l = asInt(s);
01748             stripLeading(s);
01749             stripLeading(s, "0");
01750             stripLeading(s, asString<long>(l));
01751             
01752                // put the int in a stringstream to convert it
01753             std::ostringstream st;
01754             st << std::hex << l << std::dec;
01755             
01756                // add the new hex to s
01757             s.insert(0, upperCase(st.str()) );
01758             
01759             return s;
01760          }
01761          catch(StringException &e)
01762          {
01763             GPSTK_RETHROW(e);
01764          }
01765          catch(std::exception &e)
01766          {
01767             StringException strexc("Exception thrown: " + std::string(e.what()));
01768             GPSTK_THROW(strexc);
01769          }
01770       }
01771 
01772          // character to hex...
01773       inline std::string& c2x(std::string& s)
01774          throw(StringException)
01775       {
01776          const char hexDigits[] = "0123456789ABCDEF";
01777          try
01778          {
01779             std::string old(s);
01780             const unsigned char *pSource = (unsigned char *)old.c_str();
01781             unsigned n = old.length();
01782 
01783             s.resize(n * 2, 0);
01784 
01785             for (int i = 0; i < (int)n * 2;)
01786             {
01787                unsigned char c = *pSource++;
01788                s[i++] = hexDigits[ c / 16 ];
01789                s[i++] = hexDigits[ c % 16 ];
01790             }
01791 
01792             return s;
01793          }
01794          catch(StringException &e)
01795          {
01796             GPSTK_RETHROW(e);
01797          }
01798          catch(std::exception &e)
01799          {
01800             StringException strexc("Exception thrown: " + std::string(e.what()));
01801             GPSTK_THROW(strexc);
01802          }
01803       }
01804 
01806           // hex to a long.
01807       inline unsigned int x2int(const std::string& s)
01808          throw (StringException)
01809       {
01810          try
01811          {
01812             std::string t(s);
01813                // remove the "0x" part, leading zeros and spaces from the 
01814                // string
01815                // ex. ' 0x003' -> '3'
01816             stripLeading(t);
01817             stripLeading(t, "0x", 1);
01818             stripLeading(t, "0");
01819             
01820                // if it's empty, it was 0
01821             if (t.empty())
01822             {
01823                return 0;
01824             }
01825 
01826                // make the stringstream, get the integer, and 
01827                // remove it from the string
01828             std::istringstream strstr(t);
01829             int i;
01830             strstr >> std::hex >> i;
01831             return i;
01832          }
01833          catch(StringException &e)
01834          {
01835             GPSTK_RETHROW(e);
01836          }
01837          catch(std::exception &e)
01838          {
01839             StringException strexc("Exception thrown: " + std::string(e.what()));
01840             GPSTK_THROW(strexc);
01841          }
01842       }
01843 
01845          // hex to decimal
01846       inline std::string& x2d(std::string& s)
01847          throw(StringException)
01848       {
01849          try
01850          {
01851                // remove the "0x" part, leading zeros and spaces from the 
01852                // string
01853                // ex. ' 0x003' -> '3'
01854             stripLeading(s);
01855             stripLeading(s, "0x", 1);
01856             stripLeading(s, "0");
01857             
01858                // make the stringstream, get the integer, and 
01859                // remove it from the string
01860             std::istringstream strstr(s);
01861             int i = 0;
01862             strstr >> std::hex >> i;
01863             stripLeading(s, asString<int>(asInt(s)), 1);
01864             
01865                // append the decimal to the existing string
01866             s.insert(0,asString<int>(i));
01867             return s;
01868          }
01869          catch(StringException &e)
01870          {
01871             GPSTK_RETHROW(e);
01872          }
01873          catch(std::exception &e)
01874          {
01875             StringException strexc("Exception thrown: " + std::string(e.what()));
01876             GPSTK_THROW(strexc);
01877          }
01878       }
01879      
01880       inline std::string int2x(const unsigned int& i)
01881          throw(StringException)
01882       {
01883          try
01884          {
01885             std::ostringstream ss;
01886             ss << std::hex << i;
01887             return ss.str();
01888          }
01889          catch(StringException &e)
01890          {
01891             GPSTK_RETHROW(e);
01892          }
01893          catch(std::exception &e)
01894          {
01895             StringException strexc("Exception thrown: " + std::string(e.what()));
01896             GPSTK_THROW(strexc);
01897          }
01898       }
01899 
01900       inline std::string& replaceAll(std::string& s, 
01901                                 const std::string& oldString, 
01902                                 const std::string& newString)
01903          throw(StringException)
01904       {
01905          try
01906          {
01907             int spot = s.find(oldString, 0);
01908             while (spot != (int)std::string::npos)
01909             {
01910                s.replace(spot, oldString.length(), newString);
01911                spot += newString.length();
01912                spot = s.find(oldString, spot);
01913             }
01914             return s;
01915          }
01916          catch(std::exception &e)
01917          {
01918             StringException strexc("Exception thrown: " + std::string(e.what()));
01919             GPSTK_THROW(strexc);
01920          }
01921       }
01922 
01923       inline bool isDigitString(const std::string& s)
01924       {
01925          if (s.size() == 0) 
01926             return false;
01927 
01928          std::string::size_type index = 0;
01929          if((s[0] == '-') || (s[0] == '+'))
01930             index++;
01931          for( ; index < s.size(); index++)
01932             if (!isdigit(s[index]))
01933                return false;
01934          return true;
01935       }
01936 
01937       inline bool isDecimalString(const std::string& s)
01938       {
01939          if (s.size() == 0) 
01940             return false;
01941 
01942          std::string::size_type index = 0;
01943          bool sawdot = false;
01944          if((s[0] == '-') || (s[0] == '+'))
01945             index++;
01946          for( ; index < s.size(); index++)
01947          {
01948             if (s[index] == '.')
01949             {
01950                if (sawdot)
01951                   return false;
01952                else sawdot = true;
01953             }
01954             else if (!isdigit(s[index]))
01955                return false;
01956          }
01957          return true;
01958       }
01959 
01960       inline bool isScientificString(const std::string& s)
01961       {
01962          if(s.size() == 0)
01963             return false;
01964 
01965          std::string::size_type pos = s.find_first_of("EeDd");
01966          if(pos == std::string::npos)
01967             return isDecimalString(s);
01968 
01969          std::string mant=s.substr(0,pos);
01970          std::string exp=s.substr(pos+1);
01971          return (isDecimalString(mant) && (exp.size()==0 || isDigitString(exp)));
01972       }
01973 
01974       inline bool isAlphaString(const std::string& s)
01975       {
01976          if (s.size() == 0) 
01977             return false;
01978 
01979          std::string::size_type index;
01980          for(index = 0; index < s.size(); index++)
01981             if (!isalpha(s[index]))
01982                return false;
01983          return true;
01984       }
01985 
01986       inline std::string matches(const std::string& s,
01987                                  const std::string& aPattern,
01988                                  const char zeroOrMore,
01989                                  const char oneOrMore,
01990                                  const char anyChar)
01991          throw(StringException)
01992       {
01993          const std::string::size_type regErrorBufSize = 512;
01994 
01995          std::string thisPattern(aPattern);
01996          std::string thisStr(s);
01997 
01998             // check if something other than the regex standard
01999             // characters (*,+,.) is used for those variables
02000          if (zeroOrMore != '*')
02001          {
02002             replaceAll(thisPattern, "*", "\\*");
02003             replaceAll(thisPattern, std::string(1, zeroOrMore), "*");
02004          }
02005          if (oneOrMore != '+')
02006          {
02007             replaceAll(thisPattern, "+", "\\+");
02008             replaceAll(thisPattern, std::string(1, oneOrMore), "+");
02009          }
02010          if (anyChar != '.')
02011          {
02012             replaceAll(thisPattern, ".", "\\.");
02013             replaceAll(thisPattern, std::string(1, anyChar), ".");
02014          }
02015          regmatch_t matches;
02016          regex_t regExp;
02017          char errorMsg[regErrorBufSize];
02018          int rc = regcomp(&regExp, thisPattern.c_str(), REG_EXTENDED);
02019 
02020          if (rc != 0)
02021          {
02022             regerror(rc, NULL, errorMsg, regErrorBufSize - 1);
02023             regfree(&regExp);
02024             StringException strerr("Regexp error: " + std::string(errorMsg));
02025             GPSTK_THROW(strerr);
02026          }
02027          rc = regexec(&regExp, thisStr.c_str(), 1, &matches, 
02028                       REG_NOTBOL | REG_NOTEOL);
02029          if ( (rc != 0) && (rc != REG_NOMATCH) )
02030          {
02031             regerror(rc, &regExp, errorMsg, regErrorBufSize - 1);
02032             regfree(&regExp);
02033             StringException strerr("Regexp error: " + std::string(errorMsg));
02034             GPSTK_THROW(strerr);
02035          }
02036 
02037          regfree(&regExp);
02038          if (rc == REG_NOMATCH)
02039             return std::string();
02040          else
02041             return thisStr.substr(matches.rm_so, matches.rm_eo - matches.rm_so);
02042       }
02043 
02044       template <class T>
02045       inline std::string formattedPrint(const std::string& fmt,
02046                                         const std::string& pat,
02047                                         const std::string& rep,
02048                                         T to)
02049          throw(StringException)
02050       {
02051          regex_t re;
02052          const size_t bufferSize = 513;
02053          char buffer[bufferSize];
02054          int rc = regcomp(&re, pat.c_str(), REG_EXTENDED);
02055             // if the regex doesnt compile, toast =)
02056          if ( rc != 0)
02057          {
02058             regerror(rc, NULL, buffer, bufferSize - 1);
02059             regfree(&re);
02060             StringException se("Regexp error: " + std::string(buffer));
02061             GPSTK_THROW(se);
02062          }
02063          
02064          regmatch_t r;
02065          std::string rv = fmt;
02066 
02067          while ( regexec(&re, rv.c_str(), 1, &r, 0) == 0 )
02068          {
02069             size_t len = r.rm_eo - r.rm_so;
02070             std::string mac = rv.substr(r.rm_so, len);
02071             mac = replaceAll(mac, rep.substr(0,1), rep.substr(1));
02072             sprintf(buffer, mac.c_str(), to);
02073             rv.replace(r.rm_so, len, std::string(buffer));
02074          }
02075          
02076          regfree(&re);
02077          return rv;
02078       }
02079       
02080       inline std::string subString(const std::string& s, 
02081                                    const std::string::size_type startPos,
02082                                    const std::string::size_type length,
02083                                    const char pad)
02084          throw(StringException)
02085       {
02086          try
02087          {
02088             if(startPos >= s.length())
02089             {
02090                return std::string(length, pad);
02091             }
02092             std::string temp = s.substr(startPos, length);
02093             return leftJustify(temp, length, pad);
02094          }
02095          catch(StringException &e)
02096          {
02097             GPSTK_RETHROW(e);
02098          }
02099          catch(std::exception &e)
02100          {
02101             StringException strexc("Exception thrown: " + std::string(e.what()));
02102             GPSTK_THROW(strexc);
02103          }
02104       }
02105 
02106       inline std::string& lowerCase(std::string& s)
02107       {
02108          for(std::string::size_type i = 0; i < s.length(); i++)
02109          {
02110             s[i] = tolower(s[i]);
02111          }
02112          return s;
02113       }
02114 
02115       inline std::string& upperCase(std::string& s)
02116       {
02117          for(std::string::size_type i = 0; i < s.length(); i++)
02118          {
02119             s[i] = toupper(s[i]);
02120          }
02121          return s;
02122       }
02123 
02124       inline std::string memToString(const void* p,
02125                                 const std::string::size_type size)
02126       {
02127          unsigned char* q = (unsigned char*)p;
02128          std::string s(size,'\0');
02129          for (int i=0; i<(int)size; i++)
02130          {
02131             s[i] = (unsigned char)(*q++);
02132          }
02133          return s;
02134       }
02135      
02136       inline std::string firstWord(const std::string& s, 
02137                               const char delimiter)
02138          throw(StringException)
02139       {
02140          try
02141          {
02142                // return s if there are no delimiters
02143             std::string::size_type pos = s.find_first_not_of(delimiter);
02144             if (pos == std::string::npos)
02145             {
02146                return s;
02147             }
02148                // find the end delimiter (if any) and return the string
02149             std::string::size_type endPos = s.find(delimiter, pos);
02150             if (endPos == std::string::npos)
02151             {
02152                return std::string(s, pos, endPos);
02153             }
02154             else
02155             {
02156                return std::string(s, pos, endPos - pos);
02157             }
02158          }
02159          catch(StringException &e)
02160          {
02161             GPSTK_RETHROW(e);
02162          }
02163          catch(std::exception &e)
02164          {
02165             StringException strexc("Exception thrown: " + std::string(e.what()));
02166             GPSTK_THROW(strexc);
02167          }
02168       }
02169      
02170       inline int numWords(const std::string& s, 
02171                           const char delimiter)
02172          throw(StringException)
02173       {
02174          try
02175          {
02176             std::string t(s);
02177             stripTrailing(t, delimiter);
02178             
02179             int words = 0;
02180             while(t.length())
02181             {
02182                stripLeading(t, delimiter);
02183                stripLeading(t, firstWord(t, delimiter));
02184                words++;
02185             }
02186             return words;
02187          }
02188          catch(StringException &e)
02189          {
02190             GPSTK_RETHROW(e);
02191          }
02192          catch(std::exception &e)
02193          {
02194             StringException strexc("Exception thrown: " + std::string(e.what()));
02195             GPSTK_THROW(strexc);
02196          }
02197       }
02198      
02199       inline std::string words(const std::string& s, 
02200                           const std::string::size_type firstWord,
02201                           const std::string::size_type numWords,
02202                           const char delimiter)
02203          throw(StringException)
02204       {
02205          try
02206          {
02207             if ((firstWord == 0) && (numWords == 1))
02208                return StringUtils::firstWord(s, delimiter);
02209             if (numWords == 0)
02210                return "";
02211             std::string::size_type wordNum = 0;
02212             std::string::size_type pos = 0, startPos = 0;
02213             
02214             std::string toReturn;
02215 
02216                // get position of word wordNum
02217             pos = s.find_first_not_of(delimiter, pos);
02218             while ((pos != std::string::npos) && (pos <= s.length()))
02219             {
02220                if (wordNum == firstWord)
02221                   startPos = pos;
02222                   // get first delimter after word wordNum
02223                pos = s.find(delimiter, pos);
02224                if (((int)numWords != -1) && ((int)wordNum == (int)(firstWord + (numWords-1))))
02225                   break;
02226                pos = s.find_first_not_of(delimiter, pos);
02227                wordNum++;
02228             }
02229 
02230             if (pos == std::string::npos)
02231                return s.substr(startPos);
02232             return s.substr(startPos, pos-startPos);
02233          }
02234          catch(StringException &e)
02235          {
02236             GPSTK_RETHROW(e);
02237          }
02238          catch(std::exception &e)
02239          {
02240             StringException strexc("Exception thrown: " + std::string(e.what()));
02241             GPSTK_THROW(strexc);
02242          }
02243       }
02244      
02245       inline std::string stripFirstWord(std::string& s, 
02246                                    const char delimiter)
02247          throw(StringException)
02248       {
02249          try
02250          {
02251             stripLeading(s, delimiter);
02252             std::string toReturn = firstWord(s, delimiter);
02253             stripLeading(s, toReturn);
02254             stripLeading(s, delimiter);
02255             return toReturn;
02256          }
02257          catch(StringException &e)
02258          {
02259             GPSTK_RETHROW(e);
02260          }
02261          catch(std::exception &e)
02262          {
02263             StringException strexc("Exception thrown: " + std::string(e.what()));
02264             GPSTK_THROW(strexc);
02265          }
02266       }
02267      
02268       inline std::string& removeWords(std::string& s, 
02269                                  const std::string::size_type first, 
02270                                  const std::string::size_type wordsToReplace,
02271                                  const char delimiter)
02272          throw(StringException)
02273       {
02274          try
02275          {
02276             std::string temp(s);
02277             std::string::size_type thisWord;
02278             
02279                // empty out s.  add the new parts of s as they are parsed
02280             s.erase(0, std::string::npos);
02281             
02282                // copy the part of the string through word 'first'
02283                // by appending any delimiters then appending
02284                // a word for however many words we're keeping.
02285             for(thisWord = 0; thisWord < first; thisWord++)
02286             {
02287                s.append(temp.find_first_not_of(delimiter),delimiter);
02288                stripLeading(temp, delimiter);
02289                s.append(firstWord(temp));
02290                stripLeading(temp, firstWord(temp));
02291             }
02292             
02293                // skip over the number of words to replace, making
02294                // sure to stop when there's no more string left
02295                // to skip
02296             for(thisWord = 0; 
02297                 (thisWord < wordsToReplace) && 
02298                    (temp.length() != 0);
02299                 thisWord++)
02300             {
02301                stripLeading(temp, delimiter);
02302                stripLeading(temp, firstWord(temp));
02303             }
02304             
02305                // add on any extra words at the end
02306             s.append(temp);
02307             
02308             return s;
02309          }
02310          catch(StringException &e)
02311          {
02312             GPSTK_RETHROW(e);
02313          }
02314          catch(std::exception &e)
02315          {
02316             StringException strexc("Exception thrown: " + std::string(e.what()));
02317             GPSTK_THROW(strexc);
02318          }
02319       }
02320 
02321       inline std::string doub2sci(const double& d, 
02322                              const std::string::size_type length, 
02323                              const std::string::size_type expLen,
02324                              const bool showSign,
02325                              const bool checkSwitch)
02326       {
02327          std::string toReturn;
02328          short exponentLength = expLen;
02329             
02330             /* Validate the assumptions regarding the input arguments */
02331          if (exponentLength < 0) exponentLength = 1;
02332          if (exponentLength > 3 && checkSwitch) exponentLength = 3;
02333             
02334          std::stringstream c;
02335          c.setf(std::ios::scientific, std::ios::floatfield);
02336             
02337             // length - 3 for special characters ('.', 'e', '+' or '-')
02338             // - exponentlength (e04)
02339             // - 1 for the digit before the decimal (2.)
02340             // and if showSign == true,
02341             //    an extra -1 for '-' or ' ' if it's positive or negative
02342          int expSize = 0;
02343          if (showSign)
02344             expSize = 1;
02345          c.precision(length - 3 - exponentLength - 1 - expSize);
02346 
02347             
02348          c << d;
02349             
02350          c >> toReturn;
02351 
02352          return toReturn;
02353       }
02354 
02355       inline std::string& sci2for(std::string& aStr, 
02356                              const std::string::size_type startPos,
02357                              const std::string::size_type length, 
02358                              const std::string::size_type expLen,
02359                              const bool checkSwitch)
02360          throw(StringException)
02361       {
02362          try
02363          {
02364             std::string::size_type idx = aStr.find('.', startPos);
02365             int expAdd = 0;
02366             std::string exp;
02367             long iexp;
02368               //If checkSwitch is false, always redo the exponential. Otherwise,
02369               //set it to false. 
02370             bool redoexp=!checkSwitch;
02371             
02372                // Check for decimal place within specified boundaries
02373             if ((idx == 0) || (idx >= (startPos + length - expLen - 1)))
02374             {
02375                StringException e("sci2for: no decimal point in string");
02376                GPSTK_THROW(e);
02377             }
02378             
02379                // Here, account for the possibility that there are
02380                // no numbers to the left of the decimal, but do not
02381                // account for the possibility of non-scientific
02382                // notation (more than one digit to the left of the
02383                // decimal)
02384             if (idx > startPos)
02385             {
02386                redoexp = true;
02387                   // Swap digit and decimal.
02388                aStr[idx] = aStr[idx-1];
02389                aStr[idx-1] = '.';
02390                   // Only add one to the exponent if the number is non-zero
02391                if (asDouble(aStr.substr(startPos, length)) != 0.0)
02392                   expAdd = 1;
02393             }
02394             
02395             idx = aStr.find('e', startPos);
02396             if (idx == std::string::npos)
02397             {
02398                idx = aStr.find('E', startPos);
02399                if (idx == std::string::npos)
02400                {
02401                   StringException e("sci2for:no 'e' or 'E' in string");
02402                   GPSTK_THROW(e);
02403                }
02404             }
02405                // Change the exponent character to D normally, or E of checkSwitch is false.
02406             if (checkSwitch)
02407                aStr[idx] = 'D';
02408             else 
02409                aStr[idx] = 'E';
02410                
02411                // Change the exponent itself
02412             if (redoexp)
02413             {
02414                exp = aStr.substr(idx + 1, std::string::npos);
02415                iexp = asInt(exp);
02416                iexp += expAdd;
02417 
02418                aStr.erase(idx + 1);
02419                if (iexp < 0)
02420                {
02421                   aStr += "-";
02422                   iexp -= iexp*2;
02423                }
02424                else
02425                   aStr += "+";
02426                aStr += rightJustify(asString(iexp),expLen,'0');
02427 
02428             }
02429 
02430                // if the number is positive, append a space
02431                // (if it's negative, there's a leading '-'
02432             if (aStr[0] == '.')
02433             {
02434                aStr.insert((std::string::size_type)0, 1, ' ');
02435             }
02436             
02437                //If checkSwitch is false, add on one leading zero to the string
02438             if (!checkSwitch)
02439             {
02440                aStr.insert((std::string::size_type)1, 1, '0');
02441             }
02442             
02443             
02444             return aStr;
02445          }
02446          catch(StringException &e)
02447          {
02448             GPSTK_RETHROW(e);
02449          }
02450          catch(std::exception &e)
02451          {
02452             StringException strexc("Exception thrown: " + std::string(e.what()));
02453             GPSTK_THROW(strexc);
02454          }
02455       }  // end sci2for
02456 
02457 
02458       inline std::string doub2for(const double& d, 
02459                              const std::string::size_type length, 
02460                              const std::string::size_type expLen,
02461                              const bool checkSwitch)
02462          throw(StringException)
02463       {
02464          try
02465          {
02466             short exponentLength = expLen;
02467             
02468                /* Validate the assumptions regarding the input arguments */
02469             if (exponentLength < 0) exponentLength = 1;
02470             if (exponentLength > 3 && checkSwitch) exponentLength = 3;
02471 
02472             std::string toReturn = doub2sci(d, length, exponentLength, true, checkSwitch);
02473             sci2for(toReturn, 0, length, exponentLength, checkSwitch);
02474          
02475             return toReturn;
02476          }
02477          catch(StringException &e)
02478          {
02479             GPSTK_RETHROW(e);
02480          }
02481          catch(std::exception &e)
02482          {
02483             StringException strexc("Exception thrown: " + std::string(e.what()));
02484             GPSTK_THROW(strexc);
02485          }
02486       }
02487       
02488       
02489       inline double for2doub(const std::string& aStr,
02490                              const std::string::size_type startPos,
02491                              const std::string::size_type length) 
02492       {
02493          std::string s(aStr, startPos, length);
02494          strip(s);
02495 
02496             // you can blame Rinex for these special checks
02497          if (s.empty())
02498          {
02499             return 0;
02500          }
02501 
02502          std::string::size_type pos = s.find_first_of("EDd");
02503          if (pos != std::string::npos)
02504          {
02505             s[pos] = 'e';
02506          }
02507          else
02508          {
02509                // just treat it like a double
02510             return asDouble(aStr.substr(startPos, length));
02511          }
02512          
02513          std::stringstream st;
02514          st << s;
02515          
02516          double d;
02517          st >> d;
02518          
02519          return d;
02520       }
02521 
02522       inline std::string printable(const std::string& aStr)
02523          throw(StringException)
02524       {
02525          try
02526          {
02527             std::string rv(aStr);
02528 
02529             for (int i = 0; i < (int)rv.length(); i++)
02530             {
02531                char c = rv[i];
02532                if (!isprint(c))
02533                {
02534                   if (iscntrl(c))
02535                   {
02536                      rv.replace(i,1,2,'^');
02537                      rv.replace(i+1,1,1, 64+(c));
02538                   }
02539                   else
02540                   {
02541                      std::string mess(c2x(rv.substr(i,1)));
02542                      rv.replace(i,1,"<"+mess+">");
02543                   }
02544                }
02545             }
02546 
02547             return rv;
02548          }
02549          catch(StringException &e)
02550          {
02551             GPSTK_RETHROW(e);
02552          }
02553          catch(std::exception &e)
02554          {
02555             StringException strexc("Exception thrown: " + std::string(e.what()));
02556             GPSTK_THROW(strexc);
02557          }
02558       }
02559 
02560       inline std::string& prettyPrint(std::string& aStr,
02561                                       const std::string& lineDelim,
02562                                       const std::string& indent,
02563                                       const std::string& firstIndent,
02564                                       const std::string::size_type len,
02565                                       const char wordDelim)
02566          throw(StringException)
02567       {
02568          try
02569          {
02570                // chop aStr up into words based on wordDelim
02571             std::list<std::string> wordList;
02572             std::string tempStr(aStr);
02573             stripLeading(tempStr, wordDelim);
02574             while (!tempStr.empty())
02575             {
02576                std::string theFirstWord = firstWord(tempStr,wordDelim);
02577                wordList.push_back(theFirstWord);
02578                stripLeading(tempStr, theFirstWord);
02579                stripLeading(tempStr, wordDelim);
02580             }
02581 
02582                // now reassemble the words into sentences
02583             std::string toReturn;
02584             std::string thisLine = firstIndent, lastLine;
02585             while (!wordList.empty())
02586             {
02587                lastLine = thisLine;
02588                if (!lastLine.empty())
02589                   thisLine += wordDelim;
02590                thisLine += wordList.front();
02591 
02592                if (thisLine.length() > len)
02593                {
02594                      // if the first word is longer than a line, just add it.
02595                      // if this is the first line, remember to add the indent.
02596                   if (lastLine.empty())
02597                   {
02598                      if (toReturn.empty())
02599                         lastLine += firstIndent;
02600                      lastLine = wordList.front();
02601                   }
02602 
02603                   toReturn += lastLine + lineDelim;
02604 
02605                   thisLine.erase();
02606                   lastLine.erase();
02607 
02608                   thisLine = indent;
02609                }
02610                else
02611                   wordList.erase(wordList.begin());
02612             }
02613             if (!thisLine.empty())
02614                toReturn += (thisLine + lineDelim);
02615 
02616             aStr = toReturn;
02617             return aStr;
02618          }
02619          catch(StringException &e)
02620          {
02621             GPSTK_RETHROW(e);
02622          }
02623          catch(std::exception &e)
02624          {
02625             StringException strexc("Exception thrown: " + std::string(e.what()));
02626             GPSTK_THROW(strexc);
02627          }
02628       }
02629 
02631 
02632    } // namespace StringUtils
02633 
02634 } // namespace gpstk
02635 #endif // GPSTK_STRINGUTILS_HPP
02636 
02637 
02638 

Generated on Thu Feb 9 03:31:01 2012 for GPS ToolKit Software Library by  doxygen 1.3.9.1