Commit 43edc14c authored by Dimitri van Heesch's avatar Dimitri van Heesch
Browse files

Introduce new optimized string implementation (attempt 2)

parent 151876a8
Loading
Loading
Loading
Loading
+237 −381
Original line number Original line Diff line number Diff line
@@ -24,178 +24,59 @@
#include <qregexp.h>
#include <qregexp.h>
#include <qdatastream.h>
#include <qdatastream.h>



QCString::QCString(int size)
{
  if (size>0)
  {
    m_data = (char *)malloc(size);
    if (m_data)
    {
      if (size>1) memset(m_data,' ',size-1);
      m_data[size-1]='\0';
    }
  }
  else
  {
    m_data=0;
  }
}

QCString::QCString( const QCString &s ) 
{ 
  duplicate(s);
}

QCString::QCString( const char *str )
{ 
  duplicate(str);
}

QCString::QCString( const char *str, uint maxlen )
{ 
  uint l;
  if (str && ( l = QMIN(qstrlen(str),maxlen) )) 
  { 
    m_data=(char *)malloc(l+1);
    strncpy(m_data,str,l+1);
    m_data[l]='\0';
  } 
  else
  {
    m_data=0;
  }
}

QCString::~QCString()
{
  if (m_data) free(m_data);
  m_data=0;
}

QCString &QCString::assign( const char *str )
{
  if (m_data) free(m_data);
  duplicate(str);
  return *this;
}

bool QCString::resize( uint newlen )
{
  if (newlen==0)
  {
    if (m_data) { free(m_data); m_data=0; }
    return TRUE;
  }
  if (m_data==0) // newlen>0
  {
    m_data = (char *)malloc(newlen);
  }
  else
  {
    m_data = (char *)realloc(m_data,newlen);
  }
  if (m_data==0) return FALSE;
  m_data[newlen-1]='\0';
  return TRUE;
}

bool QCString::fill( char c, int len )
{
  uint l=length();
  if (len<0) len=l;
  if ((uint)len!=l) 
  {
    if (m_data) free(m_data);
    if (len>0)
    {
      m_data=(char *)malloc(len+1);
      if (m_data==0) return FALSE;
      m_data[len]='\0';
    }
    else
    {
      m_data=0;
    }
  }
  if (len>0)
  {
    uint i;
    for (i=0;i<(uint)len;i++) m_data[i]=c;
  }
  return TRUE;
}

QCString &QCString::sprintf( const char *format, ... )
QCString &QCString::sprintf( const char *format, ... )
{
{
  va_list ap;
  va_list ap;
  va_start( ap, format );
  va_start( ap, format );
  uint l = length();
  const int minlen=256;
  const uint minlen=256;
  if (length()<minlen) resize(minlen);
  if (l<minlen)
  vsnprintf( data(), minlen, format, ap);
  {
  resize(strlen(data())+1);
    if (m_data) 
      m_data = (char *)realloc(m_data,minlen);
    else
      m_data = (char *)malloc(minlen);
  }
  vsprintf( m_data, format, ap );
  resize( qstrlen(m_data) + 1 );              // truncate
  va_end( ap );
  va_end( ap );
  return *this;
  return *this;
}
}



int QCString::find( char c, int index, bool cs ) const
int QCString::find( char c, int index, bool cs ) const
{
{
  uint len = length();
  if (index<0 || index>=(int)length()) return -1; // index outside string
  if ( m_data==0 || (uint)index>len )               // index outside string
  register const char *pos;
    return -1;
  if (cs)
  register const char *d;
  if ( cs ) // case sensitive
  {
  {
    d = strchr( m_data+index, c );
    pos = strchr(data()+index,c);
  }
  }
  else
  else
  {
  {
    d = m_data+index;
    pos = data()+index;
    c = tolower( (uchar) c );
    c = tolower((unsigned char)c);
    while ( *d && tolower((uchar) *d) != c )
    while (*pos && tolower((unsigned char)*pos)!=c) pos++;
      d++;
    if (!*pos && c) pos=0; // not found
    if ( !*d && c )                         // not found
      d = 0;
  }
  }
  return d ? (int)(d - m_data) : -1;
  return pos ? (int)(pos - data()) : -1;
}
}


