AaronCameron.net
I care not for your petty politics.
Not a Member? - Login or Create an Account
Thursday the 24th of May 2012 @ 01:03am
Front Page Journal Projects Your Profile About
[]

LibN2L-4 Library Code Reference

Classes
Compounds
Files
Members
Method Index
Full Reference

stringUtilities.cpp

Go to the documentation of this file.
00001 /************************************************************************
00002 Nova-2 Library (libN2L, or simply n2l) Game development C++ Library
00003 Copyright (C) 2003  Aaron Cameron
00004 
00005 This library is free software; you can redistribute it and/or
00006 modify it under the terms of the GNU Lesser General Public
00007 License as published by the Free Software Foundation; either
00008 version 2.1 of the License, or (at your option) any later version.
00009 
00010 This library is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 Lesser General Public License for more details.
00014 
00015 You should have received a copy of the GNU Lesser General Public
00016 License along with this library; if not, write to the Free Software
00017 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00018 
00019 A copy of the GNU Lesser General Public License has been provided with
00020 this library in the file 'COPYING'.
00021 
00022 Contact information for the author of this library has been provided
00023 with this library in the file 'AUTHOR'.
00024 ************************************************************************/
00025 #include "stringUtilities.h"
00026 
00027 #include "cParsingException.h"
00028 
00029 using namespace std;
00030 
00031 namespace n2l {
00032 
00033     /* ************************************************************ */
00034     const tString getEscapedString( const tString & i_str,
00035                                     const tString & i_targetChars,
00036                                     const char i_escapeChar )
00037     {
00038         tString output, modTargetChars(1,i_escapeChar);
00039 
00040         // Do some basic tests
00041         if (!i_str.size()) return "";
00042         if (!i_targetChars.size()) return i_str;
00043 
00044         modTargetChars += i_targetChars;
00045 
00046         tString::const_iterator targetChar = modTargetChars.begin();
00047         const tString::const_iterator TargetCharsEnd = modTargetChars.end();
00048         
00049         tString::const_iterator strChar = i_str.begin();
00050         const tString::const_iterator StrCharsEnd = i_str.end();
00051 
00052         while (StrCharsEnd != strChar) {
00053             targetChar = modTargetChars.begin();
00054             while (TargetCharsEnd != targetChar) {
00055                 if ((*strChar)==(*targetChar))
00056                     output += i_escapeChar;
00057                 ++targetChar;
00058              } // while (TargetCharsEnd!=targetChar)
00059             output += *strChar;
00060             ++strChar;
00061          } // while (StrCharsEnd != strChar)
00062         return output;
00063     }
00064 
00065 
00066     /* ************************************************************ */
00067     const tString unescapedString(  const tString & iStr,
00068                                     const char iEscapeChar,
00069                                     const char iQuoteChar )
00070     {
00071         tString temp;
00072         temp.reserve(iStr.size());  // Just to avoid resizes like mad.
00073         tString::size_type cPos = 0;
00074         const tString::size_type EPos = iStr.size();
00075         for (; cPos<EPos; ++cPos)
00076         {
00077             if (iStr[cPos]==iQuoteChar) continue;
00078             if (iStr[cPos]==iEscapeChar) {
00079                 ++cPos; // Add the next character, regardless, then skip
00080                 if (cPos==EPos) continue;
00081                 temp += iStr[cPos];
00082                 continue;
00083             }
00084             temp += iStr[cPos];
00085         }
00086         return temp;
00087     }
00088 
00089 
00090     /* ************************************************************ */
00091     const tString implode(  const vector<tString> & o_tokens,
00092                             const char i_splitChar,
00093                             const char i_escapeChar,
00094                             const char i_quoteChar )
00095     {
00096         tString output;
00097         tString escapeTargetChars;
00098 
00099         if ('\0'!=i_quoteChar)
00100             escapeTargetChars += i_quoteChar;
00101         else escapeTargetChars += i_splitChar;
00102         
00103         vector<tString>::const_iterator token = o_tokens.begin();
00104         const vector<tString>::const_iterator TokensEnd = o_tokens.end();
00105         while (TokensEnd!=token) {
00106             if ('\0'!=i_quoteChar) output += i_quoteChar;
00107             output += getEscapedString(*token, escapeTargetChars, i_escapeChar);
00108             if ('\0'!=i_quoteChar) output += i_quoteChar;
00109             ++token;
00110             if (TokensEnd!=token) output += i_splitChar;
00111          }
00112         return output;
00113     }
00114 
00115 
00116     /* ************************************************************ */
00117     void explode(   const tString & i_str,
00118                     vector<tString> & o_tokens,
00119                     const char i_splitChar,
00120                     const char i_escapeChar,
00121                     const char i_quoteChar,
00122                     const tBool iStripEscapes )
00123     {
00124         tBool quoted = false;
00125         tString token;
00126         tString::const_iterator currentChar = i_str.begin();
00127         const tString::const_iterator CurrentCharsEnd = i_str.end();
00128         while (CurrentCharsEnd>currentChar) {
00129             // Do we take the next character at face value
00130             if ((*currentChar)==i_escapeChar) {
00131                 ++currentChar;
00132                 if (CurrentCharsEnd==currentChar)
00133                     throw cParsingException("explode",
00134                                             "Escape at end of buffer",
00135                                             i_str,
00136                                             "eos" );
00137 
00138                 token += *currentChar;
00139                 ++currentChar;
00140                 continue;
00141              }
00142 
00143             // Check it for a quoteable regions
00144             if ((*currentChar)==i_quoteChar) {
00145                 quoted = !quoted;
00146                 if (!iStripEscapes) token += i_quoteChar;
00147                 ++currentChar;
00148                 continue;
00149              }
00150 
00151             // Check for split characters
00152             if ( ((*currentChar)==i_splitChar) && (!quoted) ) {
00153                 o_tokens.push_back(token);
00154                 token = "";
00155                 ++currentChar;
00156                 continue;
00157              }
00158 
00159             token += (*currentChar);
00160             ++currentChar;
00161          }
00162         // Flush the final token
00163         o_tokens.push_back(token);
00164     }
00165 
00166 
00167     /* ************************************************************ */
00168     const bool inArray( const tString & iStr,
00169                         const vector<tString> & iArray )
00170     {
00171         const vector<tString>::const_iterator EndOfArray = iArray.end();
00172         vector<tString>::const_iterator element = iArray.begin();
00173         while (EndOfArray != element)
00174             if (*element == iStr) return true;
00175         return false;
00176     }
00177 
00178 
00179     /* ************************************************************ */
00180     const tString::size_type findUnescaped( const tString & i_str,
00181                                             const char i_char,
00182                                             const tString::size_type i_sPos,
00183                                             const char i_escapeChar,
00184                                             const char i_quoteChar )
00185     {
00186         const tString::size_type S = i_str.size();
00187         if ((!S)||(S<=i_sPos)) return tString::npos;
00188 
00189         bool quoted = false;
00190 
00191         for ( tString::size_type pos = i_sPos; S>pos; ++pos ) {
00192             if (i_escapeChar == i_str[pos]) ++pos;  // Skip the escaped character
00193             else if (i_quoteChar == i_str[pos]) { quoted = !quoted;  continue; }
00194             else if (quoted) continue;
00195             else if (i_char == i_str[pos]) return pos;
00196          }
00197         return tString::npos;
00198     }
00199 
00200 
00201     /* ************************************************************ */
00202     const tString::size_type rfindUnescaped(    const tString & i_str,
00203                                             const char i_char,
00204                                             const tString::size_type i_sPos,
00205                                             const char i_escapeChar,
00206                                             const char i_quoteChar )
00207     {
00208         const tString::size_type S = i_str.size();
00209         if (!S) return tString::npos;
00210         
00211         bool quoted = false;
00212 
00213         for ( tString::size_type pos = min(i_sPos,(S-1)); pos!=0; --pos ) {
00214             if (i_escapeChar == i_str[pos-1]) --pos;    // Skip the escaped character
00215             else if (i_quoteChar == i_str[pos]) { quoted = !quoted;  continue; }
00216             else if (quoted) continue;
00217             else if (i_char == i_str[pos]) return pos;
00218          }
00219         // We couldn't check this in the loop because of the escapes
00220         if (i_str[0]==i_char) return 0;
00221         return tString::npos;
00222     }
00223 
00224     /* ************************************************************ */
00225     const tString substringReplace( const tString & i_from,
00226                                     const tString & i_to,
00227                                     const tString & i_hayStack )
00228     {
00229         tString::size_type seekPos = 0;
00230         tString::size_type symbolPos = 0;
00231         const tString::size_type FromSize = i_from.size();
00232         const tString::size_type ToSize = i_to.size();
00233         tString newStr(i_hayStack);
00234         do {
00235             symbolPos = newStr.find(i_from, seekPos);
00236             if (symbolPos == tString::npos) return newStr;
00237             if (ToSize) newStr.replace(symbolPos,FromSize, i_to);
00238             else newStr.erase(symbolPos,FromSize);
00239             seekPos = symbolPos+ToSize;
00240             if (seekPos>=newStr.size()) return newStr;
00241          } while (true);
00242     }
00243 
00244     /* ************************************************************ */
00245     const tString trimmed( const tString & iStr )
00246     {
00247         const tString::size_type SPos = iStr.find_first_not_of(" \t\n");
00248         if (SPos==tString::npos) return "";
00249         const tString::size_type EPos = iStr.find_last_not_of(" \t\n");
00250         // If the front seek found something, the end must have too.
00251         return iStr.substr(SPos,EPos-SPos+1);
00252     }
00253 
00254     /* ************************************************************ */
00255     const tString strToUpper( const tString &iStr )
00256     {
00257         const tString::size_type StrSize = iStr.size();
00258         tString temp( iStr );
00259         for (tString::size_type c=0; c<StrSize; ++c)
00260             if (iStr[c]>='a' && iStr[c]<='z')
00261                 temp[c] = iStr[c]-32;
00262         return temp;
00263     }
00264 
00265     /* ************************************************************ */
00266     const tString strToLower( const tString &iStr )
00267     {
00268         const tString::size_type StrSize = iStr.size();
00269         tString temp( iStr );
00270         for (tString::size_type c=0; c<StrSize; ++c)
00271             if (iStr[c]>='A' && iStr[c]<='Z')
00272                 temp[c] = iStr[c]+32;
00273         return temp;
00274     }
00275 
00276  } // namespace n2l
©2012 Aaron Cameron