![[]](/images/special/trans.gif)
LibN2L-4 Library Code ReferenceClassesCompounds Files Members Method Index Full Reference stringUtilities.cppGo 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 |