int QCString::find( const char *str, int index, bool cs ) const
int QCString::find( const char *str, int index, bool cs ) const
{
{
  uint l = length();
  int l = length();
  if ( m_data==0 || (uint)index > l )         // index outside string
  if (index<0 || index>=l) return -1; // index outside string
    return -1;
  if (!str)  return -1;               // no string to search for
  if ( !str )                                 // no search string
  if (!*str) return index;           // empty string matching at index
    return -1;
  register char *pos;
  if ( !*str )                                // zero-length search string
    return index;
  register const char *d;
  if (cs) // case sensitive
  if (cs) // case sensitive
  {
  {
    d = strstr( m_data+index, str );
    pos = strstr(data()+index,str);
  }
  }
  else // case insensitive
  else // case insensitive
  {
  {
    d = m_data+index;
    pos = data();
    int len = qstrlen( str );
    int len = strlen(str);
    while ( *d ) 
    while (*pos)
    {
    {
      if ( qstrnicmp(d, str, len) == 0 )
      if (strncasecmp(pos,str,len)==0) break;
        break;
      pos++;
      d++;
    }
    }
    if ( !*d )                              // not found
    if (!*pos) pos = 0; // not found
      d = 0;
  }
  }
  return d ? (int)(d - m_data) : -1;
  return pos ? (int)(pos - data()) : -1;
}
}


int QCString::find( const QCString &str, int index, bool cs ) const
int QCString::find( const QCString &str, int index, bool cs ) const
@@ -205,100 +86,84 @@ int QCString::find( const QCString &str,int index,bool cs) const


int QCString::find( const QRegExp &rx, int index ) const
int QCString::find( const QRegExp &rx, int index ) const
{
{
  QString d = QString::fromLatin1( m_data );
  QString d = QString::fromLatin1( data() );
  return d.find( rx, index );
  return d.find( rx, index );
}
}


int QCString::findRev( char c, int index, bool cs) const
int QCString::findRev( char c, int index, bool cs) const
{
{
  const char *b = m_data;
  const char *b = data();
  const char *d;
  const char *pos;
  uint len = length();
  int len = length();
  if ( b == 0 ) return -1;  // empty string
  if (len==0) return -1; // empty string
  if ( index < 0 )          // neg index ==> start from end
  if (index<0) // start from end
  {
  {
    if ( len == 0 ) return -1;
    if (cs)
    if (cs)
    {
    {
      d = strrchr( b, c );
      pos = strrchr(b,c);
      return d ? (int)(d - b) : -1;
      return pos ? (int)(pos - b) : -1;
    }
    }
    index=len;
    index=len;
  }
  }
  else if ( (uint)index > len )  // bad index
  else if (index>len) // bad index
  {
  {
    return -1;
    return -1;
  }
  }
  d = b+index;
  pos = b+index;
  if ( cs )   // case sensitive
  if (cs)
  {
  {
    while ( d >= b && *d != c )
    while ( pos>=b && *pos!=c) pos--;
      d--;
  }
  }
  else  // case insensitive
  else
  {
  {
    c = tolower( (uchar) c );
    c = tolower((unsigned char)c);
    while ( d >= b && tolower((uchar) *d) != c )
    while ( pos>=b && tolower((unsigned char)*pos)!=c) pos--;
      d--;
  }
  }
  return d >= b ? (int)(d - b) : -1;
  return pos>=b ? (int)(pos - b) : -1;
}
}


