00001 #include "MercuryString.h"
00002 #include <stdlib.h>
00003 #include <string.h>
00004
00005
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 \
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
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
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451