MercuryString.cpp

Go to the documentation of this file.
00001 #include "MercuryString.h"
00002 #include <stdlib.h>
00003 #include <string.h>
00004 
00005 //For ssprintf.
00006 #include <stdarg.h> 
00007 #include <stdio.h>
00008 
00009 #define BASE_ALLOC 16
00010 
00011 #define NEXT_ALLOC( x, y )  ( x + y + BASE_ALLOC )
00012 
00013 #define MANAGE_ALLOC( y ) \
00014     if ( m_iLen + y + 1 > m_iAlloc ) \
00015     { \
00016 /*      int iOldMalloc = m_iAlloc; */\
00017         m_iAlloc = NEXT_ALLOC( m_iLen, y ); \
00018         char * newStr = (char*)malloc( m_iAlloc ); \
00019         memcpy( newStr, m_sCur, m_iLen + 1 ); \
00020         free( m_sCur ); \
00021         m_sCur = newStr; \
00022     }
00023 
00024 MString::MString()
00025 {
00026     m_sCur = (char*)malloc( BASE_ALLOC );
00027     m_sCur[0] = '\0';
00028     m_iLen = 0;
00029     m_iAlloc = BASE_ALLOC;
00030 }
00031 
00032 MString::MString( int iPreAlloc )
00033 {
00034     m_sCur = (char*)malloc( iPreAlloc );
00035     m_sCur[0] = '\0';
00036     m_iLen = 0;
00037     m_iAlloc = iPreAlloc;
00038 }
00039 
00040 MString::MString( const char sIn )
00041 {
00042     m_iLen = 1;
00043     m_iAlloc = 2;
00044     m_sCur = (char*)malloc( m_iAlloc );
00045     m_sCur[0] = sIn;
00046     m_sCur[1] = '\0';
00047 }
00048 
00049 MString::MString( const char * sIn )
00050 {
00051     m_iLen = strlen( sIn );
00052     m_iAlloc = m_iLen + 1;
00053     m_sCur = (char*)malloc( m_iAlloc );
00054     memcpy( m_sCur, sIn, m_iAlloc );
00055 }
00056 
00057 MString::MString( const char * sIn, int iSize )
00058 {
00059     m_iLen = iSize;
00060     m_iAlloc = m_iLen + 1;
00061     m_sCur = (char*)malloc( m_iAlloc );
00062     memcpy( m_sCur, sIn, m_iLen );
00063     m_sCur[m_iLen] = '\0';
00064 }
00065 
00066 MString::MString( const MString & rhs )
00067 {
00068     m_iLen = rhs.m_iLen;
00069     m_iAlloc = rhs.m_iAlloc;
00070     m_sCur = (char*)malloc( m_iAlloc );
00071     memcpy( m_sCur, rhs.m_sCur, m_iLen );
00072     m_sCur[m_iLen] = '\0';
00073 }
00074 
00075 MString::~MString()
00076 {
00077     free(m_sCur);
00078 }
00079 
00080 const MString & MString::operator = ( const MString & rhs )
00081 {
00082     free (m_sCur);
00083     m_iLen = rhs.m_iLen;
00084     m_iAlloc = rhs.m_iAlloc;
00085     m_sCur = (char*)malloc( m_iAlloc );
00086     memcpy( m_sCur, rhs.m_sCur, m_iLen );
00087     m_sCur[m_iLen] = '\0';
00088     return (*this);
00089 }
00090 
00091 const MString & MString::operator = ( const char * rhs )
00092 {
00093     free (m_sCur);
00094     m_iLen = strlen( rhs );
00095     m_iAlloc = m_iLen + 1;
00096     m_sCur = (char*)malloc( m_iAlloc );
00097     memcpy( m_sCur, rhs, m_iAlloc );
00098     return (*this);
00099 }
00100 
00101 const MString MString::operator + ( const MString & rhs ) const
00102 {
00103     int iNextMalloc = NEXT_ALLOC( m_iLen, rhs.m_iLen );
00104     MString ret( iNextMalloc );
00105     ret.m_iLen = m_iLen + rhs.m_iLen;
00106     memcpy( ret.m_sCur, m_sCur, m_iLen );
00107     memcpy( ret.m_sCur + m_iLen, rhs.m_sCur, rhs.m_iLen );
00108     ret.m_sCur[ret.m_iLen] = '\0';
00109     return ret;
00110 }
00111 
00112 const MString MString::operator + ( const char * rhs ) const
00113 {
00114     if ( !rhs )
00115         return (*this);
00116     int iRhsLen = strlen( rhs );
00117     int iNextMalloc = NEXT_ALLOC( m_iLen, iRhsLen );
00118     MString ret( iNextMalloc );
00119     ret.m_iLen = m_iLen + iRhsLen;
00120     memcpy( ret.m_sCur, m_sCur, m_iLen );
00121     memcpy( ret.m_sCur + m_iLen, rhs, iRhsLen );
00122     ret.m_sCur[ret.m_iLen] = '\0';
00123     return ret;
00124 }
00125 
00126 const MString MString::operator + ( const char rhs ) const
00127 {
00128     int iNextMalloc = NEXT_ALLOC( m_iLen, 1 );
00129     MString ret( iNextMalloc );
00130     ret.m_iLen = m_iLen + 1;
00131     memcpy( ret.m_sCur, m_sCur, m_iLen );
00132     ret.m_sCur[ret.m_iLen - 1] = rhs;
00133     ret.m_sCur[ret.m_iLen] = '\0';
00134     return ret;
00135 }
00136 
00137 const MString & MString::operator += ( const char * rhs )
00138 {
00139     int iRhsLen = strlen( rhs );
00140     MANAGE_ALLOC( iRhsLen )
00141     memcpy( m_sCur + m_iLen, rhs, iRhsLen );
00142     m_iLen += iRhsLen;
00143     m_sCur[m_iLen] = '\0';
00144     return (*this);
00145 }
00146 
00147 const MString & MString::operator += ( const MString & rhs )
00148 {
00149     MANAGE_ALLOC( rhs.m_iLen )
00150     memcpy( m_sCur + m_iLen, rhs.m_sCur, rhs.m_iLen );
00151     m_iLen += rhs.m_iLen;
00152     m_sCur[m_iLen] = '\0';
00153     return (*this);
00154 }
00155 
00156 const MString & MString::operator += ( const char rhs )
00157 {
00158     MANAGE_ALLOC( 1 )
00159     m_sCur[m_iLen] = rhs;
00160     m_iLen++;
00161     m_sCur[m_iLen] = '\0';
00162     return (*this);
00163 }
00164 
00165 bool MString::operator == ( const MString & rhs )
00166 {
00167     return strcmp( m_sCur, rhs.m_sCur ) == 0;
00168 }
00169 
00170 bool MString::operator == ( const char * rhs )
00171 {
00172     return strcmp( m_sCur, rhs ) == 0;
00173 }
00174 
00175 bool MString::operator < ( const MString & rhs )
00176 {
00177     return strcmp( m_sCur, rhs.m_sCur ) < 0;
00178 }
00179 
00180 bool MString::operator > ( const MString & rhs )
00181 {
00182     return strcmp( m_sCur, rhs.m_sCur ) > 0;
00183 }
00184 
00185 void MString::append( const MString & app )
00186 {
00187     MANAGE_ALLOC( app.m_iLen )
00188     memcpy( m_sCur + m_iLen, app.m_sCur, app.m_iLen );
00189     m_iLen += app.m_iLen;
00190     m_sCur[m_iLen] = '\0';
00191 }
00192 
00193 void MString::append( const char app )
00194 {
00195     MANAGE_ALLOC( 1 )
00196     m_sCur[m_iLen] = app;
00197     m_iLen++;
00198     m_sCur[m_iLen] = '\0';
00199 }
00200 
00201 void MString::append( const char * app )
00202 {
00203     int iRhsLen = strlen( app );
00204     MANAGE_ALLOC( iRhsLen )
00205     memcpy( m_sCur + m_iLen, app, iRhsLen );
00206     m_iLen += iRhsLen;
00207     m_sCur[m_iLen] = '\0';
00208 }
00209 
00210 void MString::append( const char * app, int len )
00211 {
00212     MANAGE_ALLOC( len )
00213     memcpy( m_sCur + m_iLen, app, len );
00214     m_iLen += len;
00215     m_sCur[m_iLen] = '\0';
00216 }
00217 
00218 void MString::append( const char app, int len )
00219 {
00220     MANAGE_ALLOC( len )
00221     memset( m_sCur + m_iLen, app, len );
00222     m_iLen += len;
00223     m_sCur[m_iLen] = '\0';
00224 }
00225 
00226 void MString::assign( const MString & app )
00227 {
00228     free( m_sCur );
00229     m_iLen = app.m_iLen;
00230     m_iAlloc = app.m_iAlloc;
00231     m_sCur = (char*)malloc( m_iAlloc );
00232     memcpy( m_sCur, app.m_sCur, m_iLen );
00233     m_sCur[m_iLen] = '\0';
00234 }
00235 
00236 void MString::assign( const char * app )
00237 {
00238     free( m_sCur );
00239     m_iLen = strlen( app );
00240     m_iAlloc = m_iLen + 1;
00241     m_sCur = (char*)malloc( m_iAlloc );
00242     memcpy( m_sCur, app, m_iAlloc );
00243 }
00244 
00245 void MString::assign( const char * app, int len )
00246 {
00247     free( m_sCur );
00248     m_iLen = len;
00249     m_iAlloc = m_iLen + 1;
00250     m_sCur = (char*)malloc( m_iAlloc );
00251     memcpy( m_sCur, app, m_iLen );
00252     m_sCur[m_iLen] = '\0';
00253 }
00254 
00255 int MString::find( const MString & tofind, int start ) const
00256 {
00257     const char * ret = strstr( m_sCur + start, tofind.m_sCur );
00258     return (ret)?(ret-m_sCur):npos;
00259 }
00260 
00261 int MString::rfind( const MString & tofind ) const
00262 {
00263     int iLen = tofind.length();
00264     int iTarg = m_iLen - iLen;
00265 
00266     while ( iTarg >= 0 )
00267     {
00268         if ( strncmp( tofind.m_sCur+iTarg, tofind, iLen ) == 0 )
00269             return iTarg;
00270         iTarg--;
00271     }
00272     return npos;
00273 }
00274 
00275 int MString::find( const char * tofind, int start ) const
00276 {
00277     const char * ret = strstr( m_sCur + start, tofind );
00278     return (ret)?(ret-m_sCur):npos;
00279 }
00280 
00281 int MString::rfind( const char * tofind ) const
00282 {
00283     int iLen = strlen( tofind );
00284     int iTarg = m_iLen - iLen;
00285 
00286     while ( iTarg >= 0 )
00287     {
00288         if ( strncmp( m_sCur+iTarg, tofind, iLen ) == 0 )
00289             return iTarg;
00290         iTarg--;
00291     }
00292     return npos;
00293 }
00294 
00295 int MString::find( const char tofind, int start ) const
00296 {
00297     const char * ret = strchr( m_sCur + start, tofind );
00298     return (ret)?(ret-m_sCur):npos;
00299 }
00300 
00301 int MString::rfind( const char tofind ) const
00302 {
00303     const char * ret = strrchr( m_sCur, tofind );
00304     return (ret)?(ret-m_sCur):npos;
00305 }
00306 
00307 const MString MString::substr( int iStart ) const
00308 {
00309     return MString( m_sCur + iStart, m_iLen - iStart );
00310 }
00311 
00312 const MString MString::substr( int iStart, int iLength ) const
00313 {
00314     return MString( m_sCur + iStart, iLength );
00315 }
00316 
00317 int MString::compare( const MString & cmp ) const
00318 {
00319     return strcmp( m_sCur, cmp.m_sCur );
00320 }
00321 
00322 int MString::compare( const char * cmp ) const
00323 {
00324     return strcmp( m_sCur, cmp );
00325 }
00326 
00327 int MString::compare( int start, int len, const MString & cmp ) const
00328 {
00329     return strncmp( m_sCur + start, cmp.m_sCur, len );
00330 }
00331 
00332 int MString::compare( int start, int len, const char * cmp ) const
00333 {
00334     return strncmp( m_sCur + start, cmp, len );
00335 }
00336 
00337 unsigned int MString::hash() const
00338 {
00339     unsigned int ret = 0;
00340     unsigned int i;
00341     unsigned int j = size()>>2;
00342     for( i = 0; i < j; i++ )
00343         ret += ((unsigned int *)m_sCur)[i];
00344 
00345     for( i = j<<2; i < size(); i++ )
00346         ret += (unsigned int)(unsigned char)m_sCur[i];
00347 
00348     return ret;
00349 }
00350 
00351 void MString::resize( unsigned int size )
00352 {
00353     if( size <= m_iLen )
00354     {
00355         m_iLen = size; 
00356         m_sCur[size] = '\0';
00357     } else
00358     {
00359         MANAGE_ALLOC( size )
00360     }
00361 }
00362 
00363 bool operator < ( const MString & lhs, const MString & rhs )
00364 {
00365     return strcmp( lhs.m_sCur, rhs.m_sCur ) < 0;
00366 }
00367 
00368 bool operator > ( const MString & lhs, const MString & rhs )
00369 {
00370     return strcmp( lhs.m_sCur, rhs.m_sCur ) > 0;
00371 }
00372 
00373 //YUCK! This cannot be a friend function becuse of VC6 internal compiler error!
00374 MString operator + ( const char * lhs, const MString & rhs )
00375 {
00376     return MString( lhs ) + rhs;
00377 }
00378 
00379 MString operator + ( const char lhs, const MString & rhs ) 
00380 {
00381     return MString( lhs ) + rhs;
00382 }
00383 
00384 #define FMT_BLOCK_SIZE 127
00385 
00386 MString ssprintf( const char *fmt, ...)
00387 {
00388     if ( strlen(fmt)==0 )
00389         return MString("");
00390 
00391 
00392     int CurMal = FMT_BLOCK_SIZE;
00393     MString ret;
00394 
00395     while ( true )
00396     {
00397         va_list     va;
00398         va_start(va, fmt);
00399         char * base = (char*)malloc( CurMal + 1 );
00400         #if defined(WIN32)
00401           int len = _vsnprintf( base, CurMal, fmt, va );
00402         #else
00403           int len = vsnprintf( base, CurMal, fmt, va );
00404         #endif
00405 
00406         va_end( va );
00407 
00408         if (len > CurMal)
00409             while (CurMal < len)
00410                 CurMal*=2;
00411         else
00412             if ( len > 0 )
00413             {
00414                 ret.assign( base, len );
00415                 free( base );
00416                 break;
00417             } else
00418                 CurMal*=2;
00419 
00420         free(base);
00421     }
00422     return ret;
00423 }
00424 
00425 /* 
00426  * Copyright (c) 2006, Charles Lohr
00427  * All rights reserved.
00428  *
00429  * Redistribution and use in source and binary forms, with or
00430  * without modification, are permitted provided that the following
00431  * conditions are met:
00432  *  -   Redistributions of source code must retain the above
00433  *      copyright notice, this list of conditions and the following disclaimer.
00434  *  -   Redistributions in binary form must reproduce the above copyright
00435  *      notice, this list of conditions and the following disclaimer in
00436  *      the documentation and/or other materials provided with the distribution.
00437  *  -   Neither the name of the Mercury Engine nor the names of its
00438  *      contributors may be used to endorse or promote products derived from
00439  *      this software without specific prior written permission.
00440  *
00441  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00442  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00443  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00444  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
00445  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00446  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00447  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00448  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00449  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00450  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00451  */

Hosted by SourceForge.net Logo