int QCString::findRev( const char *str, int index, bool cs) const
int QCString::findRev( const char *str, int index, bool cs) const
{
{
  int slen = qstrlen(str);
  int slen = strlen(str);
  uint len = length();
  int len = length();
  if ( index < 0 )                           // neg index ==> start from end
  if (index<0) index = len-slen; // start from end
    index = len-slen;
  else if (index>len) return -1; // bad index
  else if ( (uint)index > len )              // bad index
  else if (index+slen>len) index=len-slen; // str would be too long
    return -1;
  if (index<0) return -1; // no match possible
  else if ( (uint)(index + slen) > len )     // str would be too long
  register char *pos = data()+index;
    index = len - slen;
  if ( index < 0 )
    return -1;

  register char *d = m_data + index;
  if (cs) // case sensitive
  if (cs) // case sensitive
  {
  {
    for ( int i=index; i>=0; i-- )
    for (int i=index; i>=0; i--) if (strncmp(pos--,str,slen)==0) return i;
      if ( qstrncmp(d--,str,slen)==0 )
        return i;
  }
  }
  else // case insensitive
  else // case insensitive
  {
  {
    for ( int i=index; i>=0; i-- )
    for (int i=index; i>=0; i--) if (strncasecmp(pos,str,slen)==0) return i;
      if ( qstrnicmp(d--,str,slen)==0 )
        return i;
  }
  }
  return -1;
  return -1;

}
}


int QCString::findRev( const QRegExp &rx, int index ) const
int QCString::findRev( const QRegExp &rx, int index ) const
{
{
  QString d = QString::fromLatin1( m_data );
  QString d = QString::fromLatin1( data() );
  return d.findRev( rx, index );
  return d.findRev( rx, index );
}
}


int QCString::contains( char c, bool cs ) const
int QCString::contains( char c, bool cs ) const
{
{
  if (length()==0) return 0;
  int count=0;
  int count=0;
  char *d = m_data;
  const char *pos = data();
  if ( !d )
  if (cs)
    return 0;                               
  if ( cs )                                // case sensitive
  {
  {
    while ( *d )
    while (*pos) if (*pos++ == c) count++;
      if ( *d++ == c )
        count++;                        
  }
  }
  else                                     // case insensitive
  else
  {
  {
    c = tolower( (uchar) c );
    c = tolower((unsigned char)c);
    while ( *d ) {
    while (*pos)
      if ( tolower((uchar) *d) == c )
    {
        count++;
      if (tolower((unsigned char)*pos)==c) count++;
      d++;
      pos++;
    }
    }
  }
  }
  return count;
  return count;
@@ -306,34 +171,45 @@ int QCString::contains( char c, bool cs ) const


int QCString::contains( const char *str, bool cs ) const
int QCString::contains( const char *str, bool cs ) const
{
{
  if (str==0 || length()==0) return 0;
  int count=0;
  int count=0;
  char *d = data();
  const char *pos = data();
  if ( !d )
  int len = strlen(str);
    return 0;
  while (*pos)
  int len = qstrlen( str );
  while ( *d )   // counts overlapping strings
  {
  {
    if (cs)
    if (cs)
    {
    {
      if ( qstrncmp( d, str, len ) == 0 )
      if (strncmp(pos,str,len)==0) count++;
        count++;
    }
    }
    else
    else
    {
    {
      if ( qstrnicmp(d, str, len) == 0 )
      if (strncasecmp(pos,str,len)==0) count++;
        count++;
    }
    }
    d++;
    pos++;
  }
  }
  return count;
  return count;
}
}


int QCString::contains( const QRegExp &rx ) const
int QCString::contains( const QRegExp &rx ) const
{
{
  QString d = QString::fromLatin1( m_data );
  QString d = QString::fromLatin1( data() );
  return d.contains( rx );
  return d.contains( rx );
}
}


bool QCString::stripPrefix(const char *prefix)
{
  if (prefix==0 || length()==0) return FALSE;
  int len = strlen(prefix);
  if (strncmp(prefix,data(),len)==0)
  {
    int newlen = length()-len+1;
    qmemmove(data(),data()+len,newlen);
    resize(newlen);
    return TRUE;
  }
  return FALSE;
}

QCString QCString::left( uint len )  const
QCString QCString::left( uint len )  const
{
{
  if (isEmpty())
  if (isEmpty())
@@ -342,13 +218,12 @@ QCString QCString::left( uint len ) const
  }
  }
  else if (len>=length())
  else if (len>=length())
  {
  {
    return *this;
    return QCString(data());
  }
  }
  else
  else
  {
  {
    QCString s( len+1 );
    QCString s( len+1 );
    strncpy( s.data(), m_data, len );
    memcpy( s.data(), data(), len);
    *(s.data()+len) = '\0';
    return s;
    return s;
  }
  }
}
}
@@ -361,18 +236,18 @@ QCString QCString::right( uint len ) const
  }
  }
  else
  else
  {
  {
    uint l = length();
    int l = length();
    if ( len > l ) len = l;
    if ((int)len>l) len=l;
    char *p = m_data + (l - len); 
    const char *pos = data() + (l-len);
    return QCString( p ); 
    return QCString(pos);
  }
  }
}
}


