Main Page   Class Hierarchy   File List  

Astring.cpp

00001 /*
00002   aString.cpp  general purpose string class.  
00003 
00004   Description:
00005   Provides the implementation to 
00006   the class definition described in aString.h
00007 
00008   copyright (c) 1996 - 2001 
00009   
00010   David McCombs davidmc@newcottage.com
00011 
00012   Nuclear Core Class Library
00013 
00014   freely re-usable, redistributable.
00015 */
00016 
00017 
00018 #include<ctype.h>
00019 #include<iostream>
00020 #include<stdlib.h>
00021 #include "Astring.h"
00022 
00023 //  default constructor uses initializers
00024 //  instead of assignment.
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 // constructor with passed char string.
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 // STL string compatibility
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 // Copy constructor.
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 // Assignment operator using char string.
00088 //
00089 aString & aString::operator = ( char * input )
00090 {
00091  return *this = (const char *) input;
00092 }
00093 
00094 // const char string input version of assignment operator
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 // compatibility with STL string
00114 aString & aString::operator = ( const string & input )
00115 {
00116   (*this) = input.c_str();
00117   return *this;
00118 }
00119 
00120 // assigment operator using aString reference input
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 // determine if the buffer is a number
00141 bool aString::isNumber( void )
00142 {
00143   bool bRet = false; // set false for the empty string case
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 // attach method
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 // += operator performs string concatenation.
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     // allocated buffer must be the length of both
00192     // strings plus a null, copy the original back.
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 // subString methods
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 // Sets the buffer to a new size. 
00286 aString & aString::setSize( int newSize )
00287 {
00288   allocate( newSize, true );
00289   return *this;
00290 }
00291 
00292 
00293 // Replaces any chars in 'find' with the replacement char 'replace'
00294 // defaulted parameter provides for searching in alternate string, though
00295 // replacement still occurs in the internal buffer.
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     // index should be the smaller of source and target
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         // calculate the worst possible case 
00345         // for the new buffer size
00346         int xFoundCouldBeReplaced = size/lenFind;
00347         // account for divisor
00348         newBufferSize = xFoundCouldBeReplaced * lenReplace; 
00349         // account for modulus and null terminator
00350         newBufferSize += (size%lenFind) + 1;
00351       }
00352       
00353       // allocate the new buffer
00354       char * newBuffer = new char [newBufferSize];
00355       if (newBuffer) do 
00356       {
00357         // optimism
00358         bool matches = true;
00359         for ( int k=0; k<lenFind; k++ )
00360         {
00361           if( find[k] != buffer[i+k] )
00362           {
00363             // reality
00364             matches=false;
00365             break;
00366           } // end if matches
00367         } // end for find string
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     } // end if lenFind < size && lenFind > 0 
00387   } // end if find && replace
00388   return *this;
00389 }
00390 
00391 // replace at the zero based position with the passed replacement text.
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 // removes any instance of the characters found in
00412 // the character list 'find'.
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   } // end if buffer
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   } // end if the strings exist
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           } // end while
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           // the magic number '2' comes from 
00483           // the addition of zero base positioning and
00484           // the probable null at end of the string.
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           } // end while 
00500       }
00501       
00502   } // end if buffer
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         // found it!
00525         strRet = cursor;
00526       }
00527 
00528     } // end for 
00529 
00530   } // end if
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         // found it!
00550         ret = true;
00551       }
00552 
00553     } // end for 
00554 
00555   } // end if
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         // compares!
00576         ret = true;
00577       }
00578     }
00579   } // end if
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         // compares!
00599         ret = true;
00600       }
00601     }
00602   } // end if
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   } // end if
00624 
00625   return ret;
00626 
00627 }
00628 
00629 //
00630 // Internal function for aStrings use only.
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   // Set beginning state.
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     } // end inner while on separators
00659 
00660     // handle states in context of current state   
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     } // end switch
00689         
00690 
00691     // if the current character is  '\0' and
00692     // termAdded is true, then we must be on 
00693     // a delimiter.
00694     //
00695     if( tokenleft && *tokenleft == '\0' && state == trailingDelimiter )
00696     {
00697       // move to the next token and break
00698       // out of the while loop.
00699       //
00700       tokenleft++;
00701       break;
00702     }
00703 
00704     if( tokenleft )
00705     {
00706       tokenleft++;
00707     }
00708 
00709   } // end while
00710 
00711   return iStartDelimiterCount;
00712 
00713 }
00714 
00715 // Slides the requested amount over the tokenized buffer
00716 // default is 1 character slide to move tokenleft to the next 
00717 // position in string.  Can slide a specified 
00718 // amount past the current position.  always returns the 
00719 // current position.
00720 //
00721 char * aString::slide( int iAmount )
00722 {  
00723   // detect end of tokens
00724   if( tokenleft && *tokenleft == '\0' )
00725   { 
00726     tokenReset();
00727   }
00728   // If this is a new token operation,
00729   // allocate and set a new and increment tokenLeft for return.
00730   else
00731   {
00732     if ( tokened == NULL )
00733     {
00734       if( (  pchToken = tokenleft = tokened = new char [ size ] ) != NULL )
00735       {
00736         strcpy( tokened, buffer );
00737       } // end if token allocation worked
00738     }
00739     for( int x=0; x<iAmount && *tokenleft; x++)
00740     {
00741       // increment tokenleft for return.
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     // Tokened holds the new allocated memory buffur. 
00760     // token is for return of the current token.
00761     // tokenleft hold the position to the remaining tokened string.
00762     // 
00763     int iJump = 0;
00764 
00765     // Are we at the end of our string?
00766     //
00767     if( tokenleft && *tokenleft == '\0' )
00768     { 
00769       tokenReset();
00770     }
00771 
00772     // Are we performing a new token operation?
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       } // end if token alloction worked
00783 
00784     } // end if a new token operation is happening. 
00785 
00786     // We must be in an ongoing token operation.
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     // get last tok pos.
00844     char * pchLast = allTokens[tokCount-2];
00845 
00846     if( pchLast )
00847     {
00848       // determine if last was a slide op
00849       // by looking for a null beween the last 
00850       // token and the current one
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         // simple position moves
00865         pchToken = pchLast;
00866         tokenleft = pchLast+1;
00867       }
00868       else 
00869       {
00870         // undo last delimiter
00871         tokened[tokEnd]=buffer[tokEnd];
00872 
00873         // move the remainder
00874         tokenleft = pchLast + strlen(pchLast) + 1;
00875 
00876         // move token back
00877         pchToken = pchLast;
00878       }
00879     }
00880   }
00881   else 
00882   {
00883     // either ONE or NO tokens, 
00884     // resetting is appropriate here
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   // Be very defensive
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         } // end if match found
00928 
00929       } // end for i
00930 
00931     } // end for source
00932 
00933     *target='\0';
00934 
00935   } // end if input 
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       } // end if match found
00954 
00955     } // end for source
00956 
00957     *target='\0';
00958   } // end if input
00959   return *this;
00960 }
00961 
00962 
00963 // Added this to manage memory a little 
00964 //  better than the original string class
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 // This method converts the string from a hexadecimal escape to the actual character,
00993 // input is the starting token that signifies the begining of the hex escape.
00994 // two characters are read after the escape, since that is all that is needed to represent
00995 // a character in a hex.
00996 //
00997 aString & aString::deHexify( char hexToken )
00998 {
00999   if( size && strchr( buffer, hexToken ) ) 
01000   {
01001     // continue operation
01002     
01003     int iChar;
01004     char hexVal[5];
01005     char * curPos; // position in the current buffer
01006     char * curNew; // position in the new buffer
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 && // token char was found
01013           strlen(curPos) >= 3) // enough left to dehex
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     } // end for 
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 

Generated on Tue Jan 20 09:03:27 2004 for OpenTools by doxygen1.2.18