src/tools/tString.cpp

Go to the documentation of this file.
00001 /*
00002 
00003 *************************************************************************
00004 
00005 ArmageTron -- Just another Tron Lightcycle Game in 3D.
00006 Copyright (C) 2000  Manuel Moos (manuel@moosnet.de)
00007 
00008 **************************************************************************
00009 
00010 This program is free software; you can redistribute it and/or
00011 modify it under the terms of the GNU General Public License
00012 as published by the Free Software Foundation; either version 2
00013 of the License, or (at your option) any later version.
00014 
00015 This program is distributed in the hope that it will be useful,
00016 but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 GNU General Public License for more details.
00019 
00020 You should have received a copy of the GNU General Public License
00021 along with this program; if not, write to the Free Software
00022 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00023   
00024 ***************************************************************************
00025 
00026 */
00027 
00028 #include "tMemManager.h"
00029 #include "tString.h"
00030 #include "tLocale.h"
00031 #include "tConfiguration.h"
00032 #include "tException.h"
00033 #include <ctype.h>
00034 #include <string>
00035 #include <iostream>
00036 
00037 // *******************************************************************************
00038 // *
00039 // *    Helper functions
00040 // *
00041 // *******************************************************************************
00042 
00043 // reads an escape sequence from a stream
00044 // c: the character just read from the stream
00045 // c2: eventually set to the second character read
00046 // s: the stream to read from
00047 static bool st_ReadEscapeSequence( char & c, char & c2, std::istream & s )
00048 {
00049     c2 = '\0';
00050 
00051     // detect escaping
00052     if ( c == '\\' && !s.eof() && s.good() )
00053     {
00054         c2 = s.get();
00055 
00056         // nothing useful read?
00057         if ( s.eof() )
00058         {
00059             c2 = 0;
00060             return false;
00061         }
00062 
00063         // interpret special escape sequences
00064         switch (c2)
00065         {
00066         case 'n':
00067             // turn \n into newline
00068             c = '\n';
00069             c2 = 0;
00070             return true;
00071         case '"':
00072         case ' ':
00073         case '\'':
00074         case '\n':
00075             // include quoting character as literal
00076             return true;
00077         default:
00078             // take the whole \x sequence as it appeared.
00079             return false;
00080         }
00081     }
00082 
00083     return false;
00084 }
00085 
00086 // reads an escape sequence from a stream, putting back unread char
00087 // c: the character just read from the stream
00088 // s: the stream to read from
00089 static bool st_ReadEscapeSequence( char & c, std::istream & s )
00090 {
00091     char c2 = '\0';
00092     bool ret = st_ReadEscapeSequence( c, c2, s );
00093     if ( c2 )
00094         s.putback( c2 );
00095     return ret;
00096 }
00097 
00098 // *******************************************************************************
00099 // *
00100 // *    stream reading operator
00101 // *
00102 // *******************************************************************************
00109 // *******************************************************************************
00110 
00111 std::istream & operator>> (std::istream &s,tString &x)
00112 {
00113     x.Clear();
00114 
00115     std::ws(s);
00116 
00117     char c=s.get();
00118 
00119     // check if the string is quoted
00120     bool quoted = false;
00121     char quoteChar = c;   // if it applies, this is the quoting character
00122     if ( c == '"' || c == '\'' )
00123     {
00124         // yes, it is
00125         quoted = true;
00126         c = s.get();
00127     }
00128 
00129     while((quoted || !( isblank(c) || c == '\n' || c == '\r' ) ) && s.good() && !s.eof()){
00130         x += c;
00131         c=s.get();
00132 
00133         // read and interpret escape sequences
00134         if ( !st_ReadEscapeSequence( c, s) )
00135         {
00136             // interpret special characters
00137             if ( quoted && c == quoteChar )
00138             {
00139                 // this marks the end of a quoted string; abort.
00140                 c = s.get();
00141                 break;
00142             }
00143         }
00144         else if ( isblank( c ) )
00145         {
00146             // include escaped spaces
00147             x += c;
00148             c=s.get();
00149         }
00150 
00151     }
00152     s.putback(c);
00153     return s;
00154 }
00155 
00156 
00157 //removed in favor of searching whole string...
00158 /*void tString::RemoveStartColor(){
00159         tString oldname = *this;
00160 //      unsigned short int colorcodelength = 0;
00161         tString newname = "";
00162         if (oldname.ge2("0x") == false){
00163                 return;
00164         }
00165         newname.SetLen(14);
00166 //      unsigned short int numcounter = 0;
00167         unsigned short int i = 0;
00168         for (i=2; i<oldname.Len(); i++){
00169                 if (oldname(i) > 47 && oldname(i) < 58) {
00170 //                      std::cout << oldname(i) << std::endl;
00171                         colorcodelength++;
00172                 }
00173                 else {
00174                         break;
00175                 }
00176         }
00177         unsigned short int c = 0;
00178         for (i=colorcodelength+2; i<oldname.Len(); i++) {
00179 //              std::cout << oldname(i);
00180                 newname(c) = oldname(i);
00181                 c++;
00182         }
00183         for (i=8; i<oldname.Len(); i++) {
00184 //              std::cout << oldname(i);
00185                 newname(c) = oldname(i);
00186                 c++;
00187         }
00188 //      std::cout << std::endl << newname << std::endl;
00189         *this = newname;
00190 }*/
00191 
00192 /*
00193 bool tString::operator==(const tString &other) const
00194 {
00195     if (other.Len() != Len())
00196         return false;
00197     for (int i= Len()-1; i>=0; i--)
00198         if (other(i) != (*this)(i))
00199             return false;
00200 
00201     return true;
00202 }
00203 */
00204 
00205 // Original ge2, didn't compile under linux, some stupid overload or something, so we now have ge2
00206 /*bool tString::operator>=(const tString &other) const
00207 {
00208         if (other.Len() > Len()) {
00209 //              std::cout << "lenissue\n";
00210                 return false;
00211         }
00212         for (int i=0; i<other.Len()-1; i++) {
00213                 if (other(i) != (*this)(i)) {
00214 //                      std::cout << "matchissue: '" << other(i) << "' '" << (*this)(i) << "'\n";
00215                         return false;
00216                 }
00217 //              else {
00218 //                      std::cout << other(i) << " " << (*this)(i) << std::endl;
00219 //              }
00220         }
00221 
00222         return true;
00223 } */
00224 
00225 // char st_stringOutputBuffer[tMAX_STRING_OUTPUT];
00226 
00227 // filters illegal characters
00228 class tCharacterFilter
00229 {
00230 public:
00231     tCharacterFilter()
00232     {
00233         int i;
00234         filter[0]=0;
00235 
00236         // map all unknown characters to underscores
00237         for (i=255; i>=0; --i)
00238         {
00239             filter[i] = '_';
00240         }
00241 
00242         // leave ASCII characters as they are
00243         // for (i=127; i>=32; --i)
00244         // no, leave all ISO Latin 1 characters as they are
00245         for (i=255; i>=32; --i)
00246         {
00247             filter[i] = i;
00248         }
00249 
00250         // map return and tab to space
00251         SetMap('\n',' ');
00252         SetMap('\t',' ');
00253 
00255         /*
00256         SetMap(0xc0,0xc5,'A');
00257         SetMap(0xd1,0xd6,'O');
00258         SetMap(0xd9,0xdD,'U');
00259         SetMap(0xdf,'s');
00260         SetMap(0xe0,0xe5,'a');
00261         SetMap(0xe8,0xeb,'e');
00262         SetMap(0xec,0xef,'i');
00263         SetMap(0xf0,0xf6,'o');
00264         SetMap(0xf9,0xfc,'u');
00265         */
00266 
00268         // make this data driven.
00269     }
00270 
00271     char Filter( unsigned char in )
00272     {
00273         return filter[ static_cast< unsigned int >( in )];
00274     }
00275 private:
00276     void SetMap( int in1, int in2, unsigned char out)
00277     {
00278         tASSERT( in2 <= 0xff );
00279         tASSERT( 0 <= in1 );
00280         tASSERT( in1 < in2 );
00281         for( int i = in2; i >= in1; --i )
00282             filter[ i ] = out;
00283     }
00284 
00285     void SetMap( unsigned char in, unsigned char out)
00286     {
00287         filter[ static_cast< unsigned int >( in ) ] = out;
00288     }
00289 
00290     char filter[256];
00291 };
00292 
00293 // *******************************************************************************
00294 // *
00295 // *    tString
00296 // *
00297 // *******************************************************************************
00300 // *******************************************************************************
00301 
00302 tString::tString( void )
00303 {
00304 }
00305 
00306 // *******************************************************************************
00307 // *
00308 // *    tString
00309 // *
00310 // *******************************************************************************
00314 // *******************************************************************************
00315 
00316 tString::tString( BASE const & other )
00317         : string( other )
00318 {
00319 }
00320 
00321 // *******************************************************************************
00322 // *
00323 // *    tString
00324 // *
00325 // *******************************************************************************
00329 // *******************************************************************************
00330 
00331 tString::tString( tString const & other )
00332         : string( other )
00333 {
00334 }
00335 
00336 // *******************************************************************************
00337 // *
00338 // *    tString
00339 // *
00340 // *******************************************************************************
00344 // *******************************************************************************
00345 
00346 tString::tString( CHAR const * other )
00347         : string( other ? other : "" )
00348 {
00349     // tASSERT( other );
00350 }
00351 
00352 // *******************************************************************************
00353 // *
00354 // *    tString
00355 // *
00356 // *******************************************************************************
00360 // *******************************************************************************
00361 
00362 //tString::tString( tOutput const & other )
00363 //{
00364 //    operator=( other );
00365 //}
00366 
00367 // *******************************************************************************
00368 // *
00369 // *    operator =
00370 // *
00371 // *******************************************************************************
00376 // *******************************************************************************
00377 
00378 tString & tString::operator =( tOutput const & other )
00379 {
00380     Clear();
00381     *this << other;
00382     return *this;
00383 }
00384 
00385 // *******************************************************************************
00386 // *
00387 // *   Size
00388 // *
00389 // *******************************************************************************
00393 // *******************************************************************************
00394 
00395 tString::size_type tString::Size( void ) const
00396 {
00397     return size();
00398 }
00399 
00400 // *******************************************************************************
00401 // *
00402 // *    ReadLine
00403 // *
00404 // *******************************************************************************
00409 // *******************************************************************************
00410 
00411 void tString::ReadLine( std::istream & s, bool enableEscapeSequences )
00412 {
00413     char c=' ';
00414     Clear();
00415     while(c!='\n' && c!='\r' && isblank(c) &&  s.good() && !s.eof()){
00416         c=s.get();
00417     }
00418 
00419     s.putback(c);
00420     c='x';
00421 
00422     while( true )
00423     {
00424         c=s.get();
00425 
00426         // notice end of line or file
00427         if ( c=='\n' || c=='\r' || !s.good() || s.eof())
00428             break;
00429 
00430         if ( enableEscapeSequences )
00431         {
00432             char c2 = '\0';
00433             if ( st_ReadEscapeSequence( c, c2, s ) )
00434             {
00435                 *this += c;
00436                 c = 'x';
00437                 continue;
00438             }
00439             else if ( c2 )
00440             {
00441                 *this += c;
00442                 *this += c2;
00443                 c = 'x';
00444                 continue;
00445             }
00446         }
00447 
00448         *this += c;
00449     }
00450 }
00451 
00452 // *******************************************************************************
00453 // *
00454 // *    Clear
00455 // *
00456 // *******************************************************************************
00459 // *******************************************************************************
00460 
00461 void tString::Clear( void )
00462 {
00463 #ifdef _MSC_VER
00464     *this = "";
00465 #else
00466     string::clear();
00467 #endif
00468 }
00469 
00470 // *******************************************************************************************
00471 // *
00472 // *   SetPos
00473 // *
00474 // *******************************************************************************************
00479 // *******************************************************************************************
00480 
00481 void tString::SetPos(int l, bool cut){
00482     int i;
00483     if ( l < Len() )
00484     {
00485         if ( cut )
00486         {
00487             if ( l > 0 )
00488             {
00489                 SetSize( l-1 );
00490                 operator+=(' ');
00491             }
00492             else
00493             {
00494                 Clear();
00495             }
00496         }
00497         else
00498         {
00499             operator+=(' ');
00500         }
00501     }
00502     for(i=Len();i<l;i++)
00503         operator+=(' ');
00504 }
00505 
00506 //added by me (Tank Program)
00507 //sees if a string starts with another string
00508 //created for remote admin...
00509 //but used all over the place because it's a cool method --Lucifer
00510 
00511 // *******************************************************************************************
00512 // *
00513 // *   StartsWith
00514 // *
00515 // *******************************************************************************************
00520 // *******************************************************************************************
00521 
00522 bool tString::StartsWith( const tString & other ) const
00523 {
00524     // const tString & rmhxt = *this;
00525     // rmhxt.RemoveHex();
00526     // *this = rmhxt;
00527     // other.RemoveHex();
00528     if (other.Len() > Len()) {
00529         return false;
00530     }
00531     for (int i=0; i<other.Len()-1; i++) {
00532         if (other[i] != (*this)[i]) {
00533             return false;
00534         }
00535     }
00536 
00537     return true;
00538 }
00539 
00540 // *******************************************************************************************
00541 // *
00542 // *   StartsWith
00543 // *
00544 // *******************************************************************************************
00549 // *******************************************************************************************
00550 
00551 bool tString::StartsWith( const char * other ) const
00552 {
00553     return StartsWith( tString( other ) );
00554 }
00555 
00556 // Added by me (Lucifer)
00557 // Just reverses the two strings and returns StartsWith
00558 // I thought that was clever, but it probably isn't
00559 
00560 // *******************************************************************************************
00561 // *
00562 // *   EndsWith
00563 // *
00564 // *******************************************************************************************
00569 // *******************************************************************************************
00570 
00571 bool tString::EndsWith(const tString & other ) const
00572 {
00573     if (other.Len() > Len()) {
00574         return false;
00575     }
00576     tString thisString = Reverse();
00577     tString otherString(other);
00578     otherString = otherString.Reverse();
00579 
00580     // Haha, just use StartsWith to do the comparison :)
00581     return thisString.StartsWith(otherString);
00582     //return true;
00583 }
00584 
00585 // *******************************************************************************************
00590 // *******************************************************************************************
00591 
00592 bool tString::EndsWith( const char* other) const {
00593     return EndsWith( tString(other) );
00594 }
00595 
00596 // *******************************************************************************
00597 // *
00598 // *    LTrim
00599 // *
00600 // *******************************************************************************
00604 // *******************************************************************************
00605 
00606 tString tString::LTrim( void ) const
00607 {
00608     tString toReturn;
00609     bool trim = true;
00610 
00611     for( size_t i = 0; i<size(); i++ )
00612     {
00613         if( !isblank((*this)[i]) )
00614             trim = false;
00615         if( !trim)
00616             toReturn << (*this)[i];
00617     }
00618     return toReturn;
00619 }
00620 
00621 // *******************************************************************************
00622 // *
00623 // *    RTrim
00624 // *
00625 // *******************************************************************************
00629 // *******************************************************************************
00630 
00631 tString tString::RTrim( void ) const
00632 {
00633     tString toReturn;
00634     toReturn = Reverse();
00635 
00636     toReturn = toReturn.LTrim();
00637     return toReturn.Reverse();
00638 }
00639 
00640 // *******************************************************************************
00641 // *
00642 // *    Trim
00643 // *
00644 // *******************************************************************************
00648 // *******************************************************************************
00649 
00650 tString tString::Trim( void ) const
00651 {
00652     return LTrim().RTrim();
00653 }
00654 
00655 // *******************************************************************************
00656 // *
00657 // *    StrPos
00658 // *
00659 // *******************************************************************************
00664 // *******************************************************************************
00665 
00666 int tString::StrPos( const tString & tofind ) const
00667 {
00668     if (tofind.Len() > Len()) {
00669         return -1;
00670     }
00671     for (int i=0; i<Len()-1; i++) {
00672         if ((*this)(i) == tofind(0)) {
00673             bool found = true;
00674             for (int j=0; j<tofind.Len()-1; j++) {
00675                 if ((*this)(i+j) != tofind(j))
00676                     found = false;
00677             }
00678             if (found == true)
00679                 return i;
00680         }
00681     }
00682 
00683     return -1;
00684 }
00685 
00686 int tString::StrPos( int start, const tString & tofind ) const
00687 {
00688     if (tofind.Len() > Len()) {
00689         return -1;
00690     }
00691     for (int i = start; i<Len()-1; i++) {
00692         if ((*this)(i) == tofind(0)) {
00693             bool found = true;
00694             for (int j=0; j<tofind.Len()-1; j++) {
00695                 if ((*this)(i+j) != tofind(j))
00696                     found = false;
00697             }
00698             if (found == true)
00699                 return i;
00700         }
00701     }
00702 
00703     return -1;
00704 }
00705 
00706 // *******************************************************************************
00707 // *
00708 // *    StrPos
00709 // *
00710 // *******************************************************************************
00715 // *******************************************************************************
00716 
00717 int tString::StrPos( const CHAR * tofind ) const
00718 {
00719     return StrPos( tString ( tofind ) );
00720 }
00721 
00722 int tString::StrPos( int start, const CHAR * tofind ) const
00723 {
00724     return StrPos( start, tString ( tofind ) );
00725 }
00726 
00727 // *******************************************************************************
00728 // *
00729 // *    SubStr
00730 // *
00731 // *******************************************************************************
00737 // *******************************************************************************
00738 
00739 tString tString::SubStr( const int start, int len ) const
00740 {
00741     tASSERT( start >= 0 );
00742 
00743     if (start > Len())
00744         return tString("");
00745 
00746     //if len < 0 or too long, take the whole string
00747     if ( (len + start) >= Len() ||  len < 0)
00748         len = Len() - start - 1;
00749 
00750     tString toReturn("");
00751 
00752     for (int i=start; i<(len + start); i++) {
00753         toReturn << (*this)(i);
00754     }
00755     return  toReturn;
00756 }
00757 
00758 // *******************************************************************************
00759 // *
00760 // *    SubStr
00761 // *
00762 // *******************************************************************************
00767 // *******************************************************************************
00768 
00769 tString tString::SubStr( const int start ) const
00770 {
00771     return SubStr (start, Len()-start-1 );
00772 }
00773 
00774 // helper for ToInt and ToFloat
00775 template< class T > void ToT( tString const & source, T & target, tString::size_type pos, char const * name )
00776 {
00777     if ( pos > source.Size() )
00778         pos = source.Size();
00779 
00780     if ( !source.Convert( target, pos ) )
00781     {
00782         std::ostringstream message;
00783 
00784         if ( pos > 0 )
00785         {
00786             message << "Expected an " << name << " at position " << pos << " of string \"" << source << "\", but got \"" << static_cast<tString::CHAR const *>(source) + pos << "\".";
00787         }
00788         else
00789         {
00790             message << "Expected an " << name << ", but got \"" << source << "\".";
00791         }
00792         throw tGenericException( message.str().c_str(), "Conversion Error" );
00793     }
00794 }
00795 
00796 // *******************************************************************************
00797 // *
00798 // *    ToInt
00799 // *
00800 // *******************************************************************************
00805 // *******************************************************************************
00806 
00807 int tString::ToInt( size_type pos ) const
00808 {
00809     int ret = 0;
00810     ToT( *this, ret, pos, "integer" );
00811     return ret;
00812 }
00813 
00814 // *******************************************************************************
00815 // *
00816 // *    ToFloat
00817 // *
00818 // *******************************************************************************
00823 // *******************************************************************************
00824 
00825 REAL tString::ToFloat( size_type pos ) const
00826 {
00827     REAL ret = 0;
00828     ToT( *this, ret, pos, "float" );
00829     return ret;
00830 }
00831 
00832 // exctact the integer at position pos plus 2^16 ( or the character ) [ implementation detail of CompareAlphanumerical ]
00833 static int GetInt( const tString& s, int& pos )
00834 {
00835     int ret = 0;
00836     int digit = 0;
00837     while ( pos < s.Len() && digit >= 0 && digit <= 9 )
00838     {
00839         ret = ret*10 + digit;
00840         digit = s[pos] - '0';
00841         pos++;
00842     }
00843 
00844     if ( ret > 0 )
00845     {
00846         return ret + 0x10000;
00847     }
00848     else
00849     {
00850         return digit + '0';
00851     }
00852 }
00853 
00854 // *******************************************************************************************
00855 // *
00856 // *   CompareAlphaNumerical
00857 // *
00858 // *******************************************************************************************
00864 // *******************************************************************************************
00865 
00866 int tString::CompareAlphaNumerical( const tString& a, const tString &b)
00867 {
00868     int apos = 0;
00869     int bpos = 0;
00870 
00871     while ( apos < a.Len() && bpos < b.Len() )
00872     {
00873         int adigit = GetInt( a,apos );
00874         int bdigit = GetInt( b,bpos );
00875         if ( adigit < bdigit )
00876             return 1;
00877         else if ( adigit > bdigit )
00878             return -1;
00879     }
00880 
00881     if ( a.Len() - apos < b.Len() - bpos )
00882         return 1;
00883     else if ( a.Len() - apos > b.Len() - bpos )
00884         return 1;
00885     else
00886         return 0;
00887 }
00888 
00889 // *******************************************************************************************
00890 // *
00891 // *    StripWhitespace
00892 // *
00893 // *******************************************************************************************
00897 // *******************************************************************************************
00898 
00899 tString tString::StripWhitespace( void ) const
00900 {
00901     tString toReturn;
00902 
00903     for( int i = 0; i<=Len()-2; i++ )
00904     {
00905         if( !isblank((*this)(i)) )
00906             toReturn << (*this)(i);
00907     }
00908     return toReturn;
00909 }
00910 
00912 tString tString::ToLower(void) const {
00913     tString ret(*this);
00914     for(iterator iter=ret.begin(); iter!=ret.end(); ++iter) {
00915         *iter = tolower(*iter);
00916     }
00917     return ret;
00918 }
00919 
00921 tString tString::ToUpper(void) const {
00922     tString ret(*this);
00923     for(iterator iter=ret.begin(); iter!=ret.end(); ++iter) {
00924         *iter = toupper(*iter);
00925     }
00926     return ret;
00927 }
00928 
00931 int tString::Count(CHAR what) const {
00932     int ret = 0;
00933     for(const_iterator iter=begin(); iter!=end(); ++iter) {
00934         if (*iter == what)
00935             ret++;
00936     }
00937     return ret;
00938 }
00939 
00940 //static const char delimiters[] = "`~!@#$%^&*()-=_+[]\\{}|;':\",./<>? ";
00941 static tString delimiters("!?.:;_()-, ");
00942 static tConfItemLine st_wordDelimiters( "WORD_DELIMITERS", delimiters );
00943 
00944 // *******************************************************************************************
00945 // *
00946 // *    PosWordRight
00947 // *
00948 // *******************************************************************************************
00953 // *******************************************************************************************
00954 
00955 int tString::PosWordRight( int start ) const {
00956     int nextDelimiter = strcspn( SubStr( start, Len() ), delimiters );
00957     int toMove = nextDelimiter;
00958 
00959     // A delimter in our immediate path
00960     if ( toMove == 0 ) {
00961         // Move over delimiters
00962         while ( nextDelimiter == 0 && start + 1 < Len() ) {
00963             toMove++;
00964             start++;
00965             nextDelimiter = strcspn( SubStr( start, Len() ), delimiters );
00966         }
00967         // Skip over the word if not multiple delimiters
00968         if ( toMove == 1 ) {
00969             toMove += nextDelimiter;
00970         }
00971     }
00972 
00973     return toMove;
00974 }
00975 
00976 // *******************************************************************************************
00977 // *
00978 // *    PosWordLeft
00979 // *
00980 // *******************************************************************************************
00985 // *******************************************************************************************
00986 
00987 int tString::PosWordLeft( int start ) const {
00988     return -1 * Reverse().PosWordRight( Len() - start - 1 );
00989 }
00990 
00991 // *******************************************************************************************
00992 // *
00993 // *    RemoveWordRight
00994 // *
00995 // *******************************************************************************************
01002 // *******************************************************************************************
01003 
01004 int tString::RemoveWordRight( int start ) {
01005     int removed = PosWordRight( start );
01006     RemoveSubStr( start, removed );
01007     return removed;
01008 }
01009 
01010 // *******************************************************************************************
01011 // *
01012 // *    RemoveWordLeft
01013 // *
01014 // *******************************************************************************************
01021 // *******************************************************************************************
01022 
01023 int tString::RemoveWordLeft( int start ) {
01024     int removed = PosWordLeft( start );
01025     RemoveSubStr( start, removed );
01026     return removed;
01027 }
01028 
01029 // *******************************************************************************************
01030 // *
01031 // *    RemoveSubStr
01032 // *
01033 // *******************************************************************************************
01040 // *******************************************************************************************
01041 
01042 void tString::RemoveSubStr( int start, int length ) {
01043     int strLen = Len()-1;
01044     if ( length < 0 ) {
01045         start += length;
01046         length = abs( length );
01047     }
01048 
01049     if ( start + length > strLen || start < 0 || length == 0 ) {
01050         return;
01051     }
01052 
01053     if ( start == 0 ) {
01054         if ( strLen - length == 0 ) {
01055             *this = ("");
01056         }
01057         else {
01058             *this = SubStr( start + length, strLen );
01059         }
01060     }
01061     else {
01062         *this = SubStr( 0, start ) + SubStr( start + length, strLen );
01063     }
01064 
01065     // SetSze(strLen+1-length);
01066 }
01067 
01068 
01069 // *******************************************************************************************
01070 // *
01071 // *    GetFileMimeExtension
01072 // *
01073 // *******************************************************************************************
01078 // *******************************************************************************************
01079 
01080 tString tString::GetFileMimeExtension() const {
01081     tString extension;
01082     int currentPosition = Len();
01083 
01084     bool goonie = true;
01085 
01086     if( currentPosition < 2 ) return tString("");
01087 
01088     while(goonie) {
01089         extension += SubStr(currentPosition,1);
01090         if( SubStr(currentPosition,1) == "." ) goonie = false;
01091         currentPosition--;
01092     }
01093 
01094     extension = extension.Reverse();
01095     if( extension == (*this) ) return tString("");
01096 
01097     for(size_t i=0; i<extension.size(); i++)
01098         extension[i] = tolower(extension[i]);
01099     return extension;
01100 }
01101 
01102 // *******************************************************************************************
01103 // *
01104 // *    Reverse
01105 // *
01106 // *******************************************************************************************
01110 // *******************************************************************************************
01111 
01112 tString tString::Reverse() const {
01113     tString reversed;
01114     for ( int index = Len() - 2; index >= 0; index-- ) {
01115         reversed << ( *this ) ( index );
01116     }
01117 
01118     return reversed;
01119 }
01120 
01121 // *******************************************************************************************
01122 // *
01123 // *    Truncate
01124 // *
01125 // *******************************************************************************************
01132 // *******************************************************************************************
01133 
01134 tString tString::Truncate( int truncateAt ) const
01135 {
01136     // The string does not need to be truncated
01137     if ( truncateAt >= Len() )
01138         return *this;
01139 
01140     return SubStr( 0, truncateAt ) + "...";
01141 }
01142 
01143 // *******************************************************************************
01144 // *
01145 // *    operator []
01146 // *
01147 // *******************************************************************************
01152 // *******************************************************************************
01153 
01154 tString::CHAR tString::operator []( size_t i ) const
01155 {
01156     tASSERT( i <= size() );
01157     return BASE::operator[]( i );
01158 }
01159 
01160 // *******************************************************************************
01161 // *
01162 // *    operator []
01163 // *
01164 // *******************************************************************************
01169 // *******************************************************************************
01170 
01171 tString::CHAR & tString::operator []( size_t i )
01172 {
01173     while( i >= size() )
01174     {
01175         *this += ' ';
01176 #ifdef DEBUG
01177         static bool warn = true;
01178         if( warn )
01179         {
01180             warn = false;
01181             tERR_MESSAGE("Auto-expanding string, this functionality will go away.");
01182         }
01183 #endif
01184     }
01185 
01186     return BASE::operator[](i);
01187 }
01188 
01189 // *******************************************************************************
01190 // *
01191 // *    operator []
01192 // *
01193 // *******************************************************************************
01198 // *******************************************************************************
01199 
01200 tString::CHAR tString::operator []( int i ) const
01201 {
01202     return operator[]( size_t(i) );
01203 }
01204 
01205 // *******************************************************************************
01206 // *
01207 // *    operator []
01208 // *
01209 // *******************************************************************************
01214 // *******************************************************************************
01215 
01216 tString::CHAR & tString::operator []( int i )
01217 {
01218     return operator[]( size_t(i) );
01219 }
01220 
01221 // *******************************************************************************
01222 // *
01223 // *    operator ( )
01224 // *
01225 // *******************************************************************************
01230 // *******************************************************************************
01231 
01232 tString::CHAR tString::operator ()( size_t i ) const
01233 {
01234     tASSERT( i <= size() );
01235     return BASE::operator[]( i );
01236 }
01237 
01238 // *******************************************************************************
01239 // *
01240 // *    operator ( )
01241 // *
01242 // *******************************************************************************
01247 // *******************************************************************************
01248 
01249 tString::CHAR & tString::operator ()( size_t i )
01250 {
01251     tASSERT( i < size() );
01252     return BASE::operator[]( i );
01253 }
01254 
01255 // *******************************************************************************
01256 // *
01257 // *    operator []
01258 // *
01259 // *******************************************************************************
01264 // *******************************************************************************
01265 
01266 tString::CHAR tString::operator ()( int i ) const
01267 {
01268     return operator()( size_t(i) );
01269 }
01270 
01271 // *******************************************************************************
01272 // *
01273 // *    operator ()
01274 // *
01275 // *******************************************************************************
01280 // *******************************************************************************
01281 
01282 tString::CHAR & tString::operator ()( int i )
01283 {
01284     return operator()( size_t(i) );
01285 }
01286 
01287 // *******************************************************************************************
01288 // *
01289 // *    Compare
01290 // *
01291 // *******************************************************************************************
01297 // *******************************************************************************************
01298 
01299 int tString::Compare( const char* other, bool ignoreCase ) const
01300 {
01301     if ( ignoreCase ) {
01302         return strcasecmp( *this, other );
01303     }
01304     else {
01305         return Compare( other );
01306     }
01307 }
01308 
01309 // *******************************************************************************************
01310 // *
01311 // *    Compare
01312 // *
01313 // *******************************************************************************************
01318 // *******************************************************************************************
01319 
01320 int tString::Compare( const char* other ) const
01321 {
01322     if ( !other )
01323         return 1;
01324 
01325     return strcmp( *this, other );
01326 }
01327 
01328 // *******************************************************************************
01329 // *
01330 // *    operator const CHAR*
01331 // *
01332 // *******************************************************************************
01336 // *******************************************************************************
01337 
01338 tString::operator const tString::CHAR *( void ) const
01339 {
01340     return c_str();
01341 }
01342 
01343 // *******************************************************************************
01344 // *
01345 // *    Len
01346 // *
01347 // *******************************************************************************
01351 // *******************************************************************************
01352 
01353 int tString::Len( void ) const
01354 {
01355     return size() + 1;
01356 }
01357 
01359 int tString::LongestLine( void ) const {
01360     unsigned longest = 0;
01361     unsigned pos = 0;
01362     int l;
01363     while ((l=find_first_of('\n', pos)) != -1) {
01364         if(l-pos > longest)
01365             longest = l-pos;
01366         pos = l+1;
01367     }
01368     if(size() - pos > longest)
01369         longest = size() - pos;
01370     return longest;
01371 }
01372 
01374 int tColoredString::LongestLine( void ) const {
01375     return tColoredString::RemoveColors(c_str()).LongestLine();
01376 }
01377 
01378 // *******************************************************************************
01379 // *
01380 // *    SetSize
01381 // *
01382 // *******************************************************************************
01386 // *******************************************************************************
01387 
01388 void tString::SetSize( unsigned int len )
01389 {
01390     tASSERT(len < 268435456);
01391 
01392     while ( len > size() )
01393         *this += ' ';
01394     if ( len < size() )
01395         *this = SubStr( 0, len );
01396 
01397     tASSERT( size() == len );
01398 }
01399 
01400 // *******************************************************************************
01401 // *
01402 // *    SetLen
01403 // *
01404 // *******************************************************************************
01409 // *******************************************************************************
01410 
01411 void tString::SetLen( int len )
01412 {
01413     // legacy function, don't use
01414     st_Breakpoint();
01415 
01416     while ( len > Len() )
01417         *this += ' ';
01418     if ( len < Len() )
01419         *this = SubStr( 0, len );
01420 
01421     tASSERT( Len() == len );
01422 }
01423 
01424 // *******************************************************************************************
01425 // *******************************************************************************************
01426 // *******************************************************************************************
01427 
01428 // *******************************************************************************************
01429 // *
01430 // *    ~tColoredString
01431 // *
01432 // *******************************************************************************************
01435 // *******************************************************************************************
01436 
01437 tColoredString::~tColoredString( void )
01438 {
01439 }
01440 
01441 // *******************************************************************************************
01442 // *
01443 // *    tColoredString
01444 // *
01445 // *******************************************************************************************
01448 // *******************************************************************************************
01449 
01450 tColoredString::tColoredString( void )
01451 {
01452 }
01453 
01454 // *******************************************************************************************
01455 // *
01456 // *    tColoredString
01457 // *
01458 // *******************************************************************************************
01462 // *******************************************************************************************
01463 
01464 tColoredString::tColoredString( const tColoredString & other )
01465 :tString( other )
01466 {
01467 }
01468 
01469 // *******************************************************************************************
01470 // *
01471 // *    tColoredString
01472 // *
01473 // *******************************************************************************************
01477 // *******************************************************************************************
01478 
01479 tColoredString::tColoredString( const tString & other )
01480         :tString( other )
01481 {
01482 }
01483 
01484 // *******************************************************************************************
01485 // *
01486 // *    tColoredString
01487 // *
01488 // *******************************************************************************************
01492 // *******************************************************************************************
01493 
01494 tColoredString::tColoredString( const char * other )
01495         :tString( other )
01496 {
01497 }
01498 
01499 // *******************************************************************************************
01500 // *
01501 // *    tColoredString
01502 // *
01503 // *******************************************************************************************
01507 // *******************************************************************************************
01508 
01509 tColoredString::tColoredString( const tOutput & other )
01510         :tString( other )
01511 {
01512 }
01513 
01514 // *******************************************************************************************
01515 // *
01516 // *    RemoveColors
01517 // *
01518 // *******************************************************************************************
01523 // *******************************************************************************************
01524 
01525 tString tColoredString::RemoveColors( const char * c )
01526 {
01527     tString ret;
01528 
01529     int len = strlen(c);
01530 
01531     bool removed = false;
01532 
01533     // walk through string
01534     while (*c!='\0'){
01535         // skip color codes
01536         if (*c=='0' && len >= 2 && c[1]=='x')
01537         {
01538             if(len >= 8)
01539             {
01540                 c   += 8;
01541                 len -= 8;
01542                 removed = true;
01543             }
01544             else
01545             {
01546                 // skip incomplete color codes, too
01547                 return RemoveColors( ret );
01548             }
01549         }
01550         else
01551         {
01552             ret << (*(c++));
01553             len--;
01554         }
01555     }
01556 
01557     return removed ? RemoveColors( ret ) : ret;
01558 }
01559 
01560 // helper function: removes trailing color of string and returns number of chars
01561 // used by color codes
01562 static int RemoveTrailingColor( tString& s, int maxLen=-1 )
01563 {
01564     // count bytes lost to color codes
01565     int posDisplacement = 0;
01566     int len = 0;
01567 
01568     // walk through string
01569     for ( size_t g=0; g+1 < s.Size(); g++)
01570     {
01571         if (s(g) == '0' && s(g+1) == 'x')
01572         {
01573             // test if the code is legal ( not so far at the end that it overlaps )
01574             if ( s.Size() >= g + 8 )
01575             {
01576                 // everything is in order, record color code usage and advance
01577                 posDisplacement+=8;
01578                 g+=7;
01579             }
01580             else
01581             {
01582                 // illegal code! Remove it.
01583                 s.SetSize( g );
01584                 // s[g]=0;
01585             }
01586         }
01587         else if ( maxLen > 0 )
01588         {
01589             if ( ++len >= maxLen )
01590             {
01591                 // maximal end reached, cut it off
01592                 s.SetSize( g-1 );
01593                 // s[g]=0;
01594             }
01595         }
01596     }
01597 
01598     return posDisplacement;
01599 }
01600 
01601 // *******************************************************************************************
01602 // *
01603 // *    SetPos
01604 // *
01605 // *******************************************************************************************
01610 // *******************************************************************************************
01611 
01612 
01613 void tColoredString::SetPos( int len, bool cut )
01614 {
01615     // determine desired raw length taking color codes into account and possibly cutting
01616     int wishLen = len + ::RemoveTrailingColor( *this, cut ? len : -1 );
01617 
01618     // delegate
01619     tString::SetPos( wishLen, cut );
01620 }
01621 
01622 // *******************************************************************************************
01623 // *
01624 // *    RemoveTrailingColor
01625 // *
01626 // *******************************************************************************************
01629 // *******************************************************************************************
01630 
01631 void tColoredString::RemoveTrailingColor( void )
01632 {
01633     // delegage
01634     ::RemoveTrailingColor( *this );
01635 }
01636 
01637 // *******************************************************************************************
01638 // *
01639 // *    NetFilter
01640 // *
01641 // *******************************************************************************************
01644 // *******************************************************************************************
01645 
01646 void tString::NetFilter( void )
01647 {
01648     static tCharacterFilter filter;
01649 
01650     // run through string
01651     for( int i = Len()-2; i>=0; --i )
01652     {
01653         // character to filter
01654         char & my = (*this)(i);
01655 
01656         my = filter.Filter(my);
01657     }
01658 }
01659 
01660 bool st_colorStrings=true;
01661 
01662 static tConfItem<bool> cs("COLOR_STRINGS",st_colorStrings);
01663 
01664 static int RTC(REAL x){
01665     int ret=int(x*255);
01666     if (ret<0)
01667         ret=0;
01668     if (ret>255)
01669         ret=255;
01670     return ret;
01671 }
01672 
01673 static char hex_array[]="0123456789abcdef";
01674 
01675 static char int_to_hex(int i){
01676     if (i<0 || i >15)
01677         return 'Q';
01678     else
01679         return hex_array[i];
01680 }
01681 
01682 // *******************************************************************************
01683 // *
01684 // *   color code streaming
01685 // *
01686 // *******************************************************************************
01692 // *******************************************************************************
01693 
01694 tColoredString & operator <<(tColoredString &s, const tColoredStringProxy &colorCode )
01695 {
01696     if (st_colorStrings)
01697     {
01698         char cs[9];
01699         cs[0]='0';
01700         cs[1]='x';
01701 
01702         int RGB[3];
01703         RGB[0]=RTC(colorCode.r_);
01704         RGB[1]=RTC(colorCode.g_);
01705         RGB[2]=RTC(colorCode.b_);
01706 
01707         for(int i=0;i<3;i++){
01708             int lp=RGB[i]%16;
01709             int hp=(RGB[i]-lp)/16;
01710             cs[2+2*i]=int_to_hex(hp);
01711             cs[2+2*i+1]=int_to_hex(lp);
01712         }
01713         cs[8]=0;
01714 
01715         s << cs;
01716     }
01717 
01718     return s;
01719 }
01720 
01721 #ifdef _MSC_VER
01722 // non-template replacements for VisualC
01723 bool tString::Convert( int & target, size_type startPos ) const
01724 {
01725     // generate string stream and advance it to the start position
01726     std::istringstream s(*this);
01727     s.seekg(startPos);
01728 
01729     // read it
01730     s >> target;
01731 
01732     // return failure condition
01733     return !s.fail() && s.eof() || isblank(s.get());
01734 }
01735 
01736 bool tString::Convert( REAL & target, size_type startPos ) const
01737 {
01738     // generate string stream and advance it to the start position
01739     std::istringstream s(*this);
01740     s.seekg(startPos);
01741 
01742     // read it
01743     s >> target;
01744 
01745     // return failure condition
01746     return !s.fail() && s.eof() || isblank(s.get());
01747 }
01748 
01749 #endif
01750 
01751 // *******************************************************************************
01752 // *
01753 // *   Scrapyard
01754 // *
01755 // *******************************************************************************
01756 
01757 /*
01758 tString & tString::operator<<(const char *c){
01759     return operator+=(c);
01760 }
01761 
01762 tString & tString::operator+=(const char *c){
01763     if (c){
01764         if ( Len() == 0 )
01765             operator[](0)='\0';
01766 
01767         int i=Len()-1;
01768         if (i<0) i=0;
01769         while (*c!='\0'){
01770             operator[](i)=*c;
01771             i++;
01772             c++;
01773         }
01774         operator[](i)='\0';
01775     }
01776     return *this;
01777 }
01778 
01779 tString & tString::operator=(const char *c){
01780     Clear();
01781     return operator+=(c);
01782 }
01783 
01784 tString tString::operator+(const char *c) const{
01785     tString s(*this);
01786     return s+=c;
01787     //return s;
01788 }
01789 
01790 tString::operator const char *() const{
01791     if (Len())
01792         return &operator()(0);
01793     else
01794         return "";
01795 }
01796 
01797 tString & tString::operator<<(char c){
01798     return operator+=(c);
01799 }
01800 
01801 tString & tString::operator+=(char c){
01802     if ( Len() == 0 )
01803         operator[](0)='\0';
01804 
01805     int i=Len();
01806     if (i<=0) i=1;
01807     operator[](i-1)=c;
01808     operator[](i)='\0';
01809     return *this;
01810 }
01811 
01812 tString tString::operator+(char c) const{
01813     tString s(*this);
01814     return s+=c;
01815     //return s;
01816 }
01817 
01818 
01819 std::ostream & operator<< (std::ostream &s,const tString &x){
01820     if(x.Len())
01821         return s << &(x(0));
01822     else
01823         return s;
01824 }
01825 
01826   void operator <<(tString &s,const char * c){
01827   std::stringstream S(st_stringOutputBuffer,tMAX_STRING_OUTPUT-1);
01828   S << c << '\0';
01829   s+=st_stringOutputBuffer;
01830   }
01831 
01832   void operator <<(tString &s,const unsigned char * c){
01833   std::stringstream S(st_stringOutputBuffer,tMAX_STRING_OUTPUT-1);
01834   S << c << '\0';
01835   s+=st_stringOutputBuffer;
01836   }
01837 
01838   void operator <<(tString &s,int c){
01839   std::stringstream S(st_stringOutputBuffer,tMAX_STRING_OUTPUT-1);
01840   S << c << '\0';
01841   s+=st_stringOutputBuffer;
01842   }
01843 
01844   void operator <<(tString &s,float c){
01845   std::stringstream S(st_stringOutputBuffer,tMAX_STRING_OUTPUT-1);
01846   S << c << '\0';
01847   s+=st_stringOutputBuffer;
01848   }
01849 */
01850 
01851 
01852 std::stringstream& operator<<(std::stringstream& s,const tString &t)
01853 {
01854     static_cast<std::ostream&>(s) << static_cast<const char *>(t);
01855     return s;
01856 }
01857 
01858 /*
01859 std::stringstream& operator<<(std::stringstream& s, const int &t)
01860 {
01861         static_cast<std::ostream&>(s) << static_cast<int >(t);
01862         return s;
01863 }
01864 
01865 std::stringstream& operator<<(std::stringstream& s, const float &t)
01866 {
01867         static_cast<std::ostream&>(s) << static_cast<float>(t);
01868         return s;
01869 }
01870 
01871 std::stringstream& operator<<(std::stringstream& s, const short unsigned int &t)
01872 {
01873         static_cast<std::ostream&>(s) << static_cast<int>(t);
01874         return s;
01875 }
01876 
01877 std::stringstream& operator<<(std::stringstream& s, const short int &t)
01878 {
01879         static_cast<std::ostream&>(s) << static_cast<int>(t);
01880         return s;
01881 }
01882 
01883 std::stringstream& operator<<(std::stringstream& s, const unsigned int &t)
01884 {
01885         static_cast<std::ostream&>(s) << static_cast<int>(t);
01886         return s;
01887 }
01888 
01889 std::stringstream& operator<<(std::stringstream& s, const unsigned long &t)
01890 {
01891         static_cast<std::ostream&>(s) << static_cast<int>(t);
01892         return s;
01893 }
01894 
01895 std::stringstream& operator<<(std::stringstream& s, char t)
01896 {
01897         static_cast<std::ostream&>(s) << t;
01898         return s;
01899 }
01900 
01901 std::stringstream& operator<<(std::stringstream& s, bool t)
01902 {
01903         static_cast<std::ostream&>(s) << static_cast<int>(t);
01904         return s;
01905 }
01906 
01907 
01908 std::stringstream& operator<<(std::stringstream& s, const char * const &t)
01909 {
01910         static_cast<std::ostream&>(s) << static_cast<const char *>(t);
01911         return s;
01912 }
01913 
01914 
01915 tString & tString::operator=(const tString &s)
01916 {
01917     // self copying is unsafe
01918     if ( &s == this )
01919         return *this;
01920 
01921     Clear();
01922     for (int i = s.Len()-1; i>=0; i--)
01923         operator[](i) = s(i);
01924 
01925     tASSERT( (*this) == s );
01926 
01927     return *this;
01928 }
01929 
01930 */
01931 
01932 /*
01933 
01934 //static char* st_TempString = NULL;
01935 #ifdef DEBUG
01936 //static int   st_TempStringLength = 10;
01937 #else
01938 //static int   st_TempStringLength = 1000;
01939 #endif
01940 
01941 // static int    
01942 
01943 class tTempStringCleanup
01944 {
01945 public:
01946         ~tTempStringCleanup()
01947                 {
01948                         if (st_TempString)
01949                                 free( st_TempString );
01950 
01951                         st_TempString = NULL;
01952                 }
01953 };
01954 
01955 static tTempStringCleanup cleanup;
01956 
01957 char * tString::ReserveTempString()
01958 {
01959         if (!st_TempString)
01960                 st_TempString = reinterpret_cast<char*>( malloc(st_TempStringLength) );
01961 
01962         st_TempString[st_TempStringLength-1] = 0;
01963         st_TempString[st_TempStringLength-2] = 0;
01964 
01965         return st_TempString;
01966 }
01967 
01968 
01969 int    tString::TempStringLength()
01970 {
01971         return st_TempStringLength;
01972 }
01973 
01974 void   tString::MakeTempStringLonger()
01975 {
01976         free(st_TempString);
01977         st_TempString = NULL;
01978         st_TempStringLength *= 2;
01979 }
01980 
01981 // *******************************************************************************************
01982 // *
01983 // *    operator ==
01984 // *
01985 // *******************************************************************************************
01990 // *******************************************************************************************
01991 
01992 bool tString::operator ==( const char* other ) const
01993 {
01994     return Compare( other ) == 0;
01995 }
01996 
01997 // *******************************************************************************************
01998 // *
01999 // *    operator !=
02000 // *
02001 // *******************************************************************************************
02006 // *******************************************************************************************
02007 
02008 bool tString::operator !=( const char* other ) const
02009 {
02010     return Compare( other ) != 0;
02011 }
02012 
02013 // *******************************************************************************************
02014 // *
02015 // *    operator <
02016 // *
02017 // *******************************************************************************************
02022 // *******************************************************************************************
02023 
02024 bool tString::operator <( const char* other ) const
02025 {
02026     return Compare( other ) < 0;
02027 }
02028 
02029 // *******************************************************************************************
02030 // *
02031 // *    operator>
02032 // *
02033 // *******************************************************************************************
02038 // *******************************************************************************************
02039 
02040 bool tString::operator>( const char* other ) const
02041 {
02042     return Compare( other ) > 0;
02043 }
02044 
02045 // *******************************************************************************************
02046 // *
02047 // *    operator <=
02048 // *
02049 // *******************************************************************************************
02054 // *******************************************************************************************
02055 
02056 bool tString::operator <=( const char* other ) const
02057 {
02058     return Compare( other ) <= 0;
02059 }
02060 
02061 // *******************************************************************************************
02062 // *
02063 // *    operator >=
02064 // *
02065 // *******************************************************************************************
02070 // *******************************************************************************************
02071 
02072 bool tString::operator >=( const char* other ) const
02073 {
02074     return Compare( other ) >= 0;
02075 }
02076 
02077 bool operator==( const char* first, const tString& second )
02078 {
02079     return second == first;
02080 }
02081 
02082 bool operator!=( const char* first, const tString& second )
02083 {
02084     return second != first;
02085 }
02086 
02087 bool operator<( const char* first, const tString& second )
02088 {
02089     return second > first;
02090 }
02091 
02092 bool operator>( const char* first, const tString& second )
02093 {
02094     return second < first;
02095 }
02096 
02097 bool operator<=( const char* first, const tString& second )
02098 {
02099     return second >= first;
02100 }
02101 
02102 bool operator>=( const char* first, const tString& second )
02103 {
02104     return second <= first;
02105 }
02106 
02107 bool operator==( const tString& first, const tString& second )
02108 {
02109     return first.operator==( second );
02110 }
02111 
02112 bool operator!=( const tString& first, const tString& second )
02113 {
02114     return first.operator!=( second );
02115 }
02116 
02117 bool operator<( const tString& first, const tString& second )
02118 {
02119     return first.operator<( second );
02120 }
02121 
02122 bool operator>( const tString& first, const tString& second )
02123 {
02124     return first.operator>( second );
02125 }
02126 
02127 bool operator<=( const tString& first, const tString& second )
02128 {
02129     return first.operator<=( second );
02130 }
02131 
02132 bool operator>=( const tString& first, const tString& second )
02133 {
02134     return first.operator>=( second );
02135 }
02136 
02137 void testconversion()
02138 {
02139     float x;
02140     tString t("1");
02141     tVERIFY( t.Convert( x ) );
02142     t = "1.2 b s";
02143     tVERIFY( t.Convert( x ) );
02144     t = "bla";
02145     tVERIFY( !t.Convert( x ) );
02146     t = "1b";
02147     tVERIFY( !t.Convert( x ) );
02148 }
02149 */
02150 
02151 
02152 // *******************************************************************************************
02153 // *
02154 // *    tIsInList
02155 // *
02156 // *******************************************************************************************
02164 // *******************************************************************************************
02166 bool tIsInList( tString const & list_, tString const & item )
02167 {
02168     tString list = list_;
02169 
02170     while( list != "" )
02171     {
02172         // find the item
02173         int pos = list.StrPos( item );
02174 
02175         // no traditional match? shoot.
02176         if ( pos < 0 )
02177         {
02178             return false;
02179         }
02180 
02181         // check whether the match is a true list match
02182         if ( 
02183             ( pos == 0 || list[pos-1] == ',' || isblank(list[pos-1]) )
02184             &&
02185             ( pos + item.Len() >= list.Len() || list[pos+item.Len()-1] == ',' || isblank(list[pos+item.Len()-1]) )
02186             )
02187         {
02188             return true;
02189         }
02190         else
02191         {
02192             // no? truncate the list and go on.
02193             list = list.SubStr( pos + 1 );
02194         }
02195     }
02196     
02197     return false;
02198 }
02199 
02200 // **********************************************************************
02201 // *
02202 // *    tToLower
02203 // *
02204 // **********************************************************************
02208 // **********************************************************************
02209 void tToLower( tString & toTransform )
02210 {
02211     for( int i = toTransform.Len()-2; i >= 0; --i )
02212     {
02213         toTransform[i] = tolower( toTransform[i] );
02214     }
02215 }
02216 
02217 // **********************************************************************
02218 // *
02219 // *    tToUpper
02220 // *
02221 // **********************************************************************
02225 // **********************************************************************
02226 void tToUpper( tString & toTransform )
02227 {
02228     for( int i = toTransform.Len()-2; i >= 0; --i )
02229     {
02230         toTransform[i] = toupper( toTransform[i] );
02231     }
02232 }

Generated on Sat Mar 15 22:56:02 2008 for Armagetron Advanced by  doxygen 1.5.4