QCString QCString::mid( uint index, uint len) const
QCString QCString::mid( uint index, uint len) const
{
{
  uint slen = length();
  int slen = length();
  if (len==0xffffffff) len = slen-index;
  if (len==0xffffffff) len = slen-index;
  if ( isEmpty() || index >= slen ) 
  if (isEmpty() || (int)index>=slen)
  {
  {
    return QCString();
    return QCString();
  }
  }
@@ -380,22 +255,22 @@ QCString QCString::mid( uint index, uint len) const
  {
  {
    register char *p = data()+index;
    register char *p = data()+index;
    QCString s(len+1);
    QCString s(len+1);
    strncpy( s.data(), p, len );
    memcpy(s.data(),p,len);
    *(s.data()+len) = '\0';
    return s;
    return s;
  }
  }
}
}


QCString QCString::lower() const
QCString QCString::lower() const
{
{
  QCString s( m_data );
  if (length()==0) return QCString();
  register char *p = s.data();
  QCString s(data());
  if ( p ) 
  register char *pos = s.data();
  if (pos)
  {
  {
    while ( *p ) 
    while (*pos)
    {
    {
      *p = tolower((uchar) *p);
      *pos = tolower((unsigned char)*pos);
      p++;
      pos++;
    }
    }
  }
  }
  return s;
  return s;
@@ -403,12 +278,15 @@ QCString QCString::lower() const


QCString QCString::upper() const
QCString QCString::upper() const
{
{
  QCString s( m_data );
  if (length()==0) return QCString();
  register char *p = s.data();
  QCString s(data());
  if ( p ) {
  register char *pos = s.data();
    while ( *p ) {
  if (pos)
      *p = toupper((uchar)*p);
  {
      p++;
    while (*pos)
    {
      *pos = toupper((unsigned char)*pos);
      pos++;
    }
    }
  }
  }
  return s;
  return s;
@@ -419,7 +297,7 @@ QCString QCString::stripWhiteSpace() const
  if ( isEmpty() )                            // nothing to do
  if ( isEmpty() )                            // nothing to do
    return *this;
    return *this;


  register char *s = m_data;
  register char *s = data();
  int reslen = length();
  int reslen = length();
  if ( !isspace((uchar)s[0]) && !isspace((uchar)s[reslen-1]) )
  if ( !isspace((uchar)s[0]) && !isspace((uchar)s[reslen-1]) )
    return *this;                             // returns a copy
    return *this;                             // returns a copy
@@ -437,7 +315,7 @@ QCString QCString::stripWhiteSpace() const
  while ( end && isspace((uchar) s[end]) )            // skip white space from end
  while ( end && isspace((uchar) s[end]) )            // skip white space from end
    end--;
    end--;
  end -= start - 1;
  end -= start - 1;
  memmove( result.data(), &s[start], end );
  qmemmove( result.data(), &s[start], end );
  result.resize( end + 1 );
  result.resize( end + 1 );
  return result;
  return result;
}
}
@@ -469,65 +347,47 @@ QCString QCString::simplifyWhiteSpace() const
  return result;
  return result;
}
}


QCString &QCString::assign( const char *str )
{
  return operator=(str);
}

QCString &QCString::insert( uint index, const char *s )
QCString &QCString::insert( uint index, const char *s )
{
{
  int len = s ? qstrlen(s) : 0;
  int len = s ? qstrlen(s) : 0;
  if ( len == 0 )
  if ( len == 0 ) return *this;
    return *this;
  int olen = length();
  uint olen = length();
  int nlen = olen + len;
  int nlen = olen + len;
  if ( index >= olen )  // insert after end of string
  if ((int)index>=olen)
  {
  {
    m_data = (char *)realloc(m_data,nlen+index-olen+1);
    resize(nlen+index-olen+1);
    if ( m_data ) 
    memset(data()+olen, ' ', index-olen);
    {
    memcpy(data()+index,s, len+1);
      memset( m_data+olen, ' ', index-olen );
      memcpy( m_data+index, s, len+1 );
    }
  }
  }
  else if ( (m_data = (char *)realloc(m_data,nlen+1)) )  // normal insert
  else
  {
  {
    memmove( m_data+index+len, m_data+index, olen-index+1 );
    resize(nlen+1);
    memcpy( m_data+index, s, len );
    qmemmove(data()+index+len,data()+index,olen-index+1);
    memcpy(data()+index,s,len);
  }
  }
  return *this;
  return *this;
}
}


QCString &QCString::insert( uint index, char c )        // insert char
QCString &QCString::insert( uint index, char c)
{
{
  char buf[2];
  char buf[2];
  buf[0] = c;
  buf[0] = c;
  buf[1] = '\0';
  buf[1] = '\0';
  return insert( index, buf );
  return insert( index, buf );
}
}

QCString &QCString::append( const char *s )
QCString& QCString::operator+=( const char *str )
{
  if ( !str ) return *this;  // nothing to append
  uint len1 = length();
  uint len2 = qstrlen(str);
  char *newData = (char *)realloc( m_data, len1 + len2 + 1 );
  if (newData)
{
{
    m_data = newData;
  return operator+=(s);
    memcpy( m_data + len1, str, len2 + 1 );
}
}
  return *this;      
QCString &QCString::prepend( const char *s )
}

QCString &QCString::operator+=( char c )
{
{
  uint len = length();
  return insert(0,s);
  char *newData = (char *)realloc( m_data, length()+2 );
  if (newData)
  {
    m_data = newData;
    m_data[len] = c;
    m_data[len+1] = '\0';
}
}
  return *this;
}

QCString &QCString::remove( uint index, uint len )
QCString &QCString::remove( uint index, uint len )
{
{
  uint olen = length();
  uint olen = length();
@@ -540,7 +400,7 @@ QCString &QCString::remove( uint index, uint len )
  }
  }
  else if ( len != 0 )
  else if ( len != 0 )
  {
  {
    memmove( m_data+index, m_data+index+len, olen-index-len+1 );
    qmemmove( data()+index, data()+index+len, olen-index-len+1 );
    resize( olen-len+1 );
    resize( olen-len+1 );
  }
  }
  return *this;
  return *this;
@@ -555,47 +415,67 @@ QCString &QCString::replace( uint index, uint len, const char *s )


QCString &QCString::replace( const QRegExp &rx, const char *str )
QCString &QCString::replace( const QRegExp &rx, const char *str )
{
{
  QString d = QString::fromLatin1( m_data );
  QString d = QString::fromLatin1( data() );
  QString r = QString::fromLatin1( str );
  QString r = QString::fromLatin1( str );
  d.replace( rx, r );
  d.replace( rx, r );
  operator=( d.ascii() );
  operator=( d.ascii() );
  return *this;
  return *this;
}
}


short QCString::toShort(bool *ok) const
{
  QString s(data());
  return s.toShort(ok);
}

ushort QCString::toUShort(bool *ok) const
{
  QString s(data());
  return s.toUShort(ok);
}

int QCString::toInt(bool *ok) const
{
  QString s(data());
  return s.toInt(ok);
}

uint QCString::toUInt(bool *ok) const
{
  QString s(data());
  return s.toUInt(ok);
}

long QCString::toLong(bool *ok) const
long QCString::toLong(bool *ok) const
{
{
  QString s(m_data);
  QString s(data());
  return s.toLong(ok);
  return s.toLong(ok);
}
}


