00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include<ctype.h>
00019 #include<iostream>
00020 #include<stdlib.h>
00021 #include "Astring.h"
00022
00023
00024
00025
00026 aString::aString()
00027 :buffer(NULL)
00028 ,endDelimiter('\0')
00029 ,size(0)
00030 ,pchToken(NULL)
00031 ,tokened(NULL)
00032 ,tokenleft(NULL)
00033 {
00034 ;
00035 }
00036
00037
00038
00039 aString::aString( const char* input )
00040 :buffer(NULL)
00041 ,endDelimiter('\0')
00042 ,size(0)
00043 ,pchToken(NULL)
00044 ,tokened(NULL)
00045 ,tokenleft(NULL)
00046 {
00047 if( input )
00048 {
00049 allocate(strlen( input )+1);
00050 strcpy(buffer,input);
00051 }
00052 }
00053
00054
00055 aString::aString( const string & input )
00056 :buffer(NULL)
00057 ,endDelimiter('\0')
00058 ,size(0)
00059 ,pchToken(NULL)
00060 ,tokened(NULL)
00061 ,tokenleft(NULL)
00062 {
00063 if( input.length() )
00064 {
00065 allocate( input.length()+1);
00066 strcpy(buffer,input.c_str());
00067 }
00068 }
00069
00070
00071
00072 aString::aString( const aString & input )
00073 :buffer(NULL)
00074 ,endDelimiter('\0')
00075 ,size(0)
00076 ,pchToken(NULL)
00077 ,tokened(NULL)
00078 ,tokenleft(NULL)
00079 {
00080 if( input.length() )
00081 {
00082 allocate(input.length()+1);
00083 strcpy(buffer,input.str());
00084 }
00085 }
00086
00087
00088
00089 aString & aString::operator = ( char * input )
00090 {
00091 return *this = (const char *) input;
00092 }
00093
00094
00095
00096 aString & aString::operator = ( const char * input )
00097 {
00098 if( input )
00099 {
00100 allocate(strlen( input )+1);
00101 strcpy(buffer,input);
00102 }
00103 else
00104 {
00105 delete [] buffer;
00106 buffer = NULL;
00107 size = 0;
00108 }
00109 tokenReset();
00110 return *this;
00111 }
00112
00113
00114 aString & aString::operator = ( const string & input )
00115 {
00116 (*this) = input.c_str();
00117 return *this;
00118 }
00119
00120
00121
00122 aString & aString::operator = ( const aString & input )
00123 {
00124 tokenReset();
00125 if( input.length() )
00126 {
00127 allocate(input.length()+1);
00128 strcpy(buffer,input.str());
00129 }
00130 else
00131 {
00132 delete [] buffer;
00133 buffer = NULL;
00134 size = 0;
00135 }
00136
00137 return *this;
00138 }
00139
00140
00141 bool aString::isNumber( void )
00142 {
00143 bool bRet = false;
00144 char numerical[]="0123456789.";
00145 char * chCursor = buffer;
00146 char * chNum = numerical;
00147 while( chCursor && *chCursor)
00148 {
00149 bRet = false;
00150 while( chNum && *chNum )
00151 {
00152 if( *chNum == *chCursor )
00153 bRet = true;
00154 chNum++;
00155 }
00156 if( !bRet )
00157 break;
00158 chCursor++;
00159 }
00160 return bRet;
00161 }
00162
00163
00164 void aString::attach( char * input )
00165 {
00166 if( input )
00167 {
00168 size = strlen(input)+1;
00169 delete [] buffer;
00170 buffer = input;
00171 }
00172 }
00173
00174
00175
00176
00177
00178 aString & aString::operator += ( const char * input )
00179 {
00180
00181 if( input )
00182 {
00183 int len1 = strlen( input );
00184 int len2 = 0;
00185
00186 if( buffer )
00187 {
00188 len2 = strlen(buffer);
00189 }
00190
00191
00192
00193
00194 allocate( len1+len2+1, true );
00195
00196 if ( len1 )
00197 {
00198 strcat(buffer,input);
00199 }
00200
00201 }
00202 return *this;
00203 }
00204
00205 aString & aString::operator += ( char * input )
00206 {
00207 return *this += ( const char * ) input;
00208 }
00209
00210 aString & aString::operator += ( char input )
00211 {
00212 char temp[2];
00213 temp[0]=input;
00214 temp[1]='\0';
00215 return *this += ( const char * ) temp;
00216 }
00217
00218 aString & aString::upperS(void)
00219 {
00220 if( buffer )
00221 *buffer = static_cast<char>(toupper( *buffer ));
00222 return *this;
00223 }
00224
00225 aString & aString::lowerS(void)
00226 {
00227 if( buffer )
00228 *buffer = static_cast<char>(tolower( *buffer ));
00229 return *this;
00230 }
00231
00232 aString & aString::upper(void)
00233 {
00234 if( buffer )
00235 {
00236 for( int i=0; i<size; i++ )
00237 {
00238 buffer[i] = static_cast<char>(toupper( buffer[i] ));
00239 }
00240 }
00241 return *this;
00242 }
00243
00244 aString & aString::lower(void)
00245 {
00246 if( buffer )
00247 {
00248 for( int i=0; i<size; i++ )
00249 {
00250 buffer[i] = static_cast<char>(tolower( buffer[i] ));
00251 }
00252 }
00253 return *this;
00254 }
00255
00256
00257 aString & aString::subString( const char * input, int start )
00258 {
00259 if( input &&
00260 strlen( input ) >= (unsigned) start )
00261 {
00262 const char * adj = input+start;
00263 *this=adj;
00264 }
00265 return *this;
00266 }
00267
00268 aString & aString::subString( const char * input, int start, int end )
00269 {
00270 if( input &&
00271 end >= start &&
00272 strlen( input ) >= (unsigned) end )
00273 {
00274 const char * adj = input+start;
00275 if( allocate( 2+end-start ) )
00276 {
00277 strncpy( buffer, adj, 1+end-start );
00278 buffer[1+end-start]='\0';
00279 }
00280 }
00281 return *this;
00282 }
00283
00284
00285
00286 aString & aString::setSize( int newSize )
00287 {
00288 allocate( newSize, true );
00289 return *this;
00290 }
00291
00292
00293
00294
00295
00296
00297 aString & aString::replaceFoundWith( const char * find, const char replace, const char * search )
00298 {
00299
00300 if ( find )
00301 {
00302 int findLen = strlen(find);
00303
00304 int targetLen = strlen(buffer);
00305
00306 int sourceLen = search? strlen(search): targetLen;
00307
00308 const char * pszSource = search?
00309 search:
00310 buffer;
00311
00312
00313 int idx = sourceLen < targetLen? sourceLen: targetLen;
00314
00315 for( int i=0; i < idx; i++ )
00316 {
00317 for( int j=0; j<findLen; j++ )
00318 {
00319 if( pszSource[i]==find[j] )
00320 {
00321 buffer[i] = replace;
00322 break;
00323 }
00324 }
00325 }
00326 }
00327 return *this;
00328 }
00329
00330 aString & aString::replaceFoundWith( const char * find, const char * replace )
00331 {
00332 if( find && replace )
00333 {
00334 bool changed = false;
00335 int lenFind = strlen( find );
00336 int lenReplace = strlen( replace );
00337 int i = 0, j = 0;
00338 if( lenFind < size && lenFind > 0 )
00339 {
00340 int newBufferSize=size;
00341
00342 if( lenFind < lenReplace )
00343 {
00344
00345
00346 int xFoundCouldBeReplaced = size/lenFind;
00347
00348 newBufferSize = xFoundCouldBeReplaced * lenReplace;
00349
00350 newBufferSize += (size%lenFind) + 1;
00351 }
00352
00353
00354 char * newBuffer = new char [newBufferSize];
00355 if (newBuffer) do
00356 {
00357
00358 bool matches = true;
00359 for ( int k=0; k<lenFind; k++ )
00360 {
00361 if( find[k] != buffer[i+k] )
00362 {
00363
00364 matches=false;
00365 break;
00366 }
00367 }
00368 if( matches )
00369 {
00370 memcpy(&(newBuffer[j]), replace, lenReplace );
00371 j+=lenReplace;
00372 i+=lenFind;
00373 changed=true;
00374 }
00375 newBuffer[j] = buffer[i];
00376 i++;
00377 j++;
00378 } while ( buffer[i] );
00379 if( changed )
00380 {
00381 newBuffer[j]=0;
00382 allocate(strlen(newBuffer) + 1);
00383 strcpy( buffer, newBuffer );
00384 }
00385 delete [] newBuffer;
00386 }
00387 }
00388 return *this;
00389 }
00390
00391
00392
00393 aString & aString::replaceAt( unsigned int pos, char * replace )
00394 {
00395 if( replace && strlen( replace ) )
00396 {
00397 int replaceLen = strlen( replace );
00398 if( replaceLen && ( pos+replaceLen < (unsigned) size ) )
00399 {
00400 for( char * pszSource = replace, * pszTarget = buffer+pos;
00401 *pszSource ;
00402 pszSource++, pszTarget++ )
00403 {
00404 *pszTarget = *pszSource;
00405 }
00406 }
00407 }
00408 return *this;
00409 }
00410
00411
00412
00413
00414 aString & aString::removeChars( const char * find )
00415 {
00416
00417 if( buffer )
00418 {
00419 char * buf = new char [ size ];
00420 strcpy( buf, buffer );
00421 char * ptr = strtok( buf, find );
00422 memset( buffer, '\0', size );
00423 while( ptr )
00424 {
00425 strcat( buffer, ptr );
00426 ptr = strtok( NULL, find );
00427 }
00428 delete [] buf;
00429
00430 }
00431
00432 return *this;
00433 }
00434
00435 aString & aString::encapsulateIn( const char * boundary, const char * end )
00436 {
00437 if( buffer && boundary )
00438 {
00439 int lenHead = strlen( boundary );
00440 int lenTail = end? strlen( end ): lenHead;
00441 char * buf = new char[ lenHead + size + lenTail ];
00442 strcpy( buf, boundary );
00443 strcat( buf, buffer );
00444 strcat( buf, end? end: boundary );
00445 size += lenHead+lenTail;
00446 delete [] buffer;
00447 buffer = buf;
00448 }
00449 return *this;
00450 }
00451
00452 aString & aString::trim( aString::end end )
00453 {
00454
00455 if( buffer )
00456 {
00457 char * cursor;
00458
00459 if( end == left || end == both )
00460 {
00461 cursor = buffer;
00462 while( *cursor &&
00463 ( *cursor == ' ' ||
00464 *cursor == '\n' ||
00465 *cursor == '\r' ||
00466 *cursor == '\t' ) )
00467 {
00468
00469 *cursor = '\0';
00470 cursor++;
00471
00472 }
00473 int newLen = strlen( cursor );
00474 if( newLen && cursor != buffer )
00475 {
00476 memmove( buffer, cursor, newLen+1 );
00477 }
00478 }
00479
00480 if( end == right || end == both )
00481 {
00482
00483
00484
00485 int pos = size - 2;
00486
00487 cursor = buffer + pos;
00488
00489 while( ( *cursor == ' ' ||
00490 *cursor == '\0' ||
00491 *cursor == '\n' ||
00492 *cursor == '\r' ||
00493 *cursor == '\t' ) && cursor != buffer )
00494 {
00495
00496 *cursor = '\0';
00497 cursor--;
00498
00499 }
00500 }
00501
00502 }
00503
00504 return *this;
00505
00506 }
00507
00508 char * aString::find( const char * input ) const
00509 {
00510 char * strRet = NULL;
00511 if( input )
00512 {
00513 int len = strlen( input );
00514
00515 char * cursor = buffer;
00516
00517 for( int pos = 0;
00518 pos < size-len && strRet == NULL;
00519 pos++, cursor++ )
00520 {
00521
00522 if( !strncmp( cursor, input, len ) )
00523 {
00524
00525 strRet = cursor;
00526 }
00527
00528 }
00529
00530 }
00531 return strRet;
00532 }
00533 bool aString::matchIn( const char * input ) const
00534 {
00535
00536 bool ret = false;
00537
00538 if( input )
00539 {
00540 int len = strlen( input );
00541
00542 char * cursor = buffer;
00543
00544 for( int pos = 0; pos < size-len && ret == false; pos++, cursor++ )
00545 {
00546
00547 if( !strncmp( cursor, input, len ) )
00548 {
00549
00550 ret = true;
00551 }
00552
00553 }
00554
00555 }
00556
00557 return ret;
00558
00559 }
00560
00561 bool aString::matchesStartOf( const char * input ) const
00562 {
00563
00564 bool ret = false;
00565
00566 if( input )
00567 {
00568 int len = strlen( input );
00569
00570 if( len > size )
00571 {
00572 int myLen = length();
00573 if( strncmp( buffer, input, myLen ) == 0 )
00574 {
00575
00576 ret = true;
00577 }
00578 }
00579 }
00580
00581 return ret;
00582
00583 }
00584
00585 bool aString::startOfMatches( const char * input ) const
00586 {
00587
00588 bool ret = false;
00589
00590 if( input )
00591 {
00592 int len = strlen( input );
00593
00594 if( len <= length() )
00595 {
00596 if( strncmp( buffer, input, len ) == 0 )
00597 {
00598
00599 ret = true;
00600 }
00601 }
00602 }
00603
00604 return ret;
00605
00606 }
00607
00608
00609
00610 bool aString::match( const char * input ) const
00611 {
00612
00613 bool ret = false;
00614
00615 if( buffer && input )
00616 {
00617
00618 if( !strcmp( buffer, input ) )
00619 {
00620 ret = true;
00621 }
00622
00623 }
00624
00625 return ret;
00626
00627 }
00628
00629
00630
00631
00632 int aString::oneToken( const char * separator, aString * delimiterHolder )
00633 {
00634 enum tokenStates { start, leadingDelimiter, adding, trailingDelimiter } state;
00635 bool charIsDelimiter;
00636
00637 int iStartDelimiterCount = 0;
00638
00639
00640 state = start;
00641
00642 while( *tokenleft )
00643 {
00644 const char * sepCursor = separator;
00645 endDelimiter = '\0';
00646 charIsDelimiter = false;
00647
00648 while( *sepCursor && *tokenleft )
00649 {
00650 if( *sepCursor == *tokenleft )
00651 {
00652 endDelimiter = *tokenleft;
00653 charIsDelimiter = true;
00654 break;
00655 }
00656 sepCursor++;
00657
00658 }
00659
00660
00661
00662 switch( state )
00663 {
00664 case start:
00665 case leadingDelimiter:
00666 if( charIsDelimiter )
00667 {
00668 if(delimiterHolder)
00669 {
00670 (*delimiterHolder) += endDelimiter;
00671 }
00672 state = leadingDelimiter;
00673 iStartDelimiterCount++;
00674 }
00675 else
00676 {
00677 state = adding;
00678 }
00679 break;
00680 case adding:
00681 if( charIsDelimiter )
00682 {
00683 *tokenleft='\0';
00684 state = trailingDelimiter;
00685 }
00686 break;
00687
00688 }
00689
00690
00691
00692
00693
00694
00695 if( tokenleft && *tokenleft == '\0' && state == trailingDelimiter )
00696 {
00697
00698
00699
00700 tokenleft++;
00701 break;
00702 }
00703
00704 if( tokenleft )
00705 {
00706 tokenleft++;
00707 }
00708
00709 }
00710
00711 return iStartDelimiterCount;
00712
00713 }
00714
00715
00716
00717
00718
00719
00720
00721 char * aString::slide( int iAmount )
00722 {
00723
00724 if( tokenleft && *tokenleft == '\0' )
00725 {
00726 tokenReset();
00727 }
00728
00729
00730 else
00731 {
00732 if ( tokened == NULL )
00733 {
00734 if( ( pchToken = tokenleft = tokened = new char [ size ] ) != NULL )
00735 {
00736 strcpy( tokened, buffer );
00737 }
00738 }
00739 for( int x=0; x<iAmount && *tokenleft; x++)
00740 {
00741
00742 tokenleft++;
00743 }
00744 pchToken = tokenleft-1;
00745 }
00746 if( pchToken )
00747 {
00748 allTokens.add( pchToken );
00749 }
00750 return pchToken;
00751 }
00752
00753
00754
00755 char * aString::token( const char * separator, aString * delimiterHolder )
00756 {
00757 if( buffer )
00758 {
00759
00760
00761
00762
00763 int iJump = 0;
00764
00765
00766
00767 if( tokenleft && *tokenleft == '\0' )
00768 {
00769 tokenReset();
00770 }
00771
00772
00773
00774 else if ( tokened == NULL )
00775 {
00776 if( ( pchToken = tokenleft = tokened = new char [ size ] ) != NULL )
00777 {
00778
00779 strcpy( tokened, buffer );
00780 iJump = oneToken( separator, delimiterHolder );
00781
00782 }
00783
00784 }
00785
00786
00787
00788 else
00789 {
00790 pchToken = tokenleft;
00791 iJump = oneToken( separator, delimiterHolder );
00792 }
00793
00794 pchToken+=iJump;
00795 }
00796
00797 if( pchToken )
00798 {
00799 allTokens.add( pchToken );
00800 }
00801 return pchToken;
00802 }
00803
00804 int aString::remainderPosition( void )
00805 {
00806 int iRet = -1;
00807 if( tokenleft && tokened && tokenleft >= tokened )
00808 {
00809 iRet = tokenleft - tokened;
00810 }
00811 return iRet;
00812 }
00813
00814 int aString::tokenPosition( void )
00815 {
00816 int iRet = -1;
00817 if( pchToken && tokened && pchToken >= tokened )
00818 {
00819 iRet = pchToken - tokened;
00820 }
00821 return iRet;
00822 }
00823
00824 char aString::startDelimiter( void )
00825 {
00826 char chRet='\0';
00827 int iTokPos=tokenPosition();
00828 if( iTokPos > 0 && buffer && length() > iTokPos-1)
00829 {
00830 chRet = buffer[iTokPos-1];
00831 }
00832 return chRet;
00833 }
00834
00835
00836 char * aString::backTrack()
00837 {
00838 int tokCount = allTokens.Size();
00839 int tokPos = tokenPosition();
00840 int tokEnd = tokPos + (pchToken?strlen( pchToken ):0);
00841 if( tokCount > 1 )
00842 {
00843
00844 char * pchLast = allTokens[tokCount-2];
00845
00846 if( pchLast )
00847 {
00848
00849
00850
00851 bool slideLast = true;
00852 char * testChar = pchLast;
00853 while( testChar < pchToken )
00854 {
00855 if( *testChar == '\0' )
00856 {
00857 slideLast=false;
00858 break;
00859 }
00860 testChar++;
00861 }
00862 if( slideLast==true )
00863 {
00864
00865 pchToken = pchLast;
00866 tokenleft = pchLast+1;
00867 }
00868 else
00869 {
00870
00871 tokened[tokEnd]=buffer[tokEnd];
00872
00873
00874 tokenleft = pchLast + strlen(pchLast) + 1;
00875
00876
00877 pchToken = pchLast;
00878 }
00879 }
00880 }
00881 else
00882 {
00883
00884
00885 tokenReset();
00886 }
00887 if( tokCount )
00888 {
00889 allTokens.remove(tokCount-1);
00890 }
00891 return pchToken;
00892 }
00893
00894 char * aString::currentToken( void )
00895 {
00896 return pchToken;
00897 }
00898
00899
00900 void aString::tokenReset( void )
00901 {
00902 delete [] tokened;
00903 pchToken = tokenleft = tokened = NULL;
00904 if( allTokens.Size() > 0 )
00905 allTokens.removeAll();
00906 }
00907
00908
00909 aString & aString::exclusive( char * input )
00910 {
00911
00912
00913 if( input && *input && size && buffer && *buffer )
00914 {
00915
00916 char * source;
00917 char * target;
00918 for( source = target = buffer; *source; source++ )
00919 {
00920 for( int i = 0; input[i]; i++ )
00921 {
00922 if( *source == input[i] )
00923 {
00924 *target = *source;
00925 target++;
00926 break;
00927 }
00928
00929 }
00930
00931 }
00932
00933 *target='\0';
00934
00935 }
00936
00937 return *this;
00938 }
00939
00940 aString & aString::exclusive( char low, char high )
00941 {
00942 if( size && buffer && *buffer )
00943 {
00944 char * source;
00945 char * target;
00946 for( source = target = buffer; *source; source++ )
00947 {
00948 if( *source >= low && *source <= high )
00949 {
00950 *target = *source;
00951 target++;
00952 break;
00953 }
00954
00955 }
00956
00957 *target='\0';
00958 }
00959 return *this;
00960 }
00961
00962
00963
00964
00965 bool aString::allocate(int sizeRequested, bool bCopy )
00966 {
00967 bool bRet = false;
00968 if( sizeRequested > size )
00969 {
00970 size = (1+sizeRequested/incSize)*incSize;
00971 char * temp = buffer;
00972 buffer = new char [size];
00973 if( buffer )
00974 {
00975 bRet = true;
00976 memset( buffer, 0, size );
00977 if( bCopy && temp )
00978 {
00979 strcpy( buffer, temp );
00980 }
00981 }
00982 delete [] temp;
00983 }
00984 else
00985 {
00986 bRet = true;
00987 }
00988 tokenReset();
00989 return bRet;
00990 }
00991
00992
00993
00994
00995
00996
00997 aString & aString::deHexify( char hexToken )
00998 {
00999 if( size && strchr( buffer, hexToken ) )
01000 {
01001
01002
01003 int iChar;
01004 char hexVal[5];
01005 char * curPos;
01006 char * curNew;
01007 char * end;
01008 char * newBuffer = new char [ size ];
01009 memset( newBuffer, 0, size );
01010 for( curNew=newBuffer, curPos=buffer; *curPos; curPos++, curNew++ )
01011 {
01012 if( *curPos==hexToken &&
01013 strlen(curPos) >= 3)
01014 {
01015 curPos++;
01016 strcpy( hexVal, "0x" );
01017
01018 memcpy(hexVal+2, curPos, 2);
01019 hexVal[4]='\0';
01020 iChar = (int) strtol( hexVal, &end, 16 );
01021 *curNew = iChar;
01022
01023 curPos++;
01024 }
01025 else
01026 {
01027 *curNew=*curPos;
01028 }
01029
01030 }
01031
01032 delete [] buffer;
01033 buffer = newBuffer;
01034 }
01035 return *this;
01036 }
01037
01038 std::ostream & operator << (std::ostream & outStream, const aString & inString )
01039 {
01040 return outStream << inString.str();
01041 }
01042