|
|
|
/****************************************************************************
|
|
|
|
**
|
|
|
|
** Implementation of extended char array operations, and QByteArray and
|
|
|
|
** QCString classes
|
|
|
|
**
|
|
|
|
** Created : 920722
|
|
|
|
**
|
|
|
|
** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
|
|
|
|
**
|
|
|
|
** This file is part of the tools module of the Qt GUI Toolkit.
|
|
|
|
**
|
|
|
|
** This file may be used under the terms of the GNU General
|
|
|
|
** Public License versions 2.0 or 3.0 as published by the Free
|
|
|
|
** Software Foundation and appearing in the files LICENSE.GPL2
|
|
|
|
** and LICENSE.GPL3 included in the packaging of this file.
|
|
|
|
** Alternatively you may (at your option) use any later version
|
|
|
|
** of the GNU General Public License if such license has been
|
|
|
|
** publicly approved by Trolltech ASA (or its successors, if any)
|
|
|
|
** and the KDE Free Qt Foundation.
|
|
|
|
**
|
|
|
|
** Please review the following information to ensure GNU General
|
|
|
|
** Public Licensing requirements will be met:
|
|
|
|
** http://trolltech.com/products/qt/licenses/licensing/opensource/.
|
|
|
|
** If you are unsure which license is appropriate for your use, please
|
|
|
|
** review the following information:
|
|
|
|
** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
|
|
|
|
** or contact the sales department at sales@trolltech.com.
|
|
|
|
**
|
|
|
|
** This file may be used under the terms of the Q Public License as
|
|
|
|
** defined by Trolltech ASA and appearing in the file LICENSE.QPL
|
|
|
|
** included in the packaging of this file. Licensees holding valid Qt
|
|
|
|
** Commercial licenses may use this file in accordance with the Qt
|
|
|
|
** Commercial License Agreement provided with the Software.
|
|
|
|
**
|
|
|
|
** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
|
|
|
|
** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
|
|
|
|
** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
|
|
|
|
** herein.
|
|
|
|
**
|
|
|
|
**********************************************************************/
|
|
|
|
|
|
|
|
#include "qstring.h"
|
|
|
|
#include "qregexp.h"
|
|
|
|
#include "qdatastream.h"
|
|
|
|
|
|
|
|
#ifdef QT_THREAD_SUPPORT
|
|
|
|
# include <private/qmutexpool_p.h>
|
|
|
|
#endif // QT_THREAD_SUPPORT
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <limits.h>
|
|
|
|
#ifndef QT_NO_COMPRESS
|
|
|
|
#include "../3rdparty/zlib/zlib.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
Safe and portable C string functions; extensions to standard string.h
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\relates QCString
|
|
|
|
|
|
|
|
This function is normally part of the C library. Qt implements
|
|
|
|
memmove() for platforms that do not provide it.
|
|
|
|
|
|
|
|
memmove() copies \a len bytes from \a src into \a dst. The data
|
|
|
|
is copied correctly even if \a src and \a dst overlap.
|
|
|
|
*/
|
|
|
|
|
|
|
|
void *qmemmove( void *dst, const void *src, uint len )
|
|
|
|
{
|
|
|
|
char *d;
|
|
|
|
char *s;
|
|
|
|
if ( dst > src ) {
|
|
|
|
d = (char *)dst + len - 1;
|
|
|
|
s = (char *)src + len - 1;
|
|
|
|
while ( len-- )
|
|
|
|
*d-- = *s--;
|
|
|
|
} else if ( dst < src ) {
|
|
|
|
d = (char *)dst;
|
|
|
|
s = (char *)src;
|
|
|
|
while ( len-- )
|
|
|
|
*d++ = *s++;
|
|
|
|
}
|
|
|
|
return dst;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\relates QCString
|
|
|
|
|
|
|
|
Returns a duplicate string.
|
|
|
|
|
|
|
|
Allocates space for a copy of \a src, copies it, and returns a
|
|
|
|
pointer to the copy. If \a src is 0, it immediately returns 0.
|
|
|
|
|
|
|
|
The returned string must be deleted using \c delete[].
|
|
|
|
*/
|
|
|
|
|
|
|
|
char *qstrdup( const char *src )
|
|
|
|
{
|
|
|
|
if ( !src )
|
|
|
|
return 0;
|
|
|
|
char *dst = new char[strlen(src)+1];
|
|
|
|
Q_CHECK_PTR( dst );
|
|
|
|
return strcpy( dst, src );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn char *qstrcpy( char *dst, const char *src )
|
|
|
|
|
|
|
|
\relates QCString
|
|
|
|
|
|
|
|
A safe strcpy() function.
|
|
|
|
|
|
|
|
Copies all characters up to and including the '\0' from \a src
|
|
|
|
into \a dst and returns a pointer to \a dst.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\relates QCString
|
|
|
|
|
|
|
|
A safe strncpy() function.
|
|
|
|
|
|
|
|
Copies at most \a len bytes from \a src (stopping at \a len or the
|
|
|
|
terminating '\0' whichever comes first) into \a dst and returns a
|
|
|
|
pointer to \a dst. Guarantees that \a dst is '\0'-terminated. If
|
|
|
|
\a src or \a dst is 0, returns 0 immediately.
|
|
|
|
|
|
|
|
\sa qstrcpy()
|
|
|
|
*/
|
|
|
|
|
|
|
|
char *qstrncpy( char *dst, const char *src, uint len )
|
|
|
|
{
|
|
|
|
if ( !src || !dst )
|
|
|
|
return 0;
|
|
|
|
strncpy( dst, src, len );
|
|
|
|
if ( len > 0 )
|
|
|
|
dst[len-1] = '\0';
|
|
|
|
return dst;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn uint qstrlen( const char *str );
|
|
|
|
|
|
|
|
\relates QCString
|
|
|
|
|
|
|
|
A safe strlen function.
|
|
|
|
|
|
|
|
Returns the number of characters that precede the terminating '\0'.
|
|
|
|
or 0 if \a str is 0.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn int qstrcmp( const char *str1, const char *str2 );
|
|
|
|
|
|
|
|
\relates QCString
|
|
|
|
|
|
|
|
A safe strcmp() function.
|
|
|
|
|
|
|
|
Compares \a str1 and \a str2. Returns a negative value if \a str1
|
|
|
|
is less than \a str2, 0 if \a str1 is equal to \a str2 or a
|
|
|
|
positive value if \a str1 is greater than \a str2.
|
|
|
|
|
|
|
|
Special case I: Returns 0 if \a str1 and \a str2 are both 0.
|
|
|
|
|
|
|
|
Special case II: Returns a random nonzero value if \a str1 is 0
|
|
|
|
or \a str2 is 0 (but not both).
|
|
|
|
|
|
|
|
\sa qstrncmp() qstricmp() qstrnicmp()
|
|
|
|
\link #asciinotion Note on character comparisons \endlink
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn int qstrncmp( const char *str1, const char *str2, uint len );
|
|
|
|
|
|
|
|
\relates QCString
|
|
|
|
|
|
|
|
A safe strncmp() function.
|
|
|
|
|
|
|
|
Compares at most \a len bytes of \a str1 and \a str2.
|
|
|
|
|
|
|
|
Returns a negative value if \a str1 is less than \a str2, 0 if \a
|
|
|
|
str1 is equal to \a str2 or a positive value if \a str1 is greater
|
|
|
|
than \a str2.
|
|
|
|
|
|
|
|
Special case I: Returns 0 if \a str1 and \a str2 are both 0.
|
|
|
|
|
|
|
|
Special case II: Returns a random nonzero value if \a str1 is 0
|
|
|
|
or \a str2 is 0 (but not both).
|
|
|
|
|
|
|
|
\sa qstrcmp(), qstricmp(), qstrnicmp()
|
|
|
|
\link #asciinotion Note on character comparisons \endlink
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\relates QCString
|
|
|
|
|
|
|
|
A safe stricmp() function.
|
|
|
|
|
|
|
|
Compares \a str1 and \a str2 ignoring the case.
|
|
|
|
|
|
|
|
Returns a negative value if \a str1 is less than \a str2, 0 if \a
|
|
|
|
str1 is equal to \a str2 or a positive value if \a str1 is greater
|
|
|
|
than \a str2.
|
|
|
|
|
|
|
|
Special case I: Returns 0 if \a str1 and \a str2 are both 0.
|
|
|
|
|
|
|
|
Special case II: Returns a random nonzero value if \a str1 is 0
|
|
|
|
or \a str2 is 0 (but not both).
|
|
|
|
|
|
|
|
\sa qstrcmp(), qstrncmp(), qstrnicmp()
|
|
|
|
\link #asciinotion Note on character comparisons \endlink
|
|
|
|
*/
|
|
|
|
|
|
|
|
int qstricmp( const char *str1, const char *str2 )
|
|
|
|
{
|
|
|
|
const uchar *s1 = (const uchar *)str1;
|
|
|
|
const uchar *s2 = (const uchar *)str2;
|
|
|
|
int res;
|
|
|
|
uchar c;
|
|
|
|
if ( !s1 || !s2 )
|
|
|
|
return s1 ? 1 : ( s2 ? -1 : 0 );
|
|
|
|
for ( ; !(res = (c=tolower(*s1)) - tolower(*s2)); s1++, s2++ )
|
|
|
|
if ( !c ) // strings are equal
|
|
|
|
break;
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\relates QCString
|
|
|
|
|
|
|
|
A safe strnicmp() function.
|
|
|
|
|
|
|
|
Compares at most \a len bytes of \a str1 and \a str2 ignoring the case.
|
|
|
|
|
|
|
|
Returns a negative value if \a str1 is less than \a str2, 0 if \a str1
|
|
|
|
is equal to \a str2 or a positive value if \a str1 is greater than \a
|
|
|
|
str2.
|
|
|
|
|
|
|
|
Special case I: Returns 0 if \a str1 and \a str2 are both 0.
|
|
|
|
|
|
|
|
Special case II: Returns a random nonzero value if \a str1 is 0
|
|
|
|
or \a str2 is 0 (but not both).
|
|
|
|
|
|
|
|
\sa qstrcmp(), qstrncmp() qstricmp()
|
|
|
|
\link #asciinotion Note on character comparisons \endlink
|
|
|
|
*/
|
|
|
|
|
|
|
|
int qstrnicmp( const char *str1, const char *str2, uint len )
|
|
|
|
{
|
|
|
|
const uchar *s1 = (const uchar *)str1;
|
|
|
|
const uchar *s2 = (const uchar *)str2;
|
|
|
|
int res;
|
|
|
|
uchar c;
|
|
|
|
if ( !s1 || !s2 )
|
|
|
|
return s1 ? 1 : ( s2 ? -1 : 0 );
|
|
|
|
for ( ; len--; s1++, s2++ ) {
|
|
|
|
if ( (res = (c=tolower(*s1)) - tolower(*s2)) )
|
|
|
|
return res;
|
|
|
|
if ( !c ) // strings are equal
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static Q_UINT16 crc_tbl[16];
|
|
|
|
static bool crc_tbl_init = FALSE;
|
|
|
|
|
|
|
|
static void createCRC16Table() // build CRC16 lookup table
|
|
|
|
{
|
|
|
|
uint i;
|
|
|
|
uint j;
|
|
|
|
uint v0, v1, v2, v3;
|
|
|
|
for ( i = 0; i < 16; i++ ) {
|
|
|
|
v0 = i & 1;
|
|
|
|
v1 = ( i >> 1 ) & 1;
|
|
|
|
v2 = ( i >> 2 ) & 1;
|
|
|
|
v3 = ( i >> 3 ) & 1;
|
|
|
|
j = 0;
|
|
|
|
#undef SET_BIT
|
|
|
|
#define SET_BIT(x, b, v) (x) |= (v) << (b)
|
|
|
|
SET_BIT( j, 0, v0 );
|
|
|
|
SET_BIT( j, 7, v0 );
|
|
|
|
SET_BIT( j, 12, v0 );
|
|
|
|
SET_BIT( j, 1, v1 );
|
|
|
|
SET_BIT( j, 8, v1 );
|
|
|
|
SET_BIT( j, 13, v1 );
|
|
|
|
SET_BIT( j, 2, v2 );
|
|
|
|
SET_BIT( j, 9, v2 );
|
|
|
|
SET_BIT( j, 14, v2 );
|
|
|
|
SET_BIT( j, 3, v3 );
|
|
|
|
SET_BIT( j, 10, v3 );
|
|
|
|
SET_BIT( j, 15, v3 );
|
|
|
|
crc_tbl[i] = j;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\relates QMemArray
|
|
|
|
|
|
|
|
Returns the CRC-16 checksum of \a len bytes starting at \a data.
|
|
|
|
|
|
|
|
The checksum is independent of the byte order (endianness).
|
|
|
|
*/
|
|
|
|
|
|
|
|
Q_UINT16 qChecksum( const char *data, uint len )
|
|
|
|
{
|
|
|
|
if ( !crc_tbl_init ) { // create lookup table
|
|
|
|
|
|
|
|
#ifdef QT_THREAD_SUPPORT
|
|
|
|
QMutexLocker locker( qt_global_mutexpool ?
|
|
|
|
qt_global_mutexpool->get( &crc_tbl_init ) : 0 );
|
|
|
|
#endif // QT_THREAD_SUPPORT
|
|
|
|
|
|
|
|
if ( !crc_tbl_init ) {
|
|
|
|
createCRC16Table();
|
|
|
|
crc_tbl_init = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Q_UINT16 crc = 0xffff;
|
|
|
|
uchar c;
|
|
|
|
uchar *p = (uchar *)data;
|
|
|
|
while ( len-- ) {
|
|
|
|
c = *p++;
|
|
|
|
crc = ( (crc >> 4) & 0x0fff ) ^ crc_tbl[((crc ^ c) & 15)];
|
|
|
|
c >>= 4;
|
|
|
|
crc = ( (crc >> 4) & 0x0fff ) ^ crc_tbl[((crc ^ c) & 15)];
|
|
|
|
}
|
|
|
|
return ~crc & 0xffff;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn QByteArray qCompress( const QByteArray& data )
|
|
|
|
|
|
|
|
\relates QByteArray
|
|
|
|
|
|
|
|
Compresses the array \a data and returns the compressed byte
|
|
|
|
array using zlib.
|
|
|
|
|
|
|
|
\sa qUncompress()
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\relates QByteArray
|
|
|
|
|
|
|
|
\overload
|
|
|
|
|
|
|
|
Compresses the array \a data which is \a nbytes long and returns the
|
|
|
|
compressed byte array.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef QT_NO_COMPRESS
|
|
|
|
QByteArray qCompress( const uchar* data, int nbytes )
|
|
|
|
{
|
|
|
|
if ( nbytes == 0 ) {
|
|
|
|
QByteArray tmp( 4 );
|
|
|
|
tmp.fill( 0 );
|
|
|
|
return tmp;
|
|
|
|
}
|
|
|
|
if ( !data ) {
|
|
|
|
#if defined(QT_CHECK_RANGE)
|
|
|
|
qWarning( "qCompress: data is NULL." );
|
|
|
|
#endif
|
|
|
|
return QByteArray();
|
|
|
|
}
|
|
|
|
|
|
|
|
ulong len = nbytes + nbytes / 100 + 13;
|
|
|
|
QByteArray bazip;
|
|
|
|
int res;
|
|
|
|
do {
|
|
|
|
bazip.resize( len + 4 );
|
|
|
|
res = ::compress( (uchar*)bazip.data()+4, &len, (uchar*)data, nbytes );
|
|
|
|
|
|
|
|
switch ( res ) {
|
|
|
|
case Z_OK:
|
|
|
|
bazip.resize( len + 4 );
|
|
|
|
bazip[0] = ( nbytes & 0xff000000 ) >> 24;
|
|
|
|
bazip[1] = ( nbytes & 0x00ff0000 ) >> 16;
|
|
|
|
bazip[2] = ( nbytes & 0x0000ff00 ) >> 8;
|
|
|
|
bazip[3] = ( nbytes & 0x000000ff );
|
|
|
|
break;
|
|
|
|
case Z_MEM_ERROR:
|
|
|
|
#if defined(QT_CHECK_RANGE)
|
|
|
|
qWarning( "qCompress: Z_MEM_ERROR: Not enough memory." );
|
|
|
|
#endif
|
|
|
|
bazip.resize( 0 );
|
|
|
|
break;
|
|
|
|
case Z_BUF_ERROR:
|
|
|
|
len *= 2;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} while ( res == Z_BUF_ERROR );
|
|
|
|
|
|
|
|
return bazip;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn QByteArray qUncompress( const QByteArray& data )
|
|
|
|
|
|
|
|
\relates QByteArray
|
|
|
|
|
|
|
|
Uncompresses the array \a data and returns the uncompressed byte
|
|
|
|
array.
|
|
|
|
|
|
|
|
Returns an empty QByteArray if the input data was corrupt.
|
|
|
|
\omit
|
|
|
|
ADD THE FOLLOWING FOR Qt 4.0
|
|
|
|
This function will uncompress data compressed with qCompress()
|
|
|
|
from this and any earlier Qt version, back to Qt 3.1 when this
|
|
|
|
feature was added.
|
|
|
|
\endomit
|
|
|
|
|
|
|
|
\sa qCompress()
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\relates QByteArray
|
|
|
|
|
|
|
|
\overload
|
|
|
|
|
|
|
|
Uncompresses the array \a data which is \a nbytes long and returns
|
|
|
|
the uncompressed byte array.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef QT_NO_COMPRESS
|
|
|
|
QByteArray qUncompress( const uchar* data, int nbytes )
|
|
|
|
{
|
|
|
|
if ( !data ) {
|
|
|
|
#if defined(QT_CHECK_RANGE)
|
|
|
|
qWarning( "qUncompress: data is NULL." );
|
|
|
|
#endif
|
|
|
|
return QByteArray();
|
|
|
|
}
|
|
|
|
if ( nbytes <= 4 ) {
|
|
|
|
#if defined(QT_CHECK_RANGE)
|
|
|
|
if ( nbytes < 4 || ( data[0]!=0 || data[1]!=0 || data[2]!=0 || data[3]!=0 ) )
|
|
|
|
qWarning( "qUncompress: Input data is corrupted." );
|
|
|
|
#endif
|
|
|
|
return QByteArray();
|
|
|
|
}
|
|
|
|
ulong expectedSize = ( data[0] << 24 ) | ( data[1] << 16 ) | ( data[2] << 8 ) | data[3];
|
|
|
|
ulong len = QMAX( expectedSize, 1 );
|
|
|
|
QByteArray baunzip;
|
|
|
|
int res;
|
|
|
|
do {
|
|
|
|
if ( baunzip.resize( len ) ) {
|
|
|
|
res = ::uncompress( (uchar*)baunzip.data(), &len,
|
|
|
|
(uchar*)data+4, nbytes-4 );
|
|
|
|
} else {
|
|
|
|
res = Z_MEM_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch ( res ) {
|
|
|
|
case Z_OK:
|
|
|
|
if ( len != baunzip.size() )
|
|
|
|
baunzip.resize( len );
|
|
|
|
break;
|
|
|
|
case Z_MEM_ERROR:
|
|
|
|
#if defined(QT_CHECK_RANGE)
|
|
|
|
qWarning( "qUncompress: Z_MEM_ERROR: Not enough memory." );
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
case Z_BUF_ERROR:
|
|
|
|
len *= 2;
|
|
|
|
break;
|
|
|
|
case Z_DATA_ERROR:
|
|
|
|
#if defined(QT_CHECK_RANGE)
|
|
|
|
qWarning( "qUncompress: Z_DATA_ERROR: Input data is corrupted." );
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} while ( res == Z_BUF_ERROR );
|
|
|
|
|
|
|
|
if ( res != Z_OK )
|
|
|
|
baunzip = QByteArray();
|
|
|
|
|
|
|
|
return baunzip;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
QByteArray documentation
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\class QByteArray
|
|
|
|
\reentrant
|
|
|
|
\brief The QByteArray class provides an array of bytes.
|
|
|
|
|
|
|
|
\ingroup collection
|
|
|
|
\ingroup tools
|
|
|
|
|
|
|
|
The QByteArray class provides an explicitly shared array of bytes.
|
|
|
|
It is useful for manipulating memory areas with custom data.
|
|
|
|
QByteArray is implemented as a QMemArray\<char\>. See the \l
|
|
|
|
QMemArray documentation for further information.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn QByteArray::QByteArray()
|
|
|
|
|
|
|
|
Constructs an empty QByteArray.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn QByteArray::QByteArray( int size )
|
|
|
|
|
|
|
|
Constructs a QByteArray of size \a size.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
QByteArray stream functions
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\relates QMemArray
|
|
|
|
|
|
|
|
Writes byte array \a a to the stream \a s and returns a reference
|
|
|
|
to the stream.
|
|
|
|
|
|
|
|
\sa \link datastreamformat.html Format of the QDataStream operators \endlink
|
|
|
|
*/
|
|
|
|
#ifndef QT_NO_DATASTREAM
|
|
|
|
|
|
|
|
QDataStream &operator<<( QDataStream &s, const QByteArray &a )
|
|
|
|
{
|
|
|
|
return s.writeBytes( a.data(), a.size() );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\relates QMemArray
|
|
|
|
|
|
|
|
Reads a byte array into \a a from the stream \a s and returns a
|
|
|
|
reference to the stream.
|
|
|
|
|
|
|
|
\sa \link datastreamformat.html Format of the QDataStream operators \endlink
|
|
|
|
*/
|
|
|
|
|
|
|
|
QDataStream &operator>>( QDataStream &s, QByteArray &a )
|
|
|
|
{
|
|
|
|
Q_UINT32 len;
|
|
|
|
s >> len; // read size of array
|
|
|
|
if ( len == 0 || s.eof() ) { // end of file reached
|
|
|
|
a.resize( 0 );
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
if ( !a.resize( (uint)len ) ) { // resize array
|
|
|
|
#if defined(QT_CHECK_NULL)
|
|
|
|
qWarning( "QDataStream: Not enough memory to read QByteArray" );
|
|
|
|
#endif
|
|
|
|
len = 0;
|
|
|
|
}
|
|
|
|
if ( len > 0 ) // not null array
|
|
|
|
s.readRawBytes( a.data(), (uint)len );
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif //QT_NO_DATASTREAM
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
QCString member functions
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\class QCString qcstring.h
|
|
|
|
\reentrant
|
|
|
|
\brief The QCString class provides an abstraction of the classic C
|
|
|
|
zero-terminated char array (char *).
|
|
|
|
|
|
|
|
\ingroup text
|
|
|
|
\ingroup collection
|
|
|
|
\ingroup tools
|
|
|
|
\ingroup shared
|
|
|
|
|
|
|
|
QCString inherits QByteArray, which is defined as
|
|
|
|
QMemArray\<char\>. Since QCString is a QMemArray, it uses \link
|
|
|
|
shclass.html explicit sharing\endlink with a reference count.
|
|
|
|
|
|
|
|
QCString tries to behave like a more convenient \c{const char *}.
|
|
|
|
The price of doing this is that some algorithms will perform
|
|
|
|
badly. For example, append() is O(length()) since it scans for a
|
|
|
|
null terminator. Although you might use QCString for text that is
|
|
|
|
never exposed to the user, for most purposes, and especially for
|
|
|
|
user-visible text, you should use QString. QString provides
|
|
|
|
implicit sharing, Unicode and other internationalization support,
|
|
|
|
and is well optimized.
|
|
|
|
|
|
|
|
Note that for the QCString methods that take a \c{const char *}
|
|
|
|
parameter the \c{const char *} must either be 0 (null) or not-null
|
|
|
|
and '\0' (NUL byte) terminated; otherwise the results are
|
|
|
|
undefined.
|
|
|
|
|
|
|
|
A QCString that has not been assigned to anything is \e null, i.e.
|
|
|
|
both the length and the data pointer is 0. A QCString that
|
|
|
|
references the empty string ("", a single '\0' char) is \e empty.
|
|
|
|
Both null and empty QCStrings are legal parameters to the methods.
|
|
|
|
Assigning \c{const char *} 0 to QCString produces a null QCString.
|
|
|
|
|
|
|
|
The length() function returns the length of the string; resize()
|
|
|
|
resizes the string and truncate() truncates the string. A string
|
|
|
|
can be filled with a character using fill(). Strings can be left
|
|
|
|
or right padded with characters using leftJustify() and
|
|
|
|
rightJustify(). Characters, strings and regular expressions can be
|
|
|
|
searched for using find() and findRev(), and counted using
|
|
|
|
contains().
|
|
|
|
|
|
|
|
Strings and characters can be inserted with insert() and appended
|
|
|
|
with append(). A string can be prepended with prepend().
|
|
|
|
Characters can be removed from the string with remove() and
|
|
|
|
replaced with replace().
|
|
|
|
|
|
|
|
Portions of a string can be extracted using left(), right() and
|
|
|
|
mid(). Whitespace can be removed using stripWhiteSpace() and
|
|
|
|
simplifyWhiteSpace(). Strings can be converted to uppercase or
|
|
|
|
lowercase with upper() and lower() respectively.
|
|
|
|
|
|
|
|
Strings that contain numbers can be converted to numbers with
|
|
|
|
toShort(), toInt(), toLong(), toULong(), toFloat() and toDouble().
|
|
|
|
Numbers can be converted to strings with setNum().
|
|
|
|
|
|
|
|
Many operators are overloaded to work with QCStrings. QCString
|
|
|
|
also supports some more obscure functions, e.g. sprintf(),
|
|
|
|
setStr() and setExpand().
|
|
|
|
|
|
|
|
\target asciinotion
|
|
|
|
\sidebar Note on Character Comparisons
|
|
|
|
|
|
|
|
In QCString the notion of uppercase and lowercase and of which
|
|
|
|
character is greater than or less than another character is locale
|
|
|
|
dependent. This affects functions which support a case insensitive
|
|
|
|
option or which compare or lowercase or uppercase their arguments.
|
|
|
|
Case insensitive operations and comparisons will be accurate if
|
|
|
|
both strings contain only ASCII characters. (If \c $LC_CTYPE is
|
|
|
|
set, most Unix systems do "the right thing".) Functions that this
|
|
|
|
affects include contains(), find(), findRev(), \l operator<(), \l
|
|
|
|
operator<=(), \l operator>(), \l operator>=(), lower() and
|
|
|
|
upper().
|
|
|
|
|
|
|
|
This issue does not apply to \l{QString}s since they represent
|
|
|
|
characters using Unicode.
|
|
|
|
\endsidebar
|
|
|
|
|
|
|
|
Performance note: The QCString methods for QRegExp searching are
|
|
|
|
implemented by converting the QCString to a QString and performing
|
|
|
|
the search on that. This implies a deep copy of the QCString data.
|
|
|
|
If you are going to perform many QRegExp searches on a large
|
|
|
|
QCString, you will get better performance by converting the
|
|
|
|
QCString to a QString yourself, and then searching in the QString.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn QCString::QCString()
|
|
|
|
|
|
|
|
Constructs a null string.
|
|
|
|
|
|
|
|
\sa isNull()
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn QCString::QCString( const QCString &s )
|
|
|
|
|
|
|
|
Constructs a shallow copy \a s.
|
|
|
|
|
|
|
|
\sa assign()
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Constructs a string with room for \a size characters, including
|
|
|
|
the '\0'-terminator. Makes a null string if \a size == 0.
|
|
|
|
|
|
|
|
If \a size \> 0, then the first and last characters in the string
|
|
|
|
are initialized to '\0'. All other characters are uninitialized.
|
|
|
|
|
|
|
|
\sa resize(), isNull()
|
|
|
|
*/
|
|
|
|
|
|
|
|
QCString::QCString( int size )
|
|
|
|
: QByteArray( size )
|
|
|
|
{
|
|
|
|
if ( size > 0 ) {
|
|
|
|
*data() = '\0'; // set terminator
|
|
|
|
*(data()+(size-1)) = '\0';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Constructs a string that is a deep copy of \a str.
|
|
|
|
|
|
|
|
If \a str is 0 a null string is created.
|
|
|
|
|
|
|
|
\sa isNull()
|
|
|
|
*/
|
|
|
|
|
|
|
|
QCString::QCString( const char *str )
|
|
|
|
{
|
|
|
|
duplicate( str, qstrlen(str) + 1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Constructs a string that is a deep copy of \a str. The copy will
|
|
|
|
be at most \a maxsize bytes long including the '\0'-terminator.
|
|
|
|
|
|
|
|
Example:
|
|
|
|
\code
|
|
|
|
QCString str( "helloworld", 6 ); // assigns "hello" to str
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
If \a str contains a 0 byte within the first \a maxsize bytes, the
|
|
|
|
resulting QCString will be terminated by this 0. If \a str is 0 a
|
|
|
|
null string is created.
|
|
|
|
|
|
|
|
\sa isNull()
|
|
|
|
*/
|
|
|
|
|
|
|
|
QCString::QCString( const char *str, uint maxsize )
|
|
|
|
{
|
|
|
|
if ( str == 0 )
|
|
|
|
return;
|
|
|
|
uint len; // index of first '\0'
|
|
|
|
for ( len = 0; len < maxsize - 1; len++ ) {
|
|
|
|
if ( str[len] == '\0' )
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
QByteArray::resize( len + 1 );
|
|
|
|
memcpy( data(), str, len );
|
|
|
|
data()[len] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\reimp
|
|
|
|
*/
|
|
|
|
|
|
|
|
QCString::~QCString()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn QCString &QCString::operator=( const QCString &s )
|
|
|
|
|
|
|
|
Assigns a shallow copy of \a s to this string and returns a
|
|
|
|
reference to this string.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\overload QCString &QCString::operator=( const char *str )
|
|
|
|
|
|
|
|
Assigns a deep copy of \a str to this string and returns a
|
|
|
|
reference to this string.
|
|
|
|
|
|
|
|
If \a str is 0 a null string is created.
|
|
|
|
|
|
|
|
\sa isNull()
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn bool QCString::isNull() const
|
|
|
|
|
|
|
|
Returns TRUE if the string is null, i.e. if data() == 0; otherwise
|
|
|
|
returns FALSE. A null string is also an empty string.
|
|
|
|
|
|
|
|
Example:
|
|
|
|
\code
|
|
|
|
QCString a; // a.data() == 0, a.size() == 0, a.length() == 0
|
|
|
|
QCString b == ""; // b.data() == "", b.size() == 1, b.length() == 0
|
|
|
|
a.isNull(); // TRUE because a.data() == 0
|
|
|
|
a.isEmpty(); // TRUE because a.length() == 0
|
|
|
|
b.isNull(); // FALSE because b.data() == ""
|
|
|
|
b.isEmpty(); // TRUE because b.length() == 0
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
\sa isEmpty(), length(), size()
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn bool QCString::isEmpty() const
|
|
|
|
|
|
|
|
Returns TRUE if the string is empty, i.e. if length() == 0;
|
|
|
|
otherwise returns FALSE. An empty string is not always a null
|
|
|
|
string.
|
|
|
|
|
|
|
|
See example in isNull().
|
|
|
|
|
|
|
|
\sa isNull(), length(), size()
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn uint QCString::length() const
|
|
|
|
|
|
|
|
Returns the length of the string, excluding the '\0'-terminator.
|
|
|
|
Equivalent to calling \c strlen(data()).
|
|
|
|
|
|
|
|
Null strings and empty strings have zero length.
|
|
|
|
|
|
|
|
\sa size(), isNull(), isEmpty()
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn bool QCString::truncate( uint pos )
|
|
|
|
|
|
|
|
Truncates the string at position \a pos.
|
|
|
|
|
|
|
|
Equivalent to calling \c resize(pos+1).
|
|
|
|
|
|
|
|
Example:
|
|
|
|
\code
|
|
|
|
QCString s = "truncate this string";
|
|
|
|
s.truncate( 5 ); // s == "trunc"
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
\sa resize()
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Extends or shrinks the string to \a len bytes, including the
|
|
|
|
'\0'-terminator.
|
|
|
|
|
|
|
|
A '\0'-terminator is set at position \c{len - 1} unless
|
|
|
|
\c{len == 0}.
|
|
|
|
|
|
|
|
Example:
|
|
|
|
\code
|
|
|
|
QCString s = "resize this string";
|
|
|
|
s.resize( 7 ); // s == "resize"
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
\sa truncate()
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool QCString::resize( uint len )
|
|
|
|
{
|
|
|
|
detach();
|
|
|
|
uint wasNull = isNull();
|
|
|
|
if ( !QByteArray::resize(len) )
|
|
|
|
return FALSE;
|
|
|
|
if ( len )
|
|
|
|
data()[len - 1] = '\0';
|
|
|
|
if ( len > 0 && wasNull )
|
|
|
|
data()[0] = '\0';
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Implemented as a call to the native vsprintf() (see the manual for
|
|
|
|
your C library).
|
|
|
|
|
|
|
|
If the string is shorter than 256 characters, this sprintf() calls
|
|
|
|
resize(256) to decrease the chance of memory corruption. The
|
|
|
|
string is resized back to its actual length before sprintf()
|
|
|
|
returns.
|
|
|
|
|
|
|
|
Example:
|
|
|
|
\code
|
|
|
|
QCString s;
|
|
|
|
s.sprintf( "%d - %s", 1, "first" ); // result < 256 chars
|
|
|
|
|
|
|
|
QCString big( 25000 ); // very long string
|
|
|
|
big.sprintf( "%d - %s", 2, longString ); // result < 25000 chars
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
\warning All vsprintf() implementations will write past the end of
|
|
|
|
the target string (*this) if the \a format specification and
|
|
|
|
arguments happen to be longer than the target string, and some
|
|
|
|
will also fail if the target string is longer than some arbitrary
|
|
|
|
implementation limit.
|
|
|
|
|
|
|
|
Giving user-supplied arguments to sprintf() is risky: Sooner or
|
|
|
|
later someone will paste a huge line into your application.
|
|
|
|
*/
|
|
|
|
|
|
|
|
QCString &QCString::sprintf( const char *format, ... )
|
|
|
|
{
|
|
|
|
detach();
|
|
|
|
va_list ap;
|
|
|
|
va_start( ap, format );
|
|
|
|
if ( size() < 256 )
|
|
|
|
QByteArray::resize( 256 ); // make string big enough
|
|
|
|
#ifdef QT_VSNPRINTF
|
|
|
|
QT_VSNPRINTF( data(), size(), format, ap );
|
|
|
|
#else
|
|
|
|
vsprintf( data(), format, ap );
|
|
|
|
#endif
|
|
|
|
resize( qstrlen(data()) + 1 ); // truncate
|
|
|
|
va_end( ap );
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Fills the string with \a len bytes of character \a c, followed by
|
|
|
|
a '\0'-terminator.
|
|
|
|
|
|
|
|
If \a len is negative, then the current string length is used.
|
|
|
|
|
|
|
|
Returns FALSE is \a len is nonnegative and there is not enough
|
|
|
|
memory to resize the string; otherwise returns TRUE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool QCString::fill( char c, int len )
|
|
|
|
{
|
|
|
|
detach();
|
|
|
|
if ( len < 0 )
|
|
|
|
len = length();
|
|
|
|
if ( !QByteArray::fill(c,len+1) )
|
|
|
|
return FALSE;
|
|
|
|
*(data()+len) = '\0';
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn QCString QCString::copy() const
|
|
|
|
|
|
|
|
Returns a deep copy of this string.
|
|
|
|
|
|
|
|
\sa detach()
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Finds the first occurrence of the character \a c, starting at
|
|
|
|
position \a index.
|
|
|
|
|
|
|
|
The search is case sensitive if \a cs is TRUE, or case insensitive
|
|
|
|
if \a cs is FALSE.
|
|
|
|
|
|
|
|
Returns the position of \a c, or -1 if \a c could not be found.
|
|
|
|
|
|
|
|
\sa \link #asciinotion Note on character comparisons \endlink
|
|
|
|
*/
|
|
|
|
|
|
|
|
int QCString::find( char c, int index, bool cs ) const
|
|
|
|
{
|
|
|
|
if ( (uint)index >= size() ) // index outside string
|
|
|
|
return -1;
|
|
|
|
const char *d;
|
|
|
|
if ( cs ) { // case sensitive
|
|
|
|
d = strchr( data()+index, c );
|
|
|
|
} else {
|
|
|
|
d = data()+index;
|
|
|
|
c = tolower( (uchar) c );
|
|
|
|
while ( *d && tolower((uchar) *d) != c )
|
|
|
|
d++;
|
|
|
|
if ( !*d && c ) // not found
|
|
|
|
d = 0;
|
|
|
|
}
|
|
|
|
return d ? (int)(d - data()) : -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define REHASH( a ) \
|
|
|
|
if ( sl_minus_1 < sizeof(uint) * CHAR_BIT ) \
|
|
|
|
hashHaystack -= (a) << sl_minus_1; \
|
|
|
|
hashHaystack <<= 1
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\overload
|
|
|
|
|
|
|
|
Finds the first occurrence of the string \a str, starting at
|
|
|
|
position \a index.
|
|
|
|
|
|
|
|
The search is case sensitive if \a cs is TRUE, or case insensitive
|
|
|
|
if \a cs is FALSE.
|
|
|
|
|
|
|
|
Returns the position of \a str, or -1 if \a str could not be
|
|
|
|
found.
|
|
|
|
|
|
|
|
\sa \link #asciinotion Note on character comparisons \endlink
|
|
|
|
*/
|
|
|
|
|
|
|
|
int QCString::find( const char *str, int index, bool cs ) const
|
|
|
|
{
|
|
|
|
return find( str, index, cs, length() );
|
|
|
|
}
|
|
|
|
|
|
|
|
int QCString::find( const char *str, int index, bool cs, uint l ) const
|
|
|
|
{
|
|
|
|
if ( (uint)index >= size() )
|
|
|
|
return -1;
|
|
|
|
if ( !str )
|
|
|
|
return -1;
|
|
|
|
if ( !*str )
|
|
|
|
return index;
|
|
|
|
const uint sl = qstrlen( str );
|
|
|
|
if ( sl + index > l )
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if ( sl == 1 )
|
|
|
|
return find( *str, index, cs );
|
|
|
|
|
|
|
|
/*
|
|
|
|
See QString::find() for details.
|
|
|
|
*/
|
|
|
|
const char* needle = str;
|
|
|
|
const char* haystack = data() + index;
|
|
|
|
const char* end = data() + (l-sl);
|
|
|
|
const uint sl_minus_1 = sl-1;
|
|
|
|
uint hashNeedle = 0, hashHaystack = 0,i;
|
|
|
|
|
|
|
|
if ( cs ) {
|
|
|
|
for ( i = 0; i < sl; ++i ) {
|
|
|
|
hashNeedle = ((hashNeedle<<1) + needle[i] );
|
|
|
|
hashHaystack = ((hashHaystack<<1) + haystack[i] );
|
|
|
|
}
|
|
|
|
hashHaystack -= *(haystack+sl_minus_1);
|
|
|
|
|
|
|
|
while ( haystack <= end ) {
|
|
|
|
hashHaystack += *(haystack+sl_minus_1);
|
|
|
|
if ( hashHaystack == hashNeedle && *needle == *haystack
|
|
|
|
&& qstrncmp( needle, haystack, sl ) == 0 )
|
|
|
|
return haystack - data();
|
|
|
|
|
|
|
|
REHASH( *haystack );
|
|
|
|
++haystack;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for ( i = 0; i < sl; ++i ) {
|
|
|
|
hashNeedle = ((hashNeedle<<1) +
|
|
|
|
tolower( needle[i] ) );
|
|
|
|
hashHaystack = ((hashHaystack<<1) +
|
|
|
|
tolower( haystack[i] ) );
|
|
|
|
}
|
|
|
|
hashHaystack -= tolower(*(haystack+sl_minus_1));
|
|
|
|
|
|
|
|
while ( haystack <= end ) {
|
|
|
|
hashHaystack += tolower(*(haystack+sl_minus_1));
|
|
|
|
if ( hashHaystack == hashNeedle
|
|
|
|
&& qstrnicmp( needle, haystack, sl ) == 0 )
|
|
|
|
return haystack - data();
|
|
|
|
|
|
|
|
REHASH( tolower(*haystack) );
|
|
|
|
++haystack;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Finds the first occurrence of the character \a c, starting at
|
|
|
|
position \a index and searching backwards.
|
|
|
|
|
|
|
|
The search is case sensitive if \a cs is TRUE, or case insensitive
|
|
|
|
if \a cs is FALSE.
|
|
|
|
|
|
|
|
Returns the position of \a c, or -1 if \a c could not be found.
|
|
|
|
|
|
|
|
\sa \link #asciinotion Note on character comparisons \endlink
|
|
|
|
*/
|
|
|
|
|
|
|
|
int QCString::findRev( char c, int index, bool cs ) const
|
|
|
|
{
|
|
|
|
const char *b = data();
|
|
|
|
const char *d;
|
|
|
|
if ( index < 0 )
|
|
|
|
index = length();
|
|
|
|
if ( (uint)index >= size() )
|
|
|
|
return -1;
|
|
|
|
d = b + index;
|
|
|
|
if ( cs ) {
|
|
|
|
while ( d >= b && *d != c )
|
|
|
|
d--;
|
|
|
|
} else {
|
|
|
|
c = tolower( (uchar) c );
|
|
|
|
while ( d >= b && tolower((uchar) *d) != c )
|
|
|
|
d--;
|
|
|
|
}
|
|
|
|
return d >= b ? (int)(d - b) : -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\overload
|
|
|
|
|
|
|
|
Finds the first occurrence of the string \a str, starting at
|
|
|
|
position \a index and searching backwards.
|
|
|
|
|
|
|
|
The search is case sensitive if \a cs is TRUE, or case insensitive
|
|
|
|
if \a cs is FALSE.
|
|
|
|
|
|
|
|
Returns the position of \a str, or -1 if \a str could not be
|
|
|
|
found.
|
|
|
|
|
|
|
|
\sa \link #asciinotion Note on character comparisons \endlink
|
|
|
|
*/
|
|
|
|
|
|
|
|
int QCString::findRev( const char *str, int index, bool cs ) const
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
See QString::find() for explanations.
|
|
|
|
*/
|
|
|
|
const uint sl = qstrlen( str );
|
|
|
|
const uint l = length();
|
|
|
|
int delta = l-sl;
|
|
|
|
if ( index < 0 )
|
|
|
|
index = delta;
|
|
|
|
if ( index < 0 || index > (int)l )
|
|
|
|
return -1;
|
|
|
|
if ( index > delta )
|
|
|
|
index = delta;
|
|
|
|
|
|
|
|
if ( sl == 1 )
|
|
|
|
return findRev( *str, index, cs );
|
|
|
|
|
|
|
|
const char* needle = str;
|
|
|
|
const char* haystack = data() + index;
|
|
|
|
const char* end = data();
|
|
|
|
const uint sl_minus_1 = sl-1;
|
|
|
|
const char* n = needle+sl_minus_1;
|
|
|
|
const char* h = haystack+sl_minus_1;
|
|
|
|
uint hashNeedle = 0, hashHaystack = 0, i;
|
|
|
|
|
|
|
|
if ( cs ) {
|
|
|
|
for ( i = 0; i < sl; ++i ) {
|
|
|
|
hashNeedle = ((hashNeedle<<1) + *(n-i) );
|
|
|
|
hashHaystack = ((hashHaystack<<1) + *(h-i) );
|
|
|
|
}
|
|
|
|
hashHaystack -= *haystack;
|
|
|
|
while ( haystack >= end ) {
|
|
|
|
hashHaystack += *haystack;
|
|
|
|
if ( hashHaystack == hashNeedle && qstrncmp( needle, haystack, sl ) == 0 )
|
|
|
|
return haystack-data();
|
|
|
|
--haystack;
|
|
|
|
REHASH( *(haystack+sl) );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for ( i = 0; i < sl; ++i ) {
|
|
|
|
hashNeedle = ((hashNeedle<<1) + tolower( *(n-i) ) );
|
|
|
|
hashHaystack = ((hashHaystack<<1) + tolower( *(h-i) ) );
|
|
|
|
}
|
|
|
|
hashHaystack -= tolower(*haystack);
|
|
|
|
while ( haystack >= end ) {
|
|
|
|
hashHaystack += tolower(*haystack);
|
|
|
|
if ( hashHaystack == hashNeedle && qstrnicmp( needle, haystack, sl ) == 0 )
|
|
|
|
return haystack-data();
|
|
|
|
--haystack;
|
|
|
|
REHASH( tolower(*(haystack+sl)) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Returns the number of times the character \a c occurs in the
|
|
|
|
string.
|
|
|
|
|
|
|
|
The match is case sensitive if \a cs is TRUE, or case insensitive
|
|
|
|
if \a cs if FALSE.
|
|
|
|
|
|
|
|
\sa \link #asciinotion Note on character comparisons \endlink
|
|
|
|
*/
|
|
|
|
|
|
|
|
int QCString::contains( char c, bool cs ) const
|
|
|
|
{
|
|
|
|
int count = 0;
|
|
|
|
char *d = data();
|
|
|
|
if ( !d )
|
|
|
|
return 0;
|
|
|
|
if ( cs ) { // case sensitive
|
|
|
|
while ( *d )
|
|
|
|
if ( *d++ == c )
|
|
|
|
count++;
|
|
|
|
} else { // case insensitive
|
|
|
|
c = tolower( (uchar) c );
|
|
|
|
while ( *d ) {
|
|
|
|
if ( tolower((uchar) *d) == c )
|
|
|
|
count++;
|
|
|
|
d++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\overload
|
|
|
|
|
|
|
|
Returns the number of times \a str occurs in the string.
|
|
|
|
|
|
|
|
The match is case sensitive if \a cs is TRUE, or case insensitive
|
|
|
|
if \a cs if FALSE.
|
|
|
|
|
|
|
|
This function counts overlapping substrings, for example, "banana"
|
|
|
|
contains two occurrences of "ana".
|
|
|
|
|
|
|
|
\sa findRev()
|
|
|
|
\link #asciinotion Note on character comparisons \endlink
|
|
|
|
*/
|
|
|
|
|
|
|
|
int QCString::contains( const char *str, bool cs ) const
|
|
|
|
{
|
|
|
|
int count = 0;
|
|
|
|
int i = -1;
|
|
|
|
uint l = length();
|
|
|
|
// use find for the faster hashing algorithm
|
|
|
|
while ( ( i = find ( str, i+1, cs, l ) ) != -1 )
|
|
|
|
count++;
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Returns a substring that contains the \a len leftmost characters
|
|
|
|
of the string.
|
|
|
|
|
|
|
|
The whole string is returned if \a len exceeds the length of the
|
|
|
|
string.
|
|
|
|
|
|
|
|
Example:
|
|
|
|
\code
|
|
|
|
QCString s = "Pineapple";
|
|
|
|
QCString t = s.left( 4 ); // t == "Pine"
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
\sa right(), mid()
|
|
|
|
*/
|
|
|
|
QCString QCString::left( uint len ) const
|
|
|
|
{
|
|
|
|
if ( isEmpty() ) {
|
|
|
|
QCString empty;
|
|
|
|
return empty;
|
|
|
|
} else if ( len >= size() ) {
|
|
|
|
QCString same( data() );
|
|
|
|
return same;
|
|
|
|
} else {
|
|
|
|
QCString s( len+1 );
|
|
|
|
strncpy( s.data(), data(), len );
|
|
|
|
*(s.data()+len) = '\0';
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Returns a substring that contains the \a len rightmost characters
|
|
|
|
of the string.
|
|
|
|
|
|
|
|
The whole string is returned if \a len exceeds the length of the
|
|
|
|
string.
|
|
|
|
|
|
|
|
Example:
|
|
|
|
\code
|
|
|
|
QCString s = "Pineapple";
|
|
|
|
QCString t = s.right( 5 ); // t == "apple"
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
\sa left(), mid()
|
|
|
|
*/
|
|
|
|
|
|
|
|
QCString QCString::right( uint len ) const
|
|
|
|
{
|
|
|
|
if ( isEmpty() ) {
|
|
|
|
QCString empty;
|
|
|
|
return empty;
|
|
|
|
} else {
|
|
|
|
uint l = length();
|
|
|
|
if ( len > l )
|
|
|
|
len = l;
|
|
|
|
char *p = data() + (l - len);
|
|
|
|
return QCString( p );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Returns a substring that contains at most \a len characters from
|
|
|
|
this string, starting at position \a index.
|
|
|
|
|
|
|
|
Returns a null string if the string is empty or if \a index is out
|
|
|
|
of range. Returns the whole string from \a index if \a index+len
|
|
|
|
exceeds the length of the string.
|
|
|
|
|
|
|
|
Example:
|
|
|
|
\code
|
|
|
|
QCString s = "Two pineapples";
|
|
|
|
QCString t = s.mid( 4, 3 ); // t == "pin"
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
\sa left(), right()
|
|
|
|
*/
|
|
|
|
|
|
|
|
QCString QCString::mid( uint index, uint len ) const
|
|
|
|
{
|
|
|
|
uint slen = qstrlen( data() );
|
|
|
|
if ( isEmpty() || index >= slen ) {
|
|
|
|
QCString empty;
|
|
|
|
return empty;
|
|
|
|
} else {
|
|
|
|
if ( len > slen-index )
|
|
|
|
len = slen - index;
|
|
|
|
char *p = data()+index;
|
|
|
|
QCString s( len+1 );
|
|
|
|
strncpy( s.data(), p, len );
|
|
|
|
*(s.data()+len) = '\0';
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Returns a string of length \a width (plus one for the terminating
|
|
|
|
'\0') that contains this string padded with the \a fill character.
|
|
|
|
|
|
|
|
If the length of the string exceeds \a width and \a truncate is
|
|
|
|
FALSE (the default), then the returned string is a copy of the
|
|
|
|
string. If the length of the string exceeds \a width and \a
|
|
|
|
truncate is TRUE, then the returned string is a left(\a width).
|
|
|
|
|
|
|
|
Example:
|
|
|
|
\code
|
|
|
|
QCString s("apple");
|
|
|
|
QCString t = s.leftJustify(8, '.'); // t == "apple..."
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
\sa rightJustify()
|
|
|
|
*/
|
|
|
|
|
|
|
|
QCString QCString::leftJustify( uint width, char fill, bool truncate ) const
|
|
|
|
{
|
|
|
|
QCString result;
|
|
|
|
int len = qstrlen(data());
|
|
|
|
int padlen = width - len;
|
|
|
|
if ( padlen > 0 ) {
|
|
|
|
result.QByteArray::resize( len+padlen+1 );
|
|
|
|
memcpy( result.data(), data(), len );
|
|
|
|
memset( result.data()+len, fill, padlen );
|
|
|
|
result[len+padlen] = '\0';
|
|
|
|
} else {
|
|
|
|
if ( truncate )
|
|
|
|
result = left( width );
|
|
|
|
else
|
|
|
|
result = copy();
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Returns a string of length \a width (plus one for the terminating
|
|
|
|
'\0') that contains zero or more of the \a fill character followed
|
|
|
|
by this string.
|
|
|
|
|
|
|
|
If the length of the string exceeds \a width and \a truncate is
|
|
|
|
FALSE (the default), then the returned string is a copy of the
|
|
|
|
string. If the length of the string exceeds \a width and \a
|
|
|
|
truncate is TRUE, then the returned string is a left(\a width).
|
|
|
|
|
|
|
|
Example:
|
|
|
|
\code
|
|
|
|
QCString s("pie");
|
|
|
|
QCString t = s.rightJustify(8, '.'); // t == ".....pie"
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
\sa leftJustify()
|
|
|
|
*/
|
|
|
|
|
|
|
|
QCString QCString::rightJustify( uint width, char fill, bool truncate ) const
|
|
|
|
{
|
|
|
|
QCString result;
|
|
|
|
int len = qstrlen(data());
|
|
|
|
int padlen = width - len;
|
|
|
|
if ( padlen > 0 ) {
|
|
|
|
result.QByteArray::resize( len+padlen+1 );
|
|
|
|
memset( result.data(), fill, padlen );
|
|
|
|
memcpy( result.data()+padlen, data(), len );
|
|
|
|
result[len+padlen] = '\0';
|
|
|
|
} else {
|
|
|
|
if ( truncate )
|
|
|
|
result = left( width );
|
|
|
|
else
|
|
|
|
result = copy();
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Returns a new string that is a copy of this string converted to lower
|
|
|
|
case.
|
|
|
|
|
|
|
|
Example:
|
|
|
|
\code
|
|
|
|
QCString s("Credit");
|
|
|
|
QCString t = s.lower(); // t == "credit"
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
\sa upper()
|
|
|
|
\link #asciinotion Note on character comparisons \endlink
|
|
|
|
*/
|
|
|
|
|
|
|
|
QCString QCString::lower() const
|
|
|
|
{
|
|
|
|
QCString s( data() );
|
|
|
|
char *p = s.data();
|
|
|
|
if ( p ) {
|
|
|
|
while ( *p ) {
|
|
|
|
*p = tolower( (uchar) *p );
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Returns a new string that is a copy of this string converted to upper case.
|
|
|
|
|
|
|
|
Example:
|
|
|
|
\code
|
|
|
|
QCString s( "Debit" );
|
|
|
|
QCString t = s.upper(); // t == "DEBIT"
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
\sa lower()
|
|
|
|
\link #asciinotion Note on character comparisons \endlink
|
|
|
|
*/
|
|
|
|
|
|
|
|
QCString QCString::upper() const
|
|
|
|
{
|
|
|
|
QCString s( data() );
|
|
|
|
char *p = s.data();
|
|
|
|
if ( p ) {
|
|
|
|
while ( *p ) {
|
|
|
|
*p = toupper(*p);
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Returns a new string that has white space removed from the start
|
|
|
|
and the end.
|
|
|
|
|
|
|
|
White space means the decimal ASCII codes 9, 10, 11, 12, 13 and
|
|
|
|
32.
|
|
|
|
|
|
|
|
Example:
|
|
|
|
\code
|
|
|
|
QCString s = " space ";
|
|
|
|
QCString t = s.stripWhiteSpace(); // t == "space"
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
\sa simplifyWhiteSpace()
|
|
|
|
*/
|
|
|
|
|
|
|
|
QCString QCString::stripWhiteSpace() const
|
|
|
|
{
|
|
|
|
if ( isEmpty() ) // nothing to do
|
|
|
|
return copy();
|
|
|
|
|
|
|
|
char *s = data();
|
|
|
|
QCString result = s;
|
|
|
|
int reslen = result.length();
|
|
|
|
if ( !isspace((uchar) s[0]) && !isspace((uchar) s[reslen-1]) )
|
|
|
|
return result; // returns a copy
|
|
|
|
|
|
|
|
s = result.data();
|
|
|
|
int start = 0;
|
|
|
|
int end = reslen - 1;
|
|
|
|
while ( isspace((uchar) s[start]) ) // skip white space from start
|
|
|
|
start++;
|
|
|
|
if ( s[start] == '\0' ) { // only white space
|
|
|
|
result.resize( 1 );
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
while ( end && isspace((uchar) s[end]) ) // skip white space from end
|
|
|
|
end--;
|
|
|
|
end -= start - 1;
|
|
|
|
memmove( result.data(), &s[start], end );
|
|
|
|
result.resize( end + 1 );
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Returns a new string that has white space removed from the start
|
|
|
|
and the end, plus any sequence of internal white space replaced
|
|
|
|
with a single space (ASCII 32).
|
|
|
|
|
|
|
|
White space means the decimal ASCII codes 9, 10, 11, 12, 13 and
|
|
|
|
32.
|
|
|
|
|
|
|
|
\code
|
|
|
|
QCString s = " lots\t of\nwhite space ";
|
|
|
|
QCString t = s.simplifyWhiteSpace(); // t == "lots of white space"
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
\sa stripWhiteSpace()
|
|
|
|
*/
|
|
|
|
|
|
|
|
QCString QCString::simplifyWhiteSpace() const
|
|
|
|
{
|
|
|
|
if ( isEmpty() ) // nothing to do
|
|
|
|
return copy();
|
|
|
|
QCString result( size() );
|
|
|
|
char *from = data();
|
|
|
|
char *to = result.data();
|
|
|
|
char *first = to;
|
|
|
|
for ( ;; ) {
|
|
|
|
while ( isspace((uchar) *from) )
|
|
|
|
from++;
|
|
|
|
while ( *from && !isspace((uchar) *from) )
|
|
|
|
*to++ = *from++;
|
|
|
|
if ( *from )
|
|
|
|
*to++ = 0x20; // ' '
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if ( to > first && *(to-1) == 0x20 )
|
|
|
|
to--;
|
|
|
|
*to = '\0';
|
|
|
|
result.resize( (int)(to - result.data()) + 1 );
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\overload
|
|
|
|
|
|
|
|
Inserts string \a s into the string at position \a index.
|
|
|
|
|
|
|
|
If \a index is beyond the end of the string, the string is
|
|
|
|
padded with spaces (ASCII 32) to length \a index and then \a s
|
|
|
|
is appended.
|
|
|
|
|
|
|
|
\code
|
|
|
|
QCString s = "I like fish";
|
|
|
|
s.insert( 2, "don't "); // s == "I don't like fish"
|
|
|
|
|
|
|
|
s = "x"; // index 01234
|
|
|
|
s.insert( 3, "yz" ); // s == "x yz"
|
|
|
|
\endcode
|
|
|
|
*/
|
|
|
|
|
|
|
|
QCString &QCString::insert( uint index, const char *s )
|
|
|
|
{
|
|
|
|
int len = qstrlen(s);
|
|
|
|
if ( len == 0 )
|
|
|
|
return *this;
|
|
|
|
uint olen = length();
|
|
|
|
int nlen = olen + len;
|
|
|
|
if ( index >= olen ) { // insert after end of string
|
|
|
|
detach();
|
|
|
|
if ( QByteArray::resize(nlen+index-olen+1, QByteArray::SpeedOptim ) ) {
|
|
|
|
memset( data()+olen, ' ', index-olen );
|
|
|
|
memcpy( data()+index, s, len+1 );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
detach();
|
|
|
|
if ( QByteArray::resize(nlen+1, QByteArray::SpeedOptim ) ) { // normal insert
|
|
|
|
memmove( data()+index+len, data()+index, olen-index+1 );
|
|
|
|
memcpy( data()+index, s, len );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Inserts character \a c into the string at position \a index and
|
|
|
|
returns a reference to the string.
|
|
|
|
|
|
|
|
If \a index is beyond the end of the string, the string is
|
|
|
|
padded with spaces (ASCII 32) to length \a index and then \a c
|
|
|
|
is appended.
|
|
|
|
|
|
|
|
Example:
|
|
|
|
\code
|
|
|
|
QCString s = "Yes";
|
|
|
|
s.insert( 3, '!'); // s == "Yes!"
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
\sa remove(), replace()
|
|
|
|
*/
|
|
|
|
|
|
|
|
QCString &QCString::insert( uint index, char c ) // insert char
|
|
|
|
{
|
|
|
|
char buf[2];
|
|
|
|
buf[0] = c;
|
|
|
|
buf[1] = '\0';
|
|
|
|
return insert( index, buf );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn QCString &QCString::prepend( const char *s )
|
|
|
|
|
|
|
|
Prepend \a s to the string. Equivalent to insert(0, s).
|
|
|
|
|
|
|
|
\sa insert()
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Removes \a len characters from the string, starting at position \a
|
|
|
|
index, and returns a reference to the string.
|
|
|
|
|
|
|
|
If \a index is out of range, nothing happens. If \a index is
|
|
|
|
valid, but \a index + \a len is larger than the length of the
|
|
|
|
string, the string is truncated at position \a index.
|
|
|
|
|
|
|
|
\code
|
|
|
|
QCString s = "Montreal";
|
|
|
|
s.remove( 1, 4 ); // s == "Meal"
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
\sa insert(), replace()
|
|
|
|
*/
|
|
|
|
|
|
|
|
QCString &QCString::remove( uint index, uint len )
|
|
|
|
{
|
|
|
|
uint olen = length();
|
|
|
|
if ( index + len >= olen ) { // range problems
|
|
|
|
if ( index < olen ) { // index ok
|
|
|
|
detach();
|
|
|
|
resize( index+1 );
|
|
|
|
}
|
|
|
|
} else if ( len != 0 ) {
|
|
|
|
detach();
|
|
|
|
memmove( data()+index, data()+index+len, olen-index-len+1 );
|
|
|
|
QByteArray::resize(olen-len+1, QByteArray::SpeedOptim );
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Replaces \a len characters from the string, starting at position
|
|
|
|
\a index, with \a str, and returns a reference to the string.
|
|
|
|
|
|
|
|
If \a index is out of range, nothing is removed and \a str is
|
|
|
|
appended at the end of the string. If \a index is valid, but \a
|
|
|
|
index + \a len is larger than the length of the string, \a str
|
|
|
|
replaces the rest of the string from position \a index.
|
|
|
|
|
|
|
|
\code
|
|
|
|
QCString s = "Say yes!";
|
|
|
|
s.replace( 4, 3, "NO" ); // s == "Say NO!"
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
\sa insert(), remove()
|
|
|
|
*/
|
|
|
|
|
|
|
|
QCString &QCString::replace( uint index, uint len, const char *str )
|
|
|
|
{
|
|
|
|
remove( index, len );
|
|
|
|
insert( index, str );
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*! \overload
|
|
|
|
|
|
|
|
Replaces every occurrence of the character \a c in the string
|
|
|
|
with \a after. Returns a reference to the string.
|
|
|
|
|
|
|
|
Example:
|
|
|
|
\code
|
|
|
|
QCString s = "a,b,c";
|
|
|
|
s.replace( ',', " or " );
|
|
|
|
// s == "a or b or c"
|
|
|
|
\endcode
|
|
|
|
*/
|
|
|
|
QCString &QCString::replace( char c, const char *after )
|
|
|
|
{
|
|
|
|
char str[2];
|
|
|
|
str[0] = c;
|
|
|
|
str[1] = '\0';
|
|
|
|
return replace( str, after );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*! \overload
|
|
|
|
|
|
|
|
Replaces every occurrence of the string \a before in the string
|
|
|
|
with the string \a after. Returns a reference to the string.
|
|
|
|
|
|
|
|
Example:
|
|
|
|
\code
|
|
|
|
QCString s = "Greek is Greek";
|
|
|
|
s.replace( "Greek", "English" );
|
|
|
|
// s == "English is English"
|
|
|
|
\endcode
|
|
|
|
*/
|
|
|
|
|
|
|
|
QCString &QCString::replace( const char *before, const char *after )
|
|
|
|
{
|
|
|
|
if ( before == after || isNull() )
|
|
|
|
return *this;
|
|
|
|
|
|
|
|
detach();
|
|
|
|
|
|
|
|
int index = 0;
|
|
|
|
const int bl = before ? int(strlen( before )) : 0;
|
|
|
|
const int al = after ? int(strlen( after )) : 0;
|
|
|
|
char *d = data();
|
|
|
|
uint len = length();
|
|
|
|
|
|
|
|
if ( bl == al ) {
|
|
|
|
if ( bl ) {
|
|
|
|
while( (index = find( before, index, TRUE, len ) ) != -1 ) {
|
|
|
|
memcpy( d+index, after, al );
|
|
|
|
index += bl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if ( al < bl ) {
|
|
|
|
uint to = 0;
|
|
|
|
uint movestart = 0;
|
|
|
|
uint num = 0;
|
|
|
|
while( (index = find( before, index, TRUE, len ) ) != -1 ) {
|
|
|
|
if ( num ) {
|
|
|
|
int msize = index - movestart;
|
|
|
|
if ( msize > 0 ) {
|
|
|
|
memmove( d + to, d + movestart, msize );
|
|
|
|
to += msize;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
to = index;
|
|
|
|
}
|
|
|
|
if ( al ) {
|
|
|
|
memcpy( d + to, after, al );
|
|
|
|
to += al;
|
|
|
|
}
|
|
|
|
index += bl;
|
|
|
|
movestart = index;
|
|
|
|
num++;
|
|
|
|
}
|
|
|
|
if ( num ) {
|
|
|
|
int msize = len - movestart;
|
|
|
|
if ( msize > 0 )
|
|
|
|
memmove( d + to, d + movestart, msize );
|
|
|
|
resize( len - num*(bl-al) + 1 );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// the most complex case. We don't want to loose performance by doing repeated
|
|
|
|
// copies and reallocs of the string.
|
|
|
|
while( index != -1 ) {
|
|
|
|
uint indices[4096];
|
|
|
|
uint pos = 0;
|
|
|
|
while( pos < 4095 ) {
|
|
|
|
index = find(before, index, TRUE, len);
|
|
|
|
if ( index == -1 )
|
|
|
|
break;
|
|
|
|
indices[pos++] = index;
|
|
|
|
index += bl;
|
|
|
|
// avoid infinite loop
|
|
|
|
if ( !bl )
|
|
|
|
index++;
|
|
|
|
}
|
|
|
|
if ( !pos )
|
|
|
|
break;
|
|
|
|
|
|
|
|
// we have a table of replacement positions, use them for fast replacing
|
|
|
|
int adjust = pos*(al-bl);
|
|
|
|
// index has to be adjusted in case we get back into the loop above.
|
|
|
|
if ( index != -1 )
|
|
|
|
index += adjust;
|
|
|
|
uint newlen = len + adjust;
|
|
|
|
int moveend = len;
|
|
|
|
if ( newlen > len ) {
|
|
|
|
resize( newlen + 1 );
|
|
|
|
len = newlen;
|
|
|
|
}
|
|
|
|
d = data();
|
|
|
|
|
|
|
|
while( pos ) {
|
|
|
|
pos--;
|
|
|
|
int movestart = indices[pos] + bl;
|
|
|
|
int insertstart = indices[pos] + pos*(al-bl);
|
|
|
|
int moveto = insertstart + al;
|
|
|
|
memmove( d + moveto, d + movestart, (moveend - movestart) );
|
|
|
|
if ( after )
|
|
|
|
memcpy( d + insertstart, after, al );
|
|
|
|
moveend = movestart - bl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*! \overload
|
|
|
|
|
|
|
|
Replaces every occurrence of \a c1 with the char \a c2.
|
|
|
|
Returns a reference to the string.
|
|
|
|
*/
|
|
|
|
QCString &QCString::replace( char c1, char c2 )
|
|
|
|
{
|
|
|
|
detach();
|
|
|
|
uint i = 0;
|
|
|
|
char *d = data();
|
|
|
|
uint len = length();
|
|
|
|
while ( i < len ) {
|
|
|
|
if ( d[i] == c1 )
|
|
|
|
d[i] = c2;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef QT_NO_REGEXP_CAPTURE
|
|
|
|
/*!
|
|
|
|
\overload
|
|
|
|
|
|
|
|
Finds the first occurrence of the regular expression \a rx,
|
|
|
|
starting at position \a index.
|
|
|
|
|
|
|
|
Returns the position of the next match, or -1 if \a rx was not
|
|
|
|
found.
|
|
|
|
|
|
|
|
\warning If you want to apply this function repeatedly to the same
|
|
|
|
string it is more efficient to convert the string to a QString and
|
|
|
|
apply the function to that.
|
|
|
|
*/
|
|
|
|
|
|
|
|
int QCString::find( const QRegExp& rx, int index ) const
|
|
|
|
{
|
|
|
|
QString d = QString::fromAscii( data() );
|
|
|
|
return d.find( rx, index );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\overload
|
|
|
|
|
|
|
|
Finds the first occurrence of the regular expression \a rx,
|
|
|
|
starting at position \a index and searching backwards.
|
|
|
|
|
|
|
|
Returns the position of the next match (backwards), or -1 if \a rx
|
|
|
|
was not found.
|
|
|
|
|
|
|
|
\warning If you want to apply this function repeatedly to the same
|
|
|
|
string it is more efficient to convert the string to a QString and
|
|
|
|
apply the function to that.
|
|
|
|
*/
|
|
|
|
|
|
|
|
int QCString::findRev( const QRegExp& rx, int index ) const
|
|
|
|
{
|
|
|
|
QString d = QString::fromAscii( data() );
|
|
|
|
return d.findRev( rx, index );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\overload
|
|
|
|
|
|
|
|
Counts the number of overlapping occurrences of \a rx in the string.
|
|
|
|
|
|
|
|
Example:
|
|
|
|
\code
|
|
|
|
QString s = "banana and panama";
|
|
|
|
QRegExp r = QRegExp( "a[nm]a", TRUE, FALSE );
|
|
|
|
s.contains( r ); // 4 matches
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
\sa find(), findRev()
|
|
|
|
|
|
|
|
\warning If you want to apply this function repeatedly to the same
|
|
|
|
string it is more efficient to convert the string to a QString and
|
|
|
|
apply the function to that.
|
|
|
|
*/
|
|
|
|
|
|
|
|
int QCString::contains( const QRegExp &rx ) const
|
|
|
|
{
|
|
|
|
QString d = QString::fromAscii( data() );
|
|
|
|
return d.contains( rx );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\overload
|
|
|
|
|
|
|
|
Replaces every occurrence of \a rx in the string with \a str.
|
|
|
|
Returns a reference to the string.
|
|
|
|
|
|
|
|
Example:
|
|
|
|
\code
|
|
|
|
QString s = "banana";
|
|
|
|
s.replace( QRegExp("a.*a"), "" ); // becomes "b"
|
|
|
|
|
|
|
|
s = "banana";
|
|
|
|
s.replace( QRegExp("^[bn]a"), "X" ); // becomes "Xnana"
|
|
|
|
|
|
|
|
s = "banana";
|
|
|
|
s.replace( QRegExp("^[bn]a"), "" ); // becomes "nana"
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
\warning If you want to apply this function repeatedly to the same
|
|
|
|
string it is more efficient to convert the string to a QString and
|
|
|
|
apply the function to that.
|
|
|
|
*/
|
|
|
|
|
|
|
|
QCString &QCString::replace( const QRegExp &rx, const char *str )
|
|
|
|
{
|
|
|
|
QString d = QString::fromAscii( data() );
|
|
|
|
QString r = QString::fromAscii( str );
|
|
|
|
d.replace( rx, r );
|
|
|
|
setStr( d.ascii() );
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
#endif //QT_NO_REGEXP
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Returns the string converted to a \c long value.
|
|
|
|
|
|
|
|
If \a ok is not 0: \a *ok is set to FALSE if the string is not a
|
|
|
|
number, or if it has trailing garbage; otherwise \a *ok is set to
|
|
|
|
TRUE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
long QCString::toLong( bool *ok ) const
|
|
|
|
{
|
|
|
|
char *p = data();
|
|
|
|
long val=0;
|
|
|
|
const long max_mult = LONG_MAX / 10;
|
|
|
|
bool is_ok = FALSE;
|
|
|
|
int neg = 0;
|
|
|
|
if ( !p )
|
|
|
|
goto bye;
|
|
|
|
while ( isspace((uchar) *p) ) // skip leading space
|
|
|
|
p++;
|
|
|
|
if ( *p == '-' ) {
|
|
|
|
p++;
|
|
|
|
neg = 1;
|
|
|
|
} else if ( *p == '+' ) {
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
if ( !isdigit((uchar) *p) )
|
|
|
|
goto bye;
|
|
|
|
while ( isdigit((uchar) *p) ) {
|
|
|
|
if ( val > max_mult || (val == max_mult && (*p-'0') > 7+neg) )
|
|
|
|
goto bye;
|
|
|
|
val = 10*val + (*p++ - '0');
|
|
|
|
}
|
|
|
|
if ( neg )
|
|
|
|
val = -val;
|
|
|
|
while ( isspace((uchar) *p) ) // skip trailing space
|
|
|
|
p++;
|
|
|
|
if ( *p == '\0' )
|
|
|
|
is_ok = TRUE;
|
|
|
|
bye:
|
|
|
|
if ( ok )
|
|
|
|
*ok = is_ok;
|
|
|
|
return is_ok ? val : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Returns the string converted to an \c{unsigned long} value.
|
|
|
|
|
|
|
|
If \a ok is not 0: \a *ok is set to FALSE if the string is not a
|
|
|
|
number, or if it has trailing garbage; otherwise \a *ok is set to
|
|
|
|
TRUE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
ulong QCString::toULong( bool *ok ) const
|
|
|
|
{
|
|
|
|
char *p = data();
|
|
|
|
ulong val=0;
|
|
|
|
const ulong max_mult = ULONG_MAX / 10;
|
|
|
|
bool is_ok = FALSE;
|
|
|
|
if ( !p )
|
|
|
|
goto bye;
|
|
|
|
while ( isspace((uchar) *p) ) // skip leading space
|
|
|
|
p++;
|
|
|
|
if ( *p == '+' )
|
|
|
|
p++;
|
|
|
|
if ( !isdigit((uchar) *p) )
|
|
|
|
goto bye;
|
|
|
|
while ( isdigit((uchar) *p) ) {
|
|
|
|
if ( val > max_mult || (val == max_mult && (*p-'0') > 5) )
|
|
|
|
goto bye;
|
|
|
|
val = 10*val + (*p++ - '0');
|
|
|
|
}
|
|
|
|
while ( isspace((uchar) *p) ) // skip trailing space
|
|
|
|
p++;
|
|
|
|
if ( *p == '\0' )
|
|
|
|
is_ok = TRUE;
|
|
|
|
bye:
|
|
|
|
if ( ok )
|
|
|
|
*ok = is_ok;
|
|
|
|
return is_ok ? val : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Returns the string converted to a \c{short} value.
|
|
|
|
|
|
|
|
If \a ok is not 0: \a *ok is set to FALSE if the string is not a
|
|
|
|
number, is out of range, or if it has trailing garbage; otherwise
|
|
|
|
\a *ok is set to TRUE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
short QCString::toShort( bool *ok ) const
|
|
|
|
{
|
|
|
|
long v = toLong( ok );
|
|
|
|
if ( v < SHRT_MIN || v > SHRT_MAX ) {
|
|
|
|
if ( ok )
|
|
|
|
*ok = FALSE;
|
|
|
|
v = 0;
|
|
|
|
}
|
|
|
|
return (short)v;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Returns the string converted to an \c{unsigned short} value.
|
|
|
|
|
|
|
|
If \a ok is not 0: \a *ok is set to FALSE if the string is not a
|
|
|
|
number, is out of range, or if it has trailing garbage; otherwise
|
|
|
|
\a *ok is set to TRUE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
ushort QCString::toUShort( bool *ok ) const
|
|
|
|
{
|
|
|
|
ulong v = toULong( ok );
|
|
|
|
if ( v > USHRT_MAX ) {
|
|
|
|
if ( ok )
|
|
|
|
*ok = FALSE;
|
|
|
|
v = 0;
|
|
|
|
}
|
|
|
|
return (ushort)v;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Returns the string converted to a \c{int} value.
|
|
|
|
|
|
|
|
If \a ok is not 0: \a *ok is set to FALSE if the string is not a
|
|
|
|
number, or if it has trailing garbage; otherwise \a *ok is set to
|
|
|
|
TRUE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
int QCString::toInt( bool *ok ) const
|
|
|
|
{
|
|
|
|
long v = toLong( ok );
|
|
|
|
if ( v < INT_MIN || v > INT_MAX ) {
|
|
|
|
if ( ok )
|
|
|
|
*ok = FALSE;
|
|
|
|
v = 0;
|
|
|
|
}
|
|
|
|
return (int)v;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Returns the string converted to an \c{unsigned int} value.
|
|
|
|
|
|
|
|
If \a ok is not 0: \a *ok is set to FALSE if the string is not a
|
|
|
|
number, or if it has trailing garbage; otherwise \a *ok is set to
|
|
|
|
TRUE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
uint QCString::toUInt( bool *ok ) const
|
|
|
|
{
|
|
|
|
ulong v = toULong( ok );
|
|
|
|
if ( v > UINT_MAX ) {
|
|
|
|
if ( ok )
|
|
|
|
*ok = FALSE;
|
|
|
|
v = 0;
|
|
|
|
}
|
|
|
|
return (uint)v;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Returns the string converted to a \c{double} value.
|
|
|
|
|
|
|
|
If \a ok is not 0: \a *ok is set to FALSE if the string is not a
|
|
|
|
number, or if it has trailing garbage; otherwise \a *ok is set to
|
|
|
|
TRUE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
double QCString::toDouble( bool *ok ) const
|
|
|
|
{
|
|
|
|
char *end;
|
|
|
|
double val = strtod( data() ? data() : "", &end );
|
|
|
|
if ( ok )
|
|
|
|
*ok = ( data() && *data() && ( end == 0 || *end == '\0' ) );
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Returns the string converted to a \c{float} value.
|
|
|
|
|
|
|
|
If \a ok is not 0: \a *ok is set to FALSE if the string is not a
|
|
|
|
number, or if it has trailing garbage; otherwise \a *ok is set to
|
|
|
|
TRUE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
float QCString::toFloat( bool *ok ) const
|
|
|
|
{
|
|
|
|
return (float)toDouble( ok );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Makes a deep copy of \a str. Returns a reference to the string.
|
|
|
|
*/
|
|
|
|
|
|
|
|
QCString &QCString::setStr( const char *str )
|
|
|
|
{
|
|
|
|
detach();
|
|
|
|
if ( str ) // valid string
|
|
|
|
store( str, qstrlen(str)+1 );
|
|
|
|
else // empty
|
|
|
|
resize( 0 );
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\overload
|
|
|
|
|
|
|
|
Sets the string to the string representation of the number \a n
|
|
|
|
and returns a reference to the string.
|
|
|
|
*/
|
|
|
|
|
|
|
|
QCString &QCString::setNum( long n )
|
|
|
|
{
|
|
|
|
detach();
|
|
|
|
char buf[20];
|
|
|
|
char *p = &buf[19];
|
|
|
|
bool neg;
|
|
|
|
if ( n < 0 ) {
|
|
|
|
neg = TRUE;
|
|
|
|
n = -n;
|
|
|
|
} else {
|
|
|
|
neg = FALSE;
|
|
|
|
}
|
|
|
|
*p = '\0';
|
|
|
|
do {
|
|
|
|
*--p = ((int)(n%10)) + '0';
|
|
|
|
n /= 10;
|
|
|
|
} while ( n );
|
|
|
|
if ( neg )
|
|
|
|
*--p = '-';
|
|
|
|
store( p, qstrlen(p)+1 );
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\overload
|
|
|
|
|
|
|
|
Sets the string to the string representation of the number \a n
|
|
|
|
and returns a reference to the string.
|
|
|
|
*/
|
|
|
|
|
|
|
|
QCString &QCString::setNum( ulong n )
|
|
|
|
{
|
|
|
|
detach();
|
|
|
|
char buf[20];
|
|
|
|
char *p = &buf[19];
|
|
|
|
*p = '\0';
|
|
|
|
do {
|
|
|
|
*--p = ((int)(n%10)) + '0';
|
|
|
|
n /= 10;
|
|
|
|
} while ( n );
|
|
|
|
store( p, qstrlen(p)+1 );
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\overload QCString &QCString::setNum( int n )
|
|
|
|
|
|
|
|
Sets the string to the string representation of the number \a n
|
|
|
|
and returns a reference to the string.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\overload QCString &QCString::setNum( uint n )
|
|
|
|
|
|
|
|
Sets the string to the string representation of the number \a n
|
|
|
|
and returns a reference to the string.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\overload QCString &QCString::setNum( short n )
|
|
|
|
|
|
|
|
Sets the string to the string representation of the number \a n
|
|
|
|
and returns a reference to the string.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\overload QCString &QCString::setNum( ushort n )
|
|
|
|
|
|
|
|
Sets the string to the string representation of the number \a n
|
|
|
|
and returns a reference to the string.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Sets the string to the string representation of the number \a n
|
|
|
|
and returns a reference to the string.
|
|
|
|
|
|
|
|
The format of the string representation is specified by the format
|
|
|
|
character \a f, and the precision (number of digits after the
|
|
|
|
decimal point) is specified with \a prec.
|
|
|
|
|
|
|
|
The valid formats for \a f are 'e', 'E', 'f', 'g' and 'G'. The
|
|
|
|
formats are the same as for sprintf(); they are explained in \l
|
|
|
|
QString::arg().
|
|
|
|
*/
|
|
|
|
|
|
|
|
QCString &QCString::setNum( double n, char f, int prec )
|
|
|
|
{
|
|
|
|
#if defined(QT_CHECK_RANGE)
|
|
|
|
if ( !(f=='f' || f=='F' || f=='e' || f=='E' || f=='g' || f=='G') )
|
|
|
|
qWarning( "QCString::setNum: Invalid format char '%c'", f );
|
|
|
|
#endif
|
|
|
|
char format[20];
|
|
|
|
char *fs = format; // generate format string
|
|
|
|
*fs++ = '%'; // "%.<prec>l<f>"
|
|
|
|
if ( prec > 99 )
|
|
|
|
prec = 99;
|
|
|
|
*fs++ = '.';
|
|
|
|
if ( prec >= 10 ) {
|
|
|
|
*fs++ = prec / 10 + '0';
|
|
|
|
*fs++ = prec % 10 + '0';
|
|
|
|
} else {
|
|
|
|
*fs++ = prec + '0';
|
|
|
|
}
|
|
|
|
*fs++ = 'l';
|
|
|
|
*fs++ = f;
|
|
|
|
*fs = '\0';
|
|
|
|
return sprintf( format, n );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*! \overload QCString &QCString::setNum( float n, char f, int prec ) */
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Sets the character at position \a index to \a c and expands the
|
|
|
|
string if necessary, padding with spaces.
|
|
|
|
|
|
|
|
Returns FALSE if \a index was out of range and the string could
|
|
|
|
not be expanded; otherwise returns TRUE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool QCString::setExpand( uint index, char c )
|
|
|
|
{
|
|
|
|
detach();
|
|
|
|
uint oldlen = length();
|
|
|
|
if ( index >= oldlen ) {
|
|
|
|
if ( !QByteArray::resize( index+2 ) ) // no memory
|
|
|
|
return FALSE;
|
|
|
|
if ( index > oldlen )
|
|
|
|
memset( data() + oldlen, ' ', index - oldlen );
|
|
|
|
*(data() + index+1) = '\0'; // terminate padded string
|
|
|
|
}
|
|
|
|
*(data() + index) = c;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn QCString::operator const char *() const
|
|
|
|
|
|
|
|
Returns the string data.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn QCString& QCString::append( const char *str )
|
|
|
|
|
|
|
|
Appends string \a str to the string and returns a reference to the
|
|
|
|
string. Equivalent to operator+=().
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Appends string \a str to the string and returns a reference to the string.
|
|
|
|
*/
|
|
|
|
|
|
|
|
QCString& QCString::operator+=( const char *str )
|
|
|
|
{
|
|
|
|
if ( !str )
|
|
|
|
return *this; // nothing to append
|
|
|
|
detach();
|
|
|
|
uint len1 = length();
|
|
|
|
uint len2 = qstrlen(str);
|
|
|
|
if ( !QByteArray::resize( len1 + len2 + 1, QByteArray::SpeedOptim ) )
|
|
|
|
return *this; // no memory
|
|
|
|
memcpy( data() + len1, str, len2 + 1 );
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\overload
|
|
|
|
|
|
|
|
Appends character \a c to the string and returns a reference to the string.
|
|
|
|
*/
|
|
|
|
|
|
|
|
QCString &QCString::operator+=( char c )
|
|
|
|
{
|
|
|
|
detach();
|
|
|
|
uint len = length();
|
|
|
|
if ( !QByteArray::resize( len + 2, QByteArray::SpeedOptim ) )
|
|
|
|
return *this; // no memory
|
|
|
|
*(data() + len) = c;
|
|
|
|
*(data() + len+1) = '\0';
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
QCString stream functions
|
|
|
|
*****************************************************************************/
|
|
|
|
#ifndef QT_NO_DATASTREAM
|
|
|
|
/*!
|
|
|
|
\relates QCString
|
|
|
|
|
|
|
|
Writes string \a str to the stream \a s.
|
|
|
|
|
|
|
|
\sa \link datastreamformat.html Format of the QDataStream operators \endlink
|
|
|
|
*/
|
|
|
|
QDataStream &operator<<( QDataStream &s, const QCString &str )
|
|
|
|
{
|
|
|
|
return s.writeBytes( str.data(), str.size() );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\relates QCString
|
|
|
|
|
|
|
|
Reads a string into \a str from the stream \a s.
|
|
|
|
|
|
|
|
\sa \link datastreamformat.html Format of the QDataStream operators \endlink
|
|
|
|
*/
|
|
|
|
|
|
|
|
QDataStream &operator>>( QDataStream &s, QCString &str )
|
|
|
|
{
|
|
|
|
str.detach();
|
|
|
|
Q_UINT32 len;
|
|
|
|
s >> len; // read size of string
|
|
|
|
if ( len == 0 || s.eof() ) { // end of file reached
|
|
|
|
str.resize( 0 );
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
if ( !str.QByteArray::resize( (uint)len )) {// resize string
|
|
|
|
#if defined(QT_CHECK_NULL)
|
|
|
|
qWarning( "QDataStream: Not enough memory to read QCString" );
|
|
|
|
#endif
|
|
|
|
len = 0;
|
|
|
|
}
|
|
|
|
if ( len > 0 ) // not null array
|
|
|
|
s.readRawBytes( str.data(), (uint)len );
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
#endif //QT_NO_DATASTREAM
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
Documentation for related functions
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn bool operator==( const QCString &s1, const QCString &s2 )
|
|
|
|
|
|
|
|
\relates QCString
|
|
|
|
|
|
|
|
Returns TRUE if \a s1 and \a s2 are equal; otherwise returns FALSE.
|
|
|
|
|
|
|
|
Equivalent to qstrcmp(\a s1, \a s2) == 0.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\overload bool operator==( const QCString &s1, const char *s2 )
|
|
|
|
|
|
|
|
\relates QCString
|
|
|
|
|
|
|
|
Returns TRUE if \a s1 and \a s2 are equal; otherwise returns FALSE.
|
|
|
|
|
|
|
|
Equivalent to qstrcmp(\a s1, \a s2) == 0.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\overload bool operator==( const char *s1, const QCString &s2 )
|
|
|
|
|
|
|
|
\relates QCString
|
|
|
|
|
|
|
|
Returns TRUE if \a s1 and \a s2 are equal; otherwise returns FALSE.
|
|
|
|
|
|
|
|
Equivalent to qstrcmp(\a s1, \a s2) == 0.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn bool operator!=( const QCString &s1, const QCString &s2 )
|
|
|
|
|
|
|
|
\relates QCString
|
|
|
|
|
|
|
|
Returns TRUE if \a s1 and \a s2 are different; otherwise returns FALSE.
|
|
|
|
|
|
|
|
Equivalent to qstrcmp(\a s1, \a s2) != 0.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\overload bool operator!=( const QCString &s1, const char *s2 )
|
|
|
|
|
|
|
|
\relates QCString
|
|
|
|
|
|
|
|
Returns TRUE if \a s1 and \a s2 are different; otherwise returns FALSE.
|
|
|
|
|
|
|
|
Equivalent to qstrcmp(\a s1, \a s2) != 0.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\overload bool operator!=( const char *s1, const QCString &s2 )
|
|
|
|
|
|
|
|
\relates QCString
|
|
|
|
|
|
|
|
Returns TRUE if \a s1 and \a s2 are different; otherwise returns FALSE.
|
|
|
|
|
|
|
|
Equivalent to qstrcmp(\a s1, \a s2) != 0.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn bool operator<( const QCString &s1, const char *s2 )
|
|
|
|
|
|
|
|
\relates QCString
|
|
|
|
|
|
|
|
Returns TRUE if \a s1 is less than \a s2; otherwise returns FALSE.
|
|
|
|
|
|
|
|
Equivalent to qstrcmp(\a s1, \a s2) \< 0.
|
|
|
|
|
|
|
|
\sa \link #asciinotion Note on character comparisons \endlink
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\overload bool operator<( const char *s1, const QCString &s2 )
|
|
|
|
|
|
|
|
\relates QCString
|
|
|
|
|
|
|
|
Returns TRUE if \a s1 is less than \a s2; otherwise returns FALSE.
|
|
|
|
|
|
|
|
Equivalent to qstrcmp(\a s1, \a s2) \< 0.
|
|
|
|
|
|
|
|
\sa \link #asciinotion Note on character comparisons \endlink
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn bool operator<=( const QCString &s1, const char *s2 )
|
|
|
|
|
|
|
|
\relates QCString
|
|
|
|
|
|
|
|
Returns TRUE if \a s1 is less than or equal to \a s2; otherwise
|
|
|
|
returns FALSE.
|
|
|
|
|
|
|
|
Equivalent to qstrcmp(\a s1, \a s2) \<= 0.
|
|
|
|
|
|
|
|
\sa \link #asciinotion Note on character comparisons \endlink
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\overload bool operator<=( const char *s1, const QCString &s2 )
|
|
|
|
|
|
|
|
\relates QCString
|
|
|
|
|
|
|
|
Returns TRUE if \a s1 is less than or equal to \a s2; otherwise
|
|
|
|
returns FALSE.
|
|
|
|
|
|
|
|
Equivalent to qstrcmp(\a s1, \a s2) \<= 0.
|
|
|
|
|
|
|
|
\sa \link #asciinotion Note on character comparisons \endlink
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn bool operator>( const QCString &s1, const char *s2 )
|
|
|
|
|
|
|
|
\relates QCString
|
|
|
|
|
|
|
|
Returns TRUE if \a s1 is greater than \a s2; otherwise returns FALSE.
|
|
|
|
|
|
|
|
Equivalent to qstrcmp(\a s1, \a s2) \> 0.
|
|
|
|
|
|
|
|
\sa \link #asciinotion Note on character comparisons \endlink
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\overload bool operator>( const char *s1, const QCString &s2 )
|
|
|
|
|
|
|
|
\relates QCString
|
|
|
|
|
|
|
|
Returns TRUE if \a s1 is greater than \a s2; otherwise returns FALSE.
|
|
|
|
|
|
|
|
Equivalent to qstrcmp(\a s1, \a s2) \> 0.
|
|
|
|
|
|
|
|
\sa \link #asciinotion Note on character comparisons \endlink
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn bool operator>=( const QCString &s1, const char *s2 )
|
|
|
|
|
|
|
|
\relates QCString
|
|
|
|
|
|
|
|
Returns TRUE if \a s1 is greater than or equal to \a s2; otherwise
|
|
|
|
returns FALSE.
|
|
|
|
|
|
|
|
Equivalent to qstrcmp(\a s1, \a s2) \>= 0.
|
|
|
|
|
|
|
|
\sa \link #asciinotion Note on character comparisons \endlink
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\overload bool operator>=( const char *s1, const QCString &s2 )
|
|
|
|
|
|
|
|
\relates QCString
|
|
|
|
|
|
|
|
Returns TRUE if \a s1 is greater than or equal to \a s2; otherwise
|
|
|
|
returns FALSE.
|
|
|
|
|
|
|
|
Equivalent to qstrcmp(\a s1, \a s2) \>= 0.
|
|
|
|
|
|
|
|
\sa \link #asciinotion Note on character comparisons \endlink
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn const QCString operator+( const QCString &s1, const QCString &s2 )
|
|
|
|
|
|
|
|
\relates QCString
|
|
|
|
|
|
|
|
Returns a string which consists of the concatenation of \a s1 and
|
|
|
|
\a s2.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\overload const QCString operator+( const QCString &s1, const char *s2 )
|
|
|
|
|
|
|
|
\relates QCString
|
|
|
|
|
|
|
|
Returns a string which consists of the concatenation of \a s1 and \a s2.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\overload const QCString operator+( const char *s1, const QCString &s2 )
|
|
|
|
|
|
|
|
\relates QCString
|
|
|
|
|
|
|
|
Returns a string which consists of the concatenation of \a s1 and \a s2.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\overload const QCString operator+( const QCString &s, char c )
|
|
|
|
|
|
|
|
\relates QCString
|
|
|
|
|
|
|
|
Returns a string which consists of the concatenation of \a s and \a c.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\overload const QCString operator+( char c, const QCString &s )
|
|
|
|
|
|
|
|
\relates QCString
|
|
|
|
|
|
|
|
Returns a string which consists of the concatenation of \a c and \a s.
|
|
|
|
*/
|