ulong QCString::toULong(bool *ok) const
ulong QCString::toULong(bool *ok) const
{
{
  QString s(m_data);
  QString s(data());
  return s.toULong(ok);
  return s.toULong(ok);
}
}


short QCString::toShort( bool *ok )	const
QCString &QCString::setNum(short n)
{
{
  QString s(m_data);
  return setNum((long)n);
  return s.toShort(ok);
}
}


ushort QCString::toUShort( bool *ok ) const
QCString &QCString::setNum(ushort n)
{
{
  QString s(m_data);
  return setNum((ulong)n);
  return s.toUShort(ok);
}
}


int QCString::toInt( bool *ok ) const
QCString &QCString::setNum(int n)
{
{
  QString s(m_data);
  return setNum((long)n);
  return s.toInt(ok);
}
}


uint QCString::toUInt( bool *ok ) const
QCString &QCString::setNum(uint n)
{
{
  QString s(m_data);
  return setNum((ulong)n);
  return s.toUInt(ok);
}
}


QCString &QCString::setNum(long n)
QCString &QCString::setNum(long n)
@@ -637,31 +517,7 @@ QCString &QCString::setNum( ulong n )
  return *this;
  return *this;
}
}


void QCString::msg_index( uint index )
//-------------------------------------------------
{
#if defined(CHECK_RANGE)
    qWarning( "QCString::at: Absolute index %d out of range", index );
#else
    Q_UNUSED( index )
#endif
}

bool QCString::stripPrefix(const char *prefix)
{
  if (prefix==0) return FALSE;
  uint plen   = qstrlen(prefix);
  if (m_data && qstrncmp(prefix,m_data,plen)==0) // prefix matches
  {
    uint len    = qstrlen(m_data);
    uint newlen = len-plen+1;
    qmemmove(m_data,m_data+plen,newlen);
    resize(newlen);
    return TRUE;
  }
  return FALSE;
}

//---------------------------------------------------------------------------


