00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "qstring.h"
00040 #include "qregexp.h"
00041 #include "qdatastream.h"
00042
00043 #ifdef QT_THREAD_SUPPORT
00044 # include <private/qmutexpool_p.h>
00045 #endif // QT_THREAD_SUPPORT
00046
00047 #include <stdio.h>
00048 #include <stdarg.h>
00049 #include <stdlib.h>
00050 #include <ctype.h>
00051 #include <limits.h>
00052 #ifndef QT_NO_COMPRESS
00053 #include "../3rdparty/zlib/zlib.h"
00054 #endif
00055
00056
00057
00058
00059
00070 void *qmemmove( void *dst, const void *src, uint len )
00071 {
00072 register char *d;
00073 register char *s;
00074 if ( dst > src ) {
00075 d = (char *)dst + len - 1;
00076 s = (char *)src + len - 1;
00077 while ( len-- )
00078 *d-- = *s--;
00079 } else if ( dst < src ) {
00080 d = (char *)dst;
00081 s = (char *)src;
00082 while ( len-- )
00083 *d++ = *s++;
00084 }
00085 return dst;
00086 }
00087
00088
00100 char *qstrdup( const char *src )
00101 {
00102 if ( !src )
00103 return 0;
00104 char *dst = new char[strlen(src)+1];
00105 Q_CHECK_PTR( dst );
00106 return strcpy( dst, src );
00107 }
00108
00133 char *qstrncpy( char *dst, const char *src, uint len )
00134 {
00135 if ( !src || !dst )
00136 return 0;
00137 strncpy( dst, src, len );
00138 if ( len > 0 )
00139 dst[len-1] = '\0';
00140 return dst;
00141 }
00142
00216 int qstricmp( const char *str1, const char *str2 )
00217 {
00218 register const uchar *s1 = (const uchar *)str1;
00219 register const uchar *s2 = (const uchar *)str2;
00220 int res;
00221 uchar c;
00222 if ( !s1 || !s2 )
00223 return s1 ? 1 : ( s2 ? -1 : 0 );
00224 for ( ; !(res = (c=tolower(*s1)) - tolower(*s2)); s1++, s2++ )
00225 if ( !c )
00226 break;
00227 return res;
00228 }
00229
00250 int qstrnicmp( const char *str1, const char *str2, uint len )
00251 {
00252 register const uchar *s1 = (const uchar *)str1;
00253 register const uchar *s2 = (const uchar *)str2;
00254 int res;
00255 uchar c;
00256 if ( !s1 || !s2 )
00257 return s1 ? 1 : ( s2 ? -1 : 0 );
00258 for ( ; len--; s1++, s2++ ) {
00259 if ( (res = (c=tolower(*s1)) - tolower(*s2)) )
00260 return res;
00261 if ( !c )
00262 break;
00263 }
00264 return 0;
00265 }
00266
00267
00268 static Q_UINT16 crc_tbl[16];
00269 static bool crc_tbl_init = FALSE;
00270
00271 static void createCRC16Table()
00272 {
00273 register uint i;
00274 register uint j;
00275 uint v0, v1, v2, v3;
00276 for ( i = 0; i < 16; i++ ) {
00277 v0 = i & 1;
00278 v1 = ( i >> 1 ) & 1;
00279 v2 = ( i >> 2 ) & 1;
00280 v3 = ( i >> 3 ) & 1;
00281 j = 0;
00282 #undef SET_BIT
00283 #define SET_BIT(x, b, v) (x) |= (v) << (b)
00284 SET_BIT( j, 0, v0 );
00285 SET_BIT( j, 7, v0 );
00286 SET_BIT( j, 12, v0 );
00287 SET_BIT( j, 1, v1 );
00288 SET_BIT( j, 8, v1 );
00289 SET_BIT( j, 13, v1 );
00290 SET_BIT( j, 2, v2 );
00291 SET_BIT( j, 9, v2 );
00292 SET_BIT( j, 14, v2 );
00293 SET_BIT( j, 3, v3 );
00294 SET_BIT( j, 10, v3 );
00295 SET_BIT( j, 15, v3 );
00296 crc_tbl[i] = j;
00297 }
00298 }
00299
00308 Q_UINT16 qChecksum( const char *data, uint len )
00309 {
00310 if ( !crc_tbl_init ) {
00311
00312 #ifdef QT_THREAD_SUPPORT
00313 QMutexLocker locker( qt_global_mutexpool ?
00314 qt_global_mutexpool->get( &crc_tbl_init ) : 0 );
00315 #endif // QT_THREAD_SUPPORT
00316
00317 if ( !crc_tbl_init ) {
00318 createCRC16Table();
00319 crc_tbl_init = TRUE;
00320 }
00321 }
00322 register Q_UINT16 crc = 0xffff;
00323 uchar c;
00324 uchar *p = (uchar *)data;
00325 while ( len-- ) {
00326 c = *p++;
00327 crc = ( (crc >> 4) & 0x0fff ) ^ crc_tbl[((crc ^ c) & 15)];
00328 c >>= 4;
00329 crc = ( (crc >> 4) & 0x0fff ) ^ crc_tbl[((crc ^ c) & 15)];
00330 }
00331 return ~crc & 0xffff;
00332 }
00333
00354 #ifndef QT_NO_COMPRESS
00355 QByteArray qCompress( const uchar* data, int nbytes )
00356 {
00357 if ( nbytes == 0 ) {
00358 QByteArray tmp( 4 );
00359 tmp.fill( 0 );
00360 return tmp;
00361 }
00362 if ( !data ) {
00363 #if defined(QT_CHECK_RANGE)
00364 qWarning( "qCompress: data is NULL." );
00365 #endif
00366 return QByteArray();
00367 }
00368
00369 ulong len = nbytes * 2;
00370 QByteArray bazip;
00371 int res;
00372 do {
00373 bazip.resize( len + 4 );
00374 res = ::compress( (uchar*)bazip.data()+4, &len, (uchar*)data, nbytes );
00375
00376 switch ( res ) {
00377 case Z_OK:
00378 bazip.resize( len + 4 );
00379 bazip[0] = ( nbytes & 0xff000000 ) >> 24;
00380 bazip[1] = ( nbytes & 0x00ff0000 ) >> 16;
00381 bazip[2] = ( nbytes & 0x0000ff00 ) >> 8;
00382 bazip[3] = ( nbytes & 0x000000ff );
00383 break;
00384 case Z_MEM_ERROR:
00385 #if defined(QT_CHECK_RANGE)
00386 qWarning( "qCompress: Z_MEM_ERROR: Not enough memory." );
00387 #endif
00388 bazip.resize( 0 );
00389 break;
00390 case Z_BUF_ERROR:
00391 len *= 2;
00392 break;
00393 }
00394 } while ( res == Z_BUF_ERROR );
00395
00396 return bazip;
00397 }
00398 #endif
00399
00428 #ifndef QT_NO_COMPRESS
00429 QByteArray qUncompress( const uchar* data, int nbytes )
00430 {
00431 if ( !data ) {
00432 #if defined(QT_CHECK_RANGE)
00433 qWarning( "qUncompress: data is NULL." );
00434 #endif
00435 return QByteArray();
00436 }
00437 if ( nbytes <= 4 ) {
00438 #if defined(QT_CHECK_RANGE)
00439 if ( nbytes < 4 || ( data[0]!=0 || data[1]!=0 || data[2]!=0 || data[3]!=0 ) )
00440 qWarning( "qUncompress: Input data is corrupted." );
00441 #endif
00442 return QByteArray();
00443 }
00444 ulong expectedSize = ( data[0] << 24 ) | ( data[1] << 16 ) | ( data[2] << 8 ) | data[3];
00445 ulong len = QMAX( expectedSize, 1 );
00446 QByteArray baunzip;
00447 int res;
00448 do {
00449 baunzip.resize( len );
00450 res = ::uncompress( (uchar*)baunzip.data(), &len,
00451 (uchar*)data+4, nbytes-4 );
00452
00453 switch ( res ) {
00454 case Z_OK:
00455 if ( len != baunzip.size() )
00456 baunzip.resize( len );
00457 break;
00458 case Z_MEM_ERROR:
00459 #if defined(QT_CHECK_RANGE)
00460 qWarning( "qUncompress: Z_MEM_ERROR: Not enough memory." );
00461 #endif
00462 break;
00463 case Z_BUF_ERROR:
00464 len *= 2;
00465 break;
00466 case Z_DATA_ERROR:
00467 #if defined(QT_CHECK_RANGE)
00468 qWarning( "qUncompress: Z_DATA_ERROR: Input data is corrupted." );
00469 #endif
00470 break;
00471 }
00472 } while ( res == Z_BUF_ERROR );
00473
00474 if ( res != Z_OK )
00475 baunzip = QByteArray();
00476
00477 return baunzip;
00478 }
00479 #endif
00480
00481
00482
00483
00484
00511
00512
00513
00514
00523 #ifndef QT_NO_DATASTREAM
00524
00525 QDataStream &operator<<( QDataStream &s, const QByteArray &a )
00526 {
00527 return s.writeBytes( a.data(), a.size() );
00528 }
00529
00539 QDataStream &operator>>( QDataStream &s, QByteArray &a )
00540 {
00541 Q_UINT32 len;
00542 s >> len;
00543 if ( len == 0 || s.eof() ) {
00544 a.resize( 0 );
00545 return s;
00546 }
00547 if ( !a.resize( (uint)len ) ) {
00548 #if defined(QT_CHECK_NULL)
00549 qWarning( "QDataStream: Not enough memory to read QByteArray" );
00550 #endif
00551 len = 0;
00552 }
00553 if ( len > 0 )
00554 s.readRawBytes( a.data(), (uint)len );
00555 return s;
00556 }
00557
00558 #endif //QT_NO_DATASTREAM
00559
00560
00561
00562
00563
00677 QCString::QCString( int size )
00678 : QByteArray( size )
00679 {
00680 if ( size > 0 ) {
00681 *data() = '\0';
00682 *(data()+(size-1)) = '\0';
00683 }
00684 }
00685
00694 QCString::QCString( const char *str )
00695 {
00696 duplicate( str, qstrlen(str) + 1 );
00697 }
00698
00699
00716 QCString::QCString( const char *str, uint maxsize )
00717 {
00718 if ( str == 0 )
00719 return;
00720 uint len;
00721 for ( len = 0; len < maxsize - 1; len++ ) {
00722 if ( str[len] == '\0' )
00723 break;
00724 }
00725 QByteArray::resize( len + 1 );
00726 memcpy( data(), str, len );
00727 data()[len] = 0;
00728 }
00729
00734 QCString::~QCString()
00735 {
00736 }
00737
00830 bool QCString::resize( uint len )
00831 {
00832 detach();
00833 uint wasNull = isNull();
00834 if ( !QByteArray::resize(len) )
00835 return FALSE;
00836 if ( len )
00837 data()[len - 1] = '\0';
00838 if ( len > 0 && wasNull )
00839 data()[0] = '\0';
00840 return TRUE;
00841 }
00842
00843
00872 QCString &QCString::sprintf( const char *format, ... )
00873 {
00874 detach();
00875 va_list ap;
00876 va_start( ap, format );
00877 if ( size() < 256 )
00878 QByteArray::resize( 256 );
00879 vsprintf( data(), format, ap );
00880 resize( qstrlen(data()) + 1 );
00881 va_end( ap );
00882 return *this;
00883 }
00884
00885
00896 bool QCString::fill( char c, int len )
00897 {
00898 detach();
00899 if ( len < 0 )
00900 len = length();
00901 if ( !QByteArray::fill(c,len+1) )
00902 return FALSE;
00903 *(data()+len) = '\0';
00904 return TRUE;
00905 }
00906
00907
00929 int QCString::find( char c, int index, bool cs ) const
00930 {
00931 if ( (uint)index >= size() )
00932 return -1;
00933 register const char *d;
00934 if ( cs ) {
00935 d = strchr( data()+index, c );
00936 } else {
00937 d = data()+index;
00938 c = tolower( (uchar) c );
00939 while ( *d && tolower((uchar) *d) != c )
00940 d++;
00941 if ( !*d && c )
00942 d = 0;
00943 }
00944 return d ? (int)(d - data()) : -1;
00945 }
00946
00947 #define REHASH( a ) \
00948 if ( sl_minus_1 < sizeof(uint) * CHAR_BIT ) \
00949 hashHaystack -= (a) << sl_minus_1; \
00950 hashHaystack <<= 1
00951
00967 int QCString::find( const char *str, int index, bool cs ) const
00968 {
00969 return find( str, index, cs, length() );
00970 }
00971
00972 int QCString::find( const char *str, int index, bool cs, uint l ) const
00973 {
00974 if ( (uint)index >= size() )
00975 return -1;
00976 if ( !str )
00977 return -1;
00978 if ( !*str )
00979 return index;
00980 const uint sl = qstrlen( str );
00981 if ( sl + index > l )
00982 return -1;
00983
00984 if ( sl == 1 )
00985 return find( *str, index, cs );
00986
00987
00988
00989
00990 const char* needle = str;
00991 const char* haystack = data() + index;
00992 const char* end = data() + (l-sl);
00993 const uint sl_minus_1 = sl-1;
00994 uint hashNeedle = 0, hashHaystack = 0,i;
00995
00996 if ( cs ) {
00997 for ( i = 0; i < sl; ++i ) {
00998 hashNeedle = ((hashNeedle<<1) + needle[i] );
00999 hashHaystack = ((hashHaystack<<1) + haystack[i] );
01000 }
01001 hashHaystack -= *(haystack+sl_minus_1);
01002
01003 while ( haystack <= end ) {
01004 hashHaystack += *(haystack+sl_minus_1);
01005 if ( hashHaystack == hashNeedle && *needle == *haystack
01006 && qstrncmp( needle, haystack, sl ) == 0 )
01007 return haystack - data();
01008
01009 REHASH( *haystack );
01010 ++haystack;
01011 }
01012 } else {
01013 for ( i = 0; i < sl; ++i ) {
01014 hashNeedle = ((hashNeedle<<1) +
01015 tolower( needle[i] ) );
01016 hashHaystack = ((hashHaystack<<1) +
01017 tolower( haystack[i] ) );
01018 }
01019 hashHaystack -= tolower(*(haystack+sl_minus_1));
01020
01021 while ( haystack <= end ) {
01022 hashHaystack += tolower(*(haystack+sl_minus_1));
01023 if ( hashHaystack == hashNeedle
01024 && qstrnicmp( needle, haystack, sl ) == 0 )
01025 return haystack - data();
01026
01027 REHASH( tolower(*haystack) );
01028 ++haystack;
01029 }
01030 }
01031 return -1;
01032 }
01033
01034
01047 int QCString::findRev( char c, int index, bool cs ) const
01048 {
01049 register const char *b = data();
01050 register const char *d;
01051 if ( index < 0 )
01052 index = length();
01053 if ( (uint)index >= size() )
01054 return -1;
01055 d = b + index;
01056 if ( cs ) {
01057 while ( d >= b && *d != c )
01058 d--;
01059 } else {
01060 c = tolower( (uchar) c );
01061 while ( d >= b && tolower((uchar) *d) != c )
01062 d--;
01063 }
01064 return d >= b ? (int)(d - b) : -1;
01065 }
01066
01082 int QCString::findRev( const char *str, int index, bool cs ) const
01083 {
01084
01085
01086
01087 const uint sl = qstrlen( str );
01088 const uint l = length();
01089 int delta = l-sl;
01090 if ( index < 0 )
01091 index = delta;
01092 if ( index < 0 || index > (int)l )
01093 return -1;
01094 if ( index > delta )
01095 index = delta;
01096
01097 if ( sl == 1 )
01098 return findRev( *str, index, cs );
01099
01100 const char* needle = str;
01101 const char* haystack = data() + index;
01102 const char* end = data();
01103 const uint sl_minus_1 = sl-1;
01104 const char* n = needle+sl_minus_1;
01105 const char* h = haystack+sl_minus_1;
01106 uint hashNeedle = 0, hashHaystack = 0, i;
01107
01108 if ( cs ) {
01109 for ( i = 0; i < sl; ++i ) {
01110 hashNeedle = ((hashNeedle<<1) + *(n-i) );
01111 hashHaystack = ((hashHaystack<<1) + *(h-i) );
01112 }
01113 hashHaystack -= *haystack;
01114 while ( haystack >= end ) {
01115 hashHaystack += *haystack;
01116 if ( hashHaystack == hashNeedle && qstrncmp( needle, haystack, sl ) == 0 )
01117 return haystack-data();
01118 --haystack;
01119 REHASH( *(haystack+sl) );
01120 }
01121 } else {
01122 for ( i = 0; i < sl; ++i ) {
01123 hashNeedle = ((hashNeedle<<1) + tolower( *(n-i) ) );
01124 hashHaystack = ((hashHaystack<<1) + tolower( *(h-i) ) );
01125 }
01126 hashHaystack -= tolower(*haystack);
01127 while ( haystack >= end ) {
01128 hashHaystack += tolower(*haystack);
01129 if ( hashHaystack == hashNeedle && qstrnicmp( needle, haystack, sl ) == 0 )
01130 return haystack-data();
01131 --haystack;
01132 REHASH( tolower(*(haystack+sl)) );
01133 }
01134 }
01135 return -1;
01136 }
01137
01138
01149 int QCString::contains( char c, bool cs ) const
01150 {
01151 int count = 0;
01152 char *d = data();
01153 if ( !d )
01154 return 0;
01155 if ( cs ) {
01156 while ( *d )
01157 if ( *d++ == c )
01158 count++;
01159 } else {
01160 c = tolower( (uchar) c );
01161 while ( *d ) {
01162 if ( tolower((uchar) *d) == c )
01163 count++;
01164 d++;
01165 }
01166 }
01167 return count;
01168 }
01169
01185 int QCString::contains( const char *str, bool cs ) const
01186 {
01187 int count = 0;
01188 int i = -1;
01189 uint l = length();
01190
01191 while ( ( i = find ( str, i+1, cs, l ) ) != -1 )
01192 count++;
01193 return count;
01194 }
01195
01211 QCString QCString::left( uint len ) const
01212 {
01213 if ( isEmpty() ) {
01214 QCString empty;
01215 return empty;
01216 } else if ( len >= size() ) {
01217 QCString same( data() );
01218 return same;
01219 } else {
01220 QCString s( len+1 );
01221 strncpy( s.data(), data(), len );
01222 *(s.data()+len) = '\0';
01223 return s;
01224 }
01225 }
01226
01243 QCString QCString::right( uint len ) const
01244 {
01245 if ( isEmpty() ) {
01246 QCString empty;
01247 return empty;
01248 } else {
01249 uint l = length();
01250 if ( len > l )
01251 len = l;
01252 char *p = data() + (l - len);
01253 return QCString( p );
01254 }
01255 }
01256
01274 QCString QCString::mid( uint index, uint len ) const
01275 {
01276 uint slen = qstrlen( data() );
01277 if ( isEmpty() || index >= slen ) {
01278 QCString empty;
01279 return empty;
01280 } else {
01281 if ( len > slen-index )
01282 len = slen - index;
01283 register char *p = data()+index;
01284 QCString s( len+1 );
01285 strncpy( s.data(), p, len );
01286 *(s.data()+len) = '\0';
01287 return s;
01288 }
01289 }
01290
01309 QCString QCString::leftJustify( uint width, char fill, bool truncate ) const
01310 {
01311 QCString result;
01312 int len = qstrlen(data());
01313 int padlen = width - len;
01314 if ( padlen > 0 ) {
01315 result.QByteArray::resize( len+padlen+1 );
01316 memcpy( result.data(), data(), len );
01317 memset( result.data()+len, fill, padlen );
01318 result[len+padlen] = '\0';
01319 } else {
01320 if ( truncate )
01321 result = left( width );
01322 else
01323 result = copy();
01324 }
01325 return result;
01326 }
01327
01347 QCString QCString::rightJustify( uint width, char fill, bool truncate ) const
01348 {
01349 QCString result;
01350 int len = qstrlen(data());
01351 int padlen = width - len;
01352 if ( padlen > 0 ) {
01353 result.QByteArray::resize( len+padlen+1 );
01354 memset( result.data(), fill, padlen );
01355 memcpy( result.data()+padlen, data(), len );
01356 result[len+padlen] = '\0';
01357 } else {
01358 if ( truncate )
01359 result = left( width );
01360 else
01361 result = copy();
01362 }
01363 return result;
01364 }
01365
01380 QCString QCString::lower() const
01381 {
01382 QCString s( data() );
01383 register char *p = s.data();
01384 if ( p ) {
01385 while ( *p ) {
01386 *p = tolower( (uchar) *p );
01387 p++;
01388 }
01389 }
01390 return s;
01391 }
01392
01406 QCString QCString::upper() const
01407 {
01408 QCString s( data() );
01409 register char *p = s.data();
01410 if ( p ) {
01411 while ( *p ) {
01412 *p = toupper(*p);
01413 p++;
01414 }
01415 }
01416 return s;
01417 }
01418
01419
01436 QCString QCString::stripWhiteSpace() const
01437 {
01438 if ( isEmpty() )
01439 return copy();
01440
01441 register char *s = data();
01442 QCString result = s;
01443 int reslen = result.length();
01444 if ( !isspace((uchar) s[0]) && !isspace((uchar) s[reslen-1]) )
01445 return result;
01446
01447 s = result.data();
01448 int start = 0;
01449 int end = reslen - 1;
01450 while ( isspace((uchar) s[start]) )
01451 start++;
01452 if ( s[start] == '\0' ) {
01453 result.resize( 1 );
01454 return result;
01455 }
01456 while ( end && isspace((uchar) s[end]) )
01457 end--;
01458 end -= start - 1;
01459 memmove( result.data(), &s[start], end );
01460 result.resize( end + 1 );
01461 return result;
01462 }
01463
01464
01481 QCString QCString::simplifyWhiteSpace() const
01482 {
01483 if ( isEmpty() )
01484 return copy();
01485 QCString result( size() );
01486 char *from = data();
01487 char *to = result.data();
01488 char *first = to;
01489 for ( ;; ) {
01490 while ( isspace((uchar) *from) )
01491 from++;
01492 while ( *from && !isspace((uchar) *from) )
01493 *to++ = *from++;
01494 if ( *from )
01495 *to++ = 0x20;
01496 else
01497 break;
01498 }
01499 if ( to > first && *(to-1) == 0x20 )
01500 to--;
01501 *to = '\0';
01502 result.resize( (int)(to - result.data()) + 1 );
01503 return result;
01504 }
01505
01506
01525 QCString &QCString::insert( uint index, const char *s )
01526 {
01527 int len = qstrlen(s);
01528 if ( len == 0 )
01529 return *this;
01530 uint olen = length();
01531 int nlen = olen + len;
01532 if ( index >= olen ) {
01533 detach();
01534 if ( QByteArray::resize(nlen+index-olen+1, QByteArray::SpeedOptim ) ) {
01535 memset( data()+olen, ' ', index-olen );
01536 memcpy( data()+index, s, len+1 );
01537 }
01538 } else {
01539 detach();
01540 if ( QByteArray::resize(nlen+1, QByteArray::SpeedOptim ) ) {
01541 memmove( data()+index+len, data()+index, olen-index+1 );
01542 memcpy( data()+index, s, len );
01543 }
01544 }
01545 return *this;
01546 }
01547
01565 QCString &QCString::insert( uint index, char c )
01566 {
01567 char buf[2];
01568 buf[0] = c;
01569 buf[1] = '\0';
01570 return insert( index, buf );
01571 }
01572
01597 QCString &QCString::remove( uint index, uint len )
01598 {
01599 uint olen = length();
01600 if ( index + len >= olen ) {
01601 if ( index < olen ) {
01602 detach();
01603 resize( index+1 );
01604 }
01605 } else if ( len != 0 ) {
01606 detach();
01607 memmove( data()+index, data()+index+len, olen-index-len+1 );
01608 QByteArray::resize(olen-len+1, QByteArray::SpeedOptim );
01609 }
01610 return *this;
01611 }
01612
01630 QCString &QCString::replace( uint index, uint len, const char *str )
01631 {
01632 remove( index, len );
01633 insert( index, str );
01634 return *this;
01635 }
01636
01637
01650 QCString &QCString::replace( char c, const char *after )
01651 {
01652 char str[2];
01653 str[0] = c;
01654 str[1] = '\0';
01655 return replace( str, after );
01656 }
01657
01671 QCString &QCString::replace( const char *before, const char *after )
01672 {
01673 if ( before == after || isNull() )
01674 return *this;
01675
01676 detach();
01677
01678 int index = 0;
01679 const int bl = before ? strlen( before ) : 0;
01680 const int al = after ? strlen( after ) : 0;
01681 char *d = data();
01682 uint len = length();
01683
01684 if ( bl == al ) {
01685 if ( bl ) {
01686 while( (index = find( before, index, TRUE, len ) ) != -1 ) {
01687 memcpy( d+index, after, al );
01688 index += bl;
01689 }
01690 }
01691 } else if ( al < bl ) {
01692 uint to = 0;
01693 uint movestart = 0;
01694 uint num = 0;
01695 while( (index = find( before, index, TRUE, len ) ) != -1 ) {
01696 if ( num ) {
01697 int msize = index - movestart;
01698 if ( msize > 0 ) {
01699 memmove( d + to, d + movestart, msize );
01700 to += msize;
01701 }
01702 } else {
01703 to = index;
01704 }
01705 if ( al ) {
01706 memcpy( d + to, after, al );
01707 to += al;
01708 }
01709 index += bl;
01710 movestart = index;
01711 num++;
01712 }
01713 if ( num ) {
01714 int msize = len - movestart;
01715 if ( msize > 0 )
01716 memmove( d + to, d + movestart, msize );
01717 resize( len - num*(bl-al) + 1 );
01718 }
01719 } else {
01720
01721
01722 while( index != -1 ) {
01723 uint indices[4096];
01724 uint pos = 0;
01725 while( pos < 4095 ) {
01726 index = find(before, index, TRUE, len);
01727 if ( index == -1 )
01728 break;
01729 indices[pos++] = index;
01730 index += bl;
01731
01732 if ( !bl )
01733 index++;
01734 }
01735 if ( !pos )
01736 break;
01737
01738
01739 int adjust = pos*(al-bl);
01740
01741 if ( index != -1 )
01742 index += adjust;
01743 uint newlen = len + adjust;
01744 int moveend = len;
01745 if ( newlen > len ) {
01746 resize( newlen + 1 );
01747 len = newlen;
01748 }
01749 d = data();
01750
01751 while( pos ) {
01752 pos--;
01753 int movestart = indices[pos] + bl;
01754 int insertstart = indices[pos] + pos*(al-bl);
01755 int moveto = insertstart + al;
01756 memmove( d + moveto, d + movestart, (moveend - movestart) );
01757 if ( after )
01758 memcpy( d + insertstart, after, al );
01759 moveend = movestart - bl;
01760 }
01761 }
01762 }
01763 return *this;
01764 }
01765
01771 QCString &QCString::replace( char c1, char c2 )
01772 {
01773 detach();
01774 uint i = 0;
01775 char *d = data();
01776 uint len = length();
01777 while ( i < len ) {
01778 if ( d[i] == c1 )
01779 d[i] = c2;
01780 i++;
01781 }
01782 return *this;
01783 }
01784
01785
01786 #ifndef QT_NO_REGEXP_CAPTURE
01787
01801 int QCString::find( const QRegExp& rx, int index ) const
01802 {
01803 QString d = QString::fromAscii( data() );
01804 return d.find( rx, index );
01805 }
01806
01821 int QCString::findRev( const QRegExp& rx, int index ) const
01822 {
01823 QString d = QString::fromAscii( data() );
01824 return d.findRev( rx, index );
01825 }
01826
01846 int QCString::contains( const QRegExp &rx ) const
01847 {
01848 QString d = QString::fromAscii( data() );
01849 return d.contains( rx );
01850 }
01851
01852
01876 QCString &QCString::replace( const QRegExp &rx, const char *str )
01877 {
01878 QString d = QString::fromAscii( data() );
01879 QString r = QString::fromAscii( str );
01880 d.replace( rx, r );
01881 setStr( d.ascii() );
01882 return *this;
01883 }
01884 #endif //QT_NO_REGEXP
01885
01894 long QCString::toLong( bool *ok ) const
01895 {
01896 char *p = data();
01897 long val=0;
01898 const long max_mult = 214748364;
01899 bool is_ok = FALSE;
01900 int neg = 0;
01901 if ( !p )
01902 goto bye;
01903 while ( isspace((uchar) *p) )
01904 p++;
01905 if ( *p == '-' ) {
01906 p++;
01907 neg = 1;
01908 } else if ( *p == '+' ) {
01909 p++;
01910 }
01911 if ( !isdigit((uchar) *p) )
01912 goto bye;
01913 while ( isdigit((uchar) *p) ) {
01914 if ( val > max_mult || (val == max_mult && (*p-'0') > 7+neg) )
01915 goto bye;
01916 val = 10*val + (*p++ - '0');
01917 }
01918 if ( neg )
01919 val = -val;
01920 while ( isspace((uchar) *p) )
01921 p++;
01922 if ( *p == '\0' )
01923 is_ok = TRUE;
01924 bye:
01925 if ( ok )
01926 *ok = is_ok;
01927 return is_ok ? val : 0;
01928 }
01929
01938 ulong QCString::toULong( bool *ok ) const
01939 {
01940 char *p = data();
01941 ulong val=0;
01942 const ulong max_mult = 429496729;
01943 bool is_ok = FALSE;
01944 if ( !p )
01945 goto bye;
01946 while ( isspace((uchar) *p) )
01947 p++;
01948 if ( *p == '+' )
01949 p++;
01950 if ( !isdigit((uchar) *p) )
01951 goto bye;
01952 while ( isdigit((uchar) *p) ) {
01953 if ( val > max_mult || (val == max_mult && (*p-'0') > 5) )
01954 goto bye;
01955 val = 10*val + (*p++ - '0');
01956 }
01957 while ( isspace((uchar) *p) )
01958 p++;
01959 if ( *p == '\0' )
01960 is_ok = TRUE;
01961 bye:
01962 if ( ok )
01963 *ok = is_ok;
01964 return is_ok ? val : 0;
01965 }
01966
01975 short QCString::toShort( bool *ok ) const
01976 {
01977 long v = toLong( ok );
01978 if ( ok && *ok && (v < -32768 || v > 32767) )
01979 *ok = FALSE;
01980 return (short)v;
01981 }
01982
01991 ushort QCString::toUShort( bool *ok ) const
01992 {
01993 ulong v = toULong( ok );
01994 if ( ok && *ok && (v > 65535) )
01995 *ok = FALSE;
01996 return (ushort)v;
01997 }
01998
01999
02008 int QCString::toInt( bool *ok ) const
02009 {
02010 return (int)toLong( ok );
02011 }
02012
02021 uint QCString::toUInt( bool *ok ) const
02022 {
02023 return (uint)toULong( ok );
02024 }
02025
02034 double QCString::toDouble( bool *ok ) const
02035 {
02036 char *end;
02037 double val = strtod( data() ? data() : "", &end );
02038 if ( ok )
02039 *ok = ( data() && *data() && ( end == 0 || *end == '\0' ) );
02040 return val;
02041 }
02042
02051 float QCString::toFloat( bool *ok ) const
02052 {
02053 return (float)toDouble( ok );
02054 }
02055
02056
02061 QCString &QCString::setStr( const char *str )
02062 {
02063 detach();
02064 if ( str )
02065 store( str, qstrlen(str)+1 );
02066 else
02067 resize( 0 );
02068 return *this;
02069 }
02070
02078 QCString &QCString::setNum( long n )
02079 {
02080 detach();
02081 char buf[20];
02082 register char *p = &buf[19];
02083 bool neg;
02084 if ( n < 0 ) {
02085 neg = TRUE;
02086 n = -n;
02087 } else {
02088 neg = FALSE;
02089 }
02090 *p = '\0';
02091 do {
02092 *--p = ((int)(n%10)) + '0';
02093 n /= 10;
02094 } while ( n );
02095 if ( neg )
02096 *--p = '-';
02097 store( p, qstrlen(p)+1 );
02098 return *this;
02099 }
02100
02108 QCString &QCString::setNum( ulong n )
02109 {
02110 detach();
02111 char buf[20];
02112 register char *p = &buf[19];
02113 *p = '\0';
02114 do {
02115 *--p = ((int)(n%10)) + '0';
02116 n /= 10;
02117 } while ( n );
02118 store( p, qstrlen(p)+1 );
02119 return *this;
02120 }
02121
02163 QCString &QCString::setNum( double n, char f, int prec )
02164 {
02165 #if defined(QT_CHECK_RANGE)
02166 if ( !(f=='f' || f=='F' || f=='e' || f=='E' || f=='g' || f=='G') )
02167 qWarning( "QCString::setNum: Invalid format char '%c'", f );
02168 #endif
02169 char format[20];
02170 register char *fs = format;
02171 *fs++ = '%';
02172 if ( prec > 99 )
02173 prec = 99;
02174 *fs++ = '.';
02175 if ( prec >= 10 ) {
02176 *fs++ = prec / 10 + '0';
02177 *fs++ = prec % 10 + '0';
02178 } else {
02179 *fs++ = prec + '0';
02180 }
02181 *fs++ = 'l';
02182 *fs++ = f;
02183 *fs = '\0';
02184 return sprintf( format, n );
02185 }
02186
02198 bool QCString::setExpand( uint index, char c )
02199 {
02200 detach();
02201 uint oldlen = length();
02202 if ( index >= oldlen ) {
02203 if ( !QByteArray::resize( index+2 ) )
02204 return FALSE;
02205 if ( index > oldlen )
02206 memset( data() + oldlen, ' ', index - oldlen );
02207 *(data() + index+1) = '\0';
02208 }
02209 *(data() + index) = c;
02210 return TRUE;
02211 }
02212
02213
02232 QCString& QCString::operator+=( const char *str )
02233 {
02234 if ( !str )
02235 return *this;
02236 detach();
02237 uint len1 = length();
02238 uint len2 = qstrlen(str);
02239 if ( !QByteArray::resize( len1 + len2 + 1, QByteArray::SpeedOptim ) )
02240 return *this;
02241 memcpy( data() + len1, str, len2 + 1 );
02242 return *this;
02243 }
02244
02251 QCString &QCString::operator+=( char c )
02252 {
02253 detach();
02254 uint len = length();
02255 if ( !QByteArray::resize( len + 2, QByteArray::SpeedOptim ) )
02256 return *this;
02257 *(data() + len) = c;
02258 *(data() + len+1) = '\0';
02259 return *this;
02260 }
02261
02262
02263
02264
02265
02266 #ifndef QT_NO_DATASTREAM
02267
02274 QDataStream &operator<<( QDataStream &s, const QCString &str )
02275 {
02276 return s.writeBytes( str.data(), str.size() );
02277 }
02278
02287 QDataStream &operator>>( QDataStream &s, QCString &str )
02288 {
02289 str.detach();
02290 Q_UINT32 len;
02291 s >> len;
02292 if ( len == 0 || s.eof() ) {
02293 str.resize( 0 );
02294 return s;
02295 }
02296 if ( !str.QByteArray::resize( (uint)len )) {
02297 #if defined(QT_CHECK_NULL)
02298 qWarning( "QDataStream: Not enough memory to read QCString" );
02299 #endif
02300 len = 0;
02301 }
02302 if ( len > 0 )
02303 s.readRawBytes( str.data(), (uint)len );
02304 return s;
02305 }
02306 #endif //QT_NO_DATASTREAM
02307
02308
02309
02310
02311