00001 #ifndef OC_STRING_H
00002 #define OC_STRING_H
00003
00004 #include <string>
00005 #include <algorithm>
00006 #include <sstream>
00007 #include <regex.h>
00008
00009 using namespace std;
00010
00011
00012
00013 template<class T> string & ocAppend( string & inStr, T inVar )
00014 {
00015
00016 stringstream s;
00017 s << inVar;
00018 inStr += s.str();
00019 return inStr;
00020 }
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 class ocString: public string
00031 {
00032 private:
00033 string retVal;
00034 string::size_type idx;
00035 bool eop;
00036 int regex_status;
00037 public:
00038
00039 ocString():string(),retVal(""),idx(0),eop(false),regex_status(0){;}
00040 ocString( const char * in ):string(in),retVal(""),idx(0),eop(false),regex_status(0){;}
00041 ocString( const string & in ):string(in),retVal(""),idx(0),eop(false),regex_status(0){;}
00042
00043
00044 inline ocString & operator = ( const string & in ){ return operator=(in.c_str());}
00045 inline string & parse( const string & pattern ){ return parse(pattern.c_str());}
00046 inline ocString replace( const string & pattern, const string & replacement ){ return replace(pattern.c_str(),replacement.c_str()); }
00047 inline ocString replaceAll( const string & pattern, const string & replacement ){ return replaceAll(pattern.c_str(),replacement.c_str()); }
00048 inline ocString remove( const string & pattern ){ return remove( pattern.c_str()); }
00049
00050 ocString & operator = ( const char * in )
00051 {
00052 string::operator = ( in );
00053 parseInit();
00054 return *this;
00055 }
00056
00057
00058 template<class T> ocString & append( T inVar )
00059 {
00060 ocAppend( *this, inVar );
00061 return *this;
00062 }
00063 virtual ~ocString(){;}
00064
00065
00066
00067 void parseInit( void )
00068 {
00069 retVal = "";
00070 idx=0;
00071 eop = false;
00072 }
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 string & parse( const char * pattern )
00088 {
00089 string::size_type idxStart;
00090 retVal="";
00091 if( pattern && strlen( pattern ) && !eop )
00092 {
00093 idxStart = this->find( pattern, idx );
00094 if(idxStart != string::npos )
00095 {
00096 retVal = this->substr(idx,idxStart-idx);
00097 idx = idxStart+strlen(pattern);
00098 }
00099 else
00100 {
00101 retVal = this->substr(idx);
00102 idx=0;
00103 eop=true;
00104 }
00105 }
00106 return retVal;
00107 }
00108
00109
00110
00111
00112
00113
00114 string & tokenParse( string tokens )
00115 {
00116 enum { before, inside, after, ended } cpos = before;
00117 retVal="";
00118 if( tokens.length() && !eop )
00119 {
00120 string::size_type idxStart = idx, idxEnd = 0;
00121 while( cpos != ended && idx < size() )
00122 {
00123 char test = this->operator[](idx);
00124 if( cpos == before )
00125 {
00126
00127 if( tokens.find(test) == string::npos )
00128 {
00129 cpos = inside;
00130 idxStart = idx;
00131 }
00132 }
00133 else if( cpos == inside )
00134 {
00135
00136 if( tokens.find(test) != string::npos )
00137 {
00138 cpos = after;
00139 idxEnd = idx;
00140 }
00141 }
00142 else if( cpos==after )
00143 {
00144
00145 if( tokens.find(test) == string::npos )
00146 {
00147 cpos = ended;
00148 break;
00149 }
00150 }
00151 ++idx;
00152 }
00153 if( idxEnd > idxStart )
00154 {
00155 retVal = this->substr(idxStart,idxEnd-idxStart);
00156 }
00157 else
00158 {
00159 retVal = this->substr(idxStart);
00160 idx=0;
00161 eop=true;
00162 }
00163 }
00164 return retVal;
00165 }
00166
00170 string & remainder( void )
00171 {
00172 retVal = this->substr(idx);
00173 return retVal;
00174 }
00175
00176
00177
00178
00179
00180
00181
00182 ocString replace( const char * pattern, const char * replacement )
00183 {
00184 string::size_type idxPattern;
00185 retVal="";
00186 if( pattern )
00187 {
00188 size_t ptrnLen = strlen( pattern );
00189 if( ptrnLen > 0 )
00190 {
00191 idxPattern = this->find( pattern );
00192 if(idxPattern != string::npos )
00193 {
00194 retVal = this->substr(0, idxPattern );
00195 if( replacement && strlen(replacement) )
00196 {
00197 retVal += replacement;
00198 }
00199 retVal += this->substr(idxPattern+ptrnLen);
00200 }
00201 }
00202 }
00203
00204 if( retVal.length() == 0 ) retVal = *this;
00205 return retVal;
00206 }
00207
00208
00209
00210
00211
00212 ocString replaceAll( const char * pattern, const char * replacement )
00213 {
00214 string::size_type idxPattern, idxFrom;
00215 retVal="";
00216
00217 if( pattern )
00218 {
00219 size_t ptrnLen = strlen( pattern );
00220
00221 if( ptrnLen > 0 )
00222 {
00223 idxFrom = 0;
00224 idxPattern = this->find( pattern );
00225 while(idxPattern != string::npos )
00226 {
00227 retVal += this->substr(idxFrom, idxPattern-idxFrom );
00228 if( replacement && strlen(replacement) )
00229 {
00230 retVal += replacement;
00231 }
00232 idxFrom = idxPattern+ptrnLen;
00233 idxPattern = this->find( pattern, idxFrom );
00234 }
00235
00236 retVal += this->substr(idxFrom);
00237 }
00238 }
00239 return retVal;
00240 }
00241
00242
00243
00244
00245
00246 ocString remove( const char * pattern )
00247 {
00248 string::size_type idxPattern;
00249 retVal=*this;
00250 if( pattern )
00251 {
00252 size_t ptrnLen = strlen( pattern );
00253 if( ptrnLen > 0 )
00254 {
00255 idxPattern = this->find( pattern );
00256 if(idxPattern != string::npos )
00257 {
00258 retVal.erase(idxPattern, ptrnLen);
00259 }
00260 }
00261 }
00262 return retVal;
00263 }
00264
00265
00266
00267
00268 string::size_type lastPos( void )
00269 {
00270 return idx;
00271 }
00276 bool endOfParse(void)
00277 {
00278 return eop;
00279 }
00280
00281
00282
00283 ocString titleCase( void )
00284 {
00285 string::iterator pos;
00286 retVal="";
00287 bool wasWhiteSpace = false;
00288 for( pos=begin(); pos!=end(); ++pos )
00289 {
00290 char ch = *pos;
00291 if(wasWhiteSpace || pos==begin() )
00292 {
00293 retVal += toupper(ch);
00294 }
00295 else
00296 {
00297 retVal += tolower(ch);
00298 }
00299 if( isalpha(ch) || ch=='\'' )
00300 {
00301 wasWhiteSpace = false;
00302 }
00303 else
00304 {
00305 wasWhiteSpace = true;
00306 }
00307 }
00308 return retVal;
00309 }
00310 bool regExMatch( const char *pattern )
00311 {
00312 const char *string = c_str();
00313 regex_t re;
00314 regex_status = regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|RE_BACKSLASH_ESCAPE_IN_LISTS);
00315 if ( regex_status != 0)
00316 {
00317 return(false);
00318 }
00319 regex_status = regexec(&re, string, (size_t) 0, NULL, 0);
00320 regfree(&re);
00321 if (regex_status != 0)
00322 {
00323 return(false);
00324 }
00325 return(true);
00326
00327 }
00328 int RegExStatus( void )
00329 {
00330 return regex_status;
00331 }
00332
00333 unsigned long makeHash( void )
00334 {
00335 unsigned long hash = 0;
00336 const char * str = this->c_str();
00337 int c;
00338 while ( (c = (unsigned int) (*str++)) ) hash = c + (hash << 6) + (hash << 16) - hash;
00339 return hash;
00340 }
00341 };
00342
00343 #endif
00344
00345 #ifdef IN_T2_TESTHARNESS
00346
00347 cout << "=======================================" << endl;
00348 ocString thingy("This is \n\tSome parsable data");
00349 while( !thingy.endOfParse() )
00350 {
00351 cout << "Parsing: [" << thingy.tokenParse(" \t\n\r" ) << "]" << endl;
00352 }
00353 thingy.parseInit();
00354 cout << "=======================================" << endl;
00355 while( !thingy.endOfParse() )
00356 {
00357 cout << "Parsing: [" << thingy.parse(" ") << "]" << endl;
00358 }
00359
00360 cout << "checking out reg exp matching" << endl;
00361 thingy = "david.mc@w3.sys.com";
00362 cout << thingy.regExMatch("^[a-z\\.A-Z1-9\\-]+@[a-z\\.A-Z1-9\\-]+$") << " should be true" << endl;
00363 thingy = "david-mc@w3-sys.com";
00364 cout << thingy.regExMatch("^[a-z\\.A-Z1-9\\-]+@[a-z\\.A-Z1-9\\-]+$") << " should be true" << endl;
00365 thingy = "david9mcw3.sys9.com";
00366 cout << thingy.regExMatch("^[a-z\\.A-Z1-9\\-]+@[a-z\\.A-Z1-9\\-]+$") << " should be false" << endl;
00367 thingy = "david.mcw@";
00368 cout << thingy.regExMatch("^[a-z\\.A-Z1-9\\-]+@[a-z\\.A-Z1-9\\-]+$") << " should be false" << endl;
00369 thingy = "Hutch0099@cs.com";
00370 cout << thingy.regExMatch("^[a-z\\.A-Z0-9\\-]+@[a-z\\.A-Z0-9\\-]+$") << " should be true" << endl;
00371 cout << thingy.RegExStatus() << endl;
00372
00373 thingy = "something.cgi?isPDF=1";
00374 cout << thingy << " " << thingy.find("isPDF") << endl;
00375 cout << thingy << " " << thingy.regExMatch("isPDF") << endl;
00376
00377
00378
00379
00380
00381
00382
00383
00384 cout << "String is 'gooby gotta go'" << endl;
00385
00386 thingy = "gooby gotta go";
00387
00388 cout << "Match pattern = '(go|do)'" << endl;
00389
00390 cout << thingy.regExMatch("(go|do)") << " should be true" << endl;
00391
00392
00393
00394 ocString hashable = "Big Goofy String";
00395 cout << hashable << " hash value is " << hashable.makeHash() << endl;
00396 hashable = "Profound";
00397 cout << hashable << " hash value is " << hashable.makeHash() << endl;
00398 hashable = "The eclipse burdened the mood with gloom, even on the bright side, if there were such.";
00399 cout << hashable << " hash value is " << hashable.makeHash() << endl;
00400
00401 #endif