void *qmemmove( void *dst, const void *src, uint len )
void *qmemmove( void *dst, const void *src, uint len )
{
{
+555 −247

File changed.

Preview size limit exceeded, changes collapsed.

+1 −2
Original line number Original line Diff line number Diff line
@@ -7,7 +7,6 @@ HEADERS = qarray.h \
		  qcollection.h \
		  qcollection.h \
		  qconfig.h \
		  qconfig.h \
		  qcstring.h \
		  qcstring.h \
		  scstring.h \
		  qdatastream.h \
		  qdatastream.h \
		  qdatetime.h \
		  qdatetime.h \
		  qdict.h \
		  qdict.h \
@@ -54,7 +53,7 @@ HEADERS = qarray.h \


SOURCES		= qbuffer.cpp \
SOURCES		= qbuffer.cpp \
		  qcollection.cpp \
		  qcollection.cpp \
		  scstring.cpp \
		  qcstring.cpp \
		  qdatastream.cpp \
		  qdatastream.cpp \
		  qdatetime.cpp \
		  qdatetime.cpp \
		  qdir.cpp \
		  qdir.cpp \

qtools/scstring.cpp

deleted100644 → 0
+0 −798

File deleted.

Preview size limit exceeded, changes collapsed.

qtools/scstring.h

deleted100644 → 0
+0 −155
Original line number Original line Diff line number Diff line
/******************************************************************************
 *
 * Copyright (C) 1997-2004 by Dimitri van Heesch.
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation under the terms of the GNU General Public License is hereby 
 * granted. No representations are made about the suitability of this software 
 * for any purpose. It is provided "as is" without express or implied warranty.
 * See the GNU General Public License for more details.
 *
 * Documents produced by Doxygen are derivative works derived from the
 * input used in their production; they are not affected by this license.
 *
 */

#ifndef SCSTRING_H
#define SCSTRING_H

#include <stdlib.h>

class QRegExp;

/** This is an alternative implementation of QCString. It provides basically
 *  the same functions but uses less memory for administration. This class
 *  is just a wrapper around a plain C string requiring only 4 bytes "overhead".
 *  QCString features sharing of data and stores the string length, but 
 *  requires 4 + 12 bytes for this (even for the empty string). As doxygen 
 *  uses a LOT of string during a run it saves a lot of memory to use a 
 *  more memory efficient implementation at the cost of relatively low
 *  runtime overhead.
 */
class SCString 
{
public:
    SCString() : m_data(0) {}		// make null string
    SCString( const SCString &s );
    SCString( int size );
    SCString( const char *str );
    SCString( const char *str, uint maxlen );
    ~SCString();

    SCString    &operator=( const SCString &s );// deep copy
    SCString    &operator=( const char *str );	// deep copy

    bool        isNull()        const;
    bool	isEmpty()	const;
    uint	length()	const;
    uint        size()          const { return m_data ? length()+1 : 0; }
    char *      data()          const { return m_data; }
    bool	resize( uint newlen );
    bool	truncate( uint pos );
    bool	fill( char c, int len = -1 );

    SCString	copy()	const;

    SCString    &sprintf( const char *format, ... );

    int		find( char c, int index=0, bool cs=TRUE ) const;
    int		find( const char *str, int index=0, bool cs=TRUE ) const;
    int		find( const QRegExp &, int index=0 ) const;
    int         find( const QCString &str, int index, bool cs ) const;
    int		findRev( char c, int index=-1, bool cs=TRUE) const;
    int		findRev( const char *str, int index=-1, bool cs=TRUE) const;
    int		findRev( const QRegExp &, int index=-1 ) const;
    int		contains( char c, bool cs=TRUE ) const;
    int		contains( const char *str, bool cs=TRUE ) const;
    int		contains( const QRegExp & ) const;
    bool        stripPrefix(const char *prefix);

    SCString	left( uint len )  const;
    SCString	right( uint len ) const;
    SCString	mid( uint index, uint len=0xffffffff) const;

    SCString	lower() const;
    SCString	upper() const;

    SCString	stripWhiteSpace()	const;
    SCString	simplifyWhiteSpace()	const;

    SCString    &assign( const char *str );
    SCString    &insert( uint index, const char * );
    SCString    &insert( uint index, char );
    SCString    &append( const char *s );
    SCString    &prepend( const char *s );
    SCString    &remove( uint index, uint len );
    SCString    &replace( uint index, uint len, const char * );
    SCString    &replace( const QRegExp &, const char * );

    short	toShort( bool *ok=0 )	const;
    ushort	toUShort( bool *ok=0 )	const;
    int		toInt( bool *ok=0 )	const;
    uint	toUInt( bool *ok=0 )	const;
    long	toLong( bool *ok=0 )	const;
    ulong	toULong( bool *ok=0 )	const;

    SCString    &setNum( short );
    SCString    &setNum( ushort );
    SCString    &setNum( int );
    SCString    &setNum( uint );
    SCString    &setNum( long );
    SCString    &setNum( ulong );
    QCString    &setNum( float, char f='g', int prec=6 );
    QCString    &setNum( double, char f='g', int prec=6 );

		operator const char *() const;
    SCString    &operator+=( const char *str );
    SCString    &operator+=( char c );
    char &at( uint index ) const;
    char &operator[]( int i ) const { return at(i); }
    
  private:
    static void msg_index( uint );
    void duplicate( const SCString &s );
    void duplicate( const char *str);
    SCString &duplicate( const char *str, int);

    char *      m_data;
};

inline char &SCString::at( uint index ) const
{
  return m_data[index];
}

inline void SCString::duplicate( const SCString &s )
{
  if (!s.isEmpty()) 
  {
    uint l = strlen(s.data());
    m_data = (char *)malloc(l+1);
    if (m_data) memcpy(m_data,s.data(),l+1);
  }
  else 
    m_data=0; 
}
inline void SCString::duplicate( const char *str)
{
  if (str && str[0]!='\0') 
  {
    uint l = strlen(str);
    m_data = (char *)malloc(l+1);
    if (m_data) memcpy(m_data,str,l+1);
  }
  else 
    m_data=0;
}
inline SCString &SCString::duplicate( const char *str, int)
{
  if (m_data) free(m_data);
  duplicate(str);
  return *this;
}

#endif
Loading