Orb/Doxygen/qtools/scstring.cpp
changeset 0 42188c7ea2d9
equal deleted inserted replaced
-1:000000000000 0:42188c7ea2d9
       
     1 /******************************************************************************
       
     2  *
       
     3  * Copyright (C) 1997-2004 by Dimitri van Heesch.
       
     4  *
       
     5  * Permission to use, copy, modify, and distribute this software and its
       
     6  * documentation under the terms of the GNU General Public License is hereby 
       
     7  * granted. No representations are made about the suitability of this software 
       
     8  * for any purpose. It is provided "as is" without express or implied warranty.
       
     9  * See the GNU General Public License for more details.
       
    10  *
       
    11  * Documents produced by Doxygen are derivative works derived from the
       
    12  * input used in their production; they are not affected by this license.
       
    13  *
       
    14  */
       
    15 
       
    16 // with this switch you can choose between the original qcstring implementation,
       
    17 // which implicitly shares data so copying is faster, but requires at least 12 bytes, and
       
    18 // the new implementation in this file, which has a smaller footprint (only 4 bytes for
       
    19 // an empty string), but always copies strings.
       
    20 #define SMALLSTRING
       
    21 
       
    22 #include "qcstring.h"
       
    23 #ifndef SMALLSTRING
       
    24 #include "qcstring.cpp"
       
    25 #else
       
    26 #define SCString QCString
       
    27 
       
    28 #include <qstring.h>
       
    29 #include <stdlib.h>
       
    30 #include <stdio.h>
       
    31 #include <stdarg.h>
       
    32 #include <ctype.h>
       
    33 #include <qregexp.h>
       
    34 #include <qdatastream.h>
       
    35 
       
    36 
       
    37 SCString::SCString(int size)
       
    38 {
       
    39   if (size>0)
       
    40   {
       
    41     m_data = (char *)malloc(size);
       
    42     if (m_data)
       
    43     {
       
    44       if (size>1) memset(m_data,' ',size-1);
       
    45       m_data[size-1]='\0';
       
    46     }
       
    47   }
       
    48   else
       
    49   {
       
    50     m_data=0;
       
    51   }
       
    52 }
       
    53 
       
    54 SCString::SCString( const SCString &s ) 
       
    55 { 
       
    56   duplicate(s);
       
    57 }
       
    58 
       
    59 SCString::SCString( const char *str )
       
    60 { 
       
    61   duplicate(str);
       
    62 }
       
    63 
       
    64 SCString::SCString( const char *str, uint maxlen )
       
    65 { 
       
    66   uint l;
       
    67   if (str && ( l = QMIN(qstrlen(str),maxlen) )) 
       
    68   { 
       
    69     m_data=(char *)malloc(l+1);
       
    70     strncpy(m_data,str,l+1);
       
    71     m_data[l]='\0';
       
    72   } 
       
    73   else
       
    74   {
       
    75     m_data=0;
       
    76   }
       
    77 }
       
    78 
       
    79 SCString::~SCString()
       
    80 {
       
    81   if (m_data) free(m_data);
       
    82   m_data=0;
       
    83 }
       
    84 
       
    85 SCString &SCString::assign( const char *str )
       
    86 {
       
    87   if (m_data==str) return *this;
       
    88   if (m_data) free(m_data);
       
    89   duplicate(str);
       
    90   return *this;
       
    91 }
       
    92 
       
    93 bool SCString::resize( uint newlen )
       
    94 {
       
    95   if (newlen==0)
       
    96   {
       
    97     if (m_data) { free(m_data); m_data=0; }
       
    98     return TRUE;
       
    99   }
       
   100   if (m_data==0) // newlen>0
       
   101   {
       
   102     m_data = (char *)malloc(newlen);
       
   103   }
       
   104   else
       
   105   {
       
   106     m_data = (char *)realloc(m_data,newlen);
       
   107   }
       
   108   if (m_data==0) return FALSE;
       
   109   m_data[newlen-1]='\0';
       
   110   return TRUE;
       
   111 }
       
   112 
       
   113 bool SCString::fill( char c, int len )
       
   114 {
       
   115   uint l=length();
       
   116   if (len<0) len=l;
       
   117   if ((uint)len!=l) 
       
   118   {
       
   119     if (m_data) free(m_data);
       
   120     if (len>0)
       
   121     {
       
   122       m_data=(char *)malloc(len+1);
       
   123       if (m_data==0) return FALSE;
       
   124       m_data[len]='\0';
       
   125     }
       
   126     else
       
   127     {
       
   128       m_data=0;
       
   129     }
       
   130   }
       
   131   if (len>0)
       
   132   {
       
   133     uint i;
       
   134     for (i=0;i<(uint)len;i++) m_data[i]=c;
       
   135   }
       
   136   return TRUE;
       
   137 }
       
   138 
       
   139 SCString &SCString::sprintf( const char *format, ... )
       
   140 {
       
   141   va_list ap;
       
   142   va_start( ap, format );
       
   143   uint l = length();
       
   144   const uint minlen=256;
       
   145   if (l<minlen)
       
   146   {
       
   147     if (m_data) 
       
   148       m_data = (char *)realloc(m_data,minlen);
       
   149     else
       
   150       m_data = (char *)malloc(minlen);
       
   151   }
       
   152   vsprintf( m_data, format, ap );
       
   153   resize( qstrlen(m_data) + 1 );              // truncate
       
   154   va_end( ap );
       
   155   return *this;
       
   156 }
       
   157 
       
   158 
       
   159 int SCString::find( char c, int index, bool cs ) const
       
   160 {
       
   161   uint len = length();
       
   162   if ( m_data==0 || (uint)index>len )               // index outside string
       
   163     return -1;
       
   164   register const char *d;
       
   165   if ( cs ) // case sensitive
       
   166   {  
       
   167     d = strchr( m_data+index, c );
       
   168   } 
       
   169   else 
       
   170   {
       
   171     d = m_data+index;
       
   172     c = tolower( (uchar) c );
       
   173     while ( *d && tolower((uchar) *d) != c )
       
   174       d++;
       
   175     if ( !*d && c )                         // not found
       
   176       d = 0;
       
   177   }
       
   178   return d ? (int)(d - m_data) : -1;
       
   179 }
       
   180 
       
   181 int SCString::find( const char *str, int index, bool cs ) const
       
   182 {
       
   183   uint l = length();
       
   184   if ( m_data==0 || (uint)index > l )         // index outside string
       
   185     return -1;
       
   186   if ( !str )                                 // no search string
       
   187     return -1;
       
   188   if ( !*str )                                // zero-length search string
       
   189     return index;
       
   190   register const char *d;
       
   191   if ( cs )                                   // case sensitive
       
   192   {              
       
   193     d = strstr( m_data+index, str );
       
   194   } 
       
   195   else                                        // case insensitive
       
   196   {
       
   197     d = m_data+index;
       
   198     int len = qstrlen( str );
       
   199     while ( *d ) 
       
   200     {
       
   201       if ( qstrnicmp(d, str, len) == 0 )
       
   202         break;
       
   203       d++;
       
   204     }
       
   205     if ( !*d )                              // not found
       
   206       d = 0;
       
   207   }
       
   208   return d ? (int)(d - m_data) : -1;
       
   209 }
       
   210 
       
   211 int SCString::find( const QRegExp &rx, int index ) const
       
   212 {
       
   213   QString d = QString::fromLatin1( m_data );
       
   214   return d.find( rx, index );
       
   215 }
       
   216 
       
   217 int SCString::findRev( char c, int index, bool cs) const
       
   218 {
       
   219   const char *b = m_data;
       
   220   const char *d;
       
   221   uint len = length();
       
   222   if ( b == 0 ) return -1;  // empty string
       
   223   if ( index < 0 )          // neg index ==> start from end
       
   224   {
       
   225     if ( len == 0 ) return -1;
       
   226     if ( cs ) 
       
   227     {
       
   228       d = strrchr( b, c );
       
   229       return d ? (int)(d - b) : -1;
       
   230     }
       
   231     index = len;
       
   232   } 
       
   233   else if ( (uint)index > len )  // bad index
       
   234   {      
       
   235     return -1;
       
   236   }
       
   237   d = b+index;
       
   238   if ( cs )   // case sensitive
       
   239   {
       
   240     while ( d >= b && *d != c )
       
   241       d--;
       
   242   } 
       
   243   else  // case insensitive
       
   244   {
       
   245     c = tolower( (uchar) c );
       
   246     while ( d >= b && tolower((uchar) *d) != c )
       
   247       d--;
       
   248   }
       
   249   return d >= b ? (int)(d - b) : -1;
       
   250 }
       
   251 
       
   252 int SCString::findRev( const char *str, int index, bool cs) const
       
   253 {
       
   254   int slen = qstrlen(str);
       
   255   uint len = length();
       
   256   if ( index < 0 )                           // neg index ==> start from end
       
   257     index = len-slen;
       
   258   else if ( (uint)index > len )              // bad index
       
   259     return -1;
       
   260   else if ( (uint)(index + slen) > len )     // str would be too long
       
   261     index = len - slen;
       
   262   if ( index < 0 )
       
   263     return -1;
       
   264 
       
   265   register char *d = m_data + index;
       
   266   if ( cs )                     // case sensitive 
       
   267   {      
       
   268     for ( int i=index; i>=0; i-- )
       
   269       if ( qstrncmp(d--,str,slen)==0 )
       
   270         return i;
       
   271   } 
       
   272   else                          // case insensitive
       
   273   {           
       
   274     for ( int i=index; i>=0; i-- )
       
   275       if ( qstrnicmp(d--,str,slen)==0 )
       
   276         return i;
       
   277   }
       
   278   return -1;
       
   279 
       
   280 }
       
   281 
       
   282 int SCString::findRev( const QRegExp &rx, int index ) const
       
   283 {
       
   284   QString d = QString::fromLatin1( m_data );
       
   285   return d.findRev( rx, index );
       
   286 }
       
   287 
       
   288 int SCString::contains( char c, bool cs ) const
       
   289 {
       
   290   int count = 0;
       
   291   char *d = m_data;
       
   292   if ( !d )
       
   293     return 0;                               
       
   294   if ( cs )                                // case sensitive
       
   295   {
       
   296     while ( *d )
       
   297       if ( *d++ == c )
       
   298         count++;                        
       
   299   } 
       
   300   else                                     // case insensitive
       
   301   {
       
   302     c = tolower( (uchar) c );
       
   303     while ( *d ) {
       
   304       if ( tolower((uchar) *d) == c )
       
   305         count++;
       
   306       d++;
       
   307     }
       
   308   }
       
   309   return count;
       
   310 }
       
   311 
       
   312 int SCString::contains( const char *str, bool cs ) const
       
   313 {
       
   314   int count = 0;
       
   315   char *d = data();
       
   316   if ( !d )
       
   317     return 0;
       
   318   int len = qstrlen( str );
       
   319   while ( *d )   // counts overlapping strings
       
   320   {
       
   321     if ( cs ) 
       
   322     {
       
   323       if ( qstrncmp( d, str, len ) == 0 )
       
   324         count++;
       
   325     } 
       
   326     else 
       
   327     {
       
   328       if ( qstrnicmp(d, str, len) == 0 )
       
   329         count++;
       
   330     }
       
   331     d++;
       
   332   }
       
   333   return count;
       
   334 }
       
   335 
       
   336 int SCString::contains( const QRegExp &rx ) const
       
   337 { 
       
   338   QString d = QString::fromLatin1( m_data );
       
   339   return d.contains( rx );
       
   340 }
       
   341 
       
   342 SCString SCString::left( uint len )  const
       
   343 {
       
   344   if ( isEmpty() ) 
       
   345   {
       
   346     return SCString();
       
   347   } 
       
   348   else if ( len >= length() ) 
       
   349   {
       
   350     return *this;
       
   351   } 
       
   352   else 
       
   353   {
       
   354     SCString s( len+1 );
       
   355     strncpy( s.data(), m_data, len );
       
   356     *(s.data()+len) = '\0';
       
   357     return s;
       
   358   }
       
   359 }
       
   360 
       
   361 SCString SCString::right( uint len ) const
       
   362 {
       
   363   if ( isEmpty() ) 
       
   364   {
       
   365     return SCString();
       
   366   } 
       
   367   else 
       
   368   {
       
   369     uint l = length();
       
   370     if ( len > l ) len = l;
       
   371     char *p = m_data + (l - len); 
       
   372     return SCString( p ); 
       
   373   }       
       
   374 }
       
   375 
       
   376 SCString SCString::mid( uint index, uint len) const
       
   377 {
       
   378   uint slen = length();
       
   379   if ( len == 0xffffffff ) len = slen-index;
       
   380   if ( isEmpty() || index >= slen ) 
       
   381   {
       
   382     return SCString();
       
   383   } 
       
   384   else 
       
   385   {
       
   386     register char *p = data()+index;
       
   387     SCString s( len+1 );
       
   388     strncpy( s.data(), p, len );
       
   389     *(s.data()+len) = '\0';
       
   390     return s;
       
   391   }
       
   392 }
       
   393 
       
   394 SCString SCString::lower() const
       
   395 {
       
   396   SCString s( m_data );
       
   397   register char *p = s.data();
       
   398   if ( p ) 
       
   399   {
       
   400     while ( *p ) 
       
   401     {
       
   402       *p = tolower((uchar) *p);
       
   403       p++;
       
   404     }
       
   405   }
       
   406   return s;
       
   407 }
       
   408 
       
   409 SCString SCString::upper() const
       
   410 {
       
   411   SCString s( m_data );
       
   412   register char *p = s.data();
       
   413   if ( p ) {
       
   414     while ( *p ) {
       
   415       *p = toupper((uchar)*p);
       
   416       p++;
       
   417     }
       
   418   }
       
   419   return s;
       
   420 }
       
   421 
       
   422 SCString SCString::stripWhiteSpace()	const
       
   423 {
       
   424   if ( isEmpty() )                            // nothing to do
       
   425     return *this;
       
   426 
       
   427   register char *s = m_data;
       
   428   int reslen = length();
       
   429   if ( !isspace((uchar) s[0]) && !isspace((uchar) s[reslen-1]) )
       
   430     return *this;                           // returns a copy
       
   431 
       
   432   SCString result(s);
       
   433   s = result.data(); 
       
   434   int start = 0;
       
   435   int end = reslen - 1;
       
   436   while ( isspace((uchar) s[start]) )                 // skip white space from start
       
   437     start++; 
       
   438   if ( s[start] == '\0' ) 
       
   439   {                                                   // only white space
       
   440     return SCString();
       
   441   }
       
   442   while ( end && isspace((uchar) s[end]) )            // skip white space from end
       
   443     end--;
       
   444   end -= start - 1;
       
   445   memmove( result.data(), &s[start], end );
       
   446   result.resize( end + 1 );
       
   447   return result;
       
   448 }
       
   449 
       
   450 SCString SCString::simplifyWhiteSpace() const
       
   451 {
       
   452   if ( isEmpty() )                            // nothing to do
       
   453     return *this;
       
   454 
       
   455   SCString result( length()+1 );
       
   456   char *from  = data();
       
   457   char *to    = result.data();
       
   458   char *first = to;
       
   459   while ( TRUE ) 
       
   460   {
       
   461     while ( *from && isspace((uchar) *from) )
       
   462       from++;
       
   463     while ( *from && !isspace((uchar)*from) )
       
   464       *to++ = *from++;
       
   465     if ( *from )
       
   466       *to++ = 0x20;                       // ' '
       
   467     else
       
   468       break;
       
   469   }
       
   470   if ( to > first && *(to-1) == 0x20 )
       
   471     to--;
       
   472   *to = '\0';
       
   473   result.resize( (int)((long)to - (long)result.data()) + 1 );
       
   474   return result;
       
   475 }
       
   476 
       
   477 SCString &SCString::insert( uint index, const char *s )
       
   478 {   
       
   479   int len = qstrlen(s);
       
   480   if ( len == 0 )
       
   481     return *this;
       
   482   uint olen = length();
       
   483   int nlen = olen + len;                      
       
   484   if ( index >= olen )  // insert after end of string
       
   485   {                     
       
   486     m_data = (char *)realloc(m_data,nlen+index-olen+1);
       
   487     if ( m_data ) 
       
   488     {
       
   489       memset( m_data+olen, ' ', index-olen );
       
   490       memcpy( m_data+index, s, len+1 );
       
   491     }
       
   492   } 
       
   493   else if ( (m_data = (char *)realloc(m_data,nlen+1)) )  // normal insert
       
   494   { 
       
   495     memmove( m_data+index+len, m_data+index, olen-index+1 );
       
   496     memcpy( m_data+index, s, len );
       
   497   }
       
   498   return *this;
       
   499 }
       
   500 
       
   501 SCString &SCString::insert( uint index, char c )        // insert char
       
   502 {
       
   503   char buf[2];
       
   504   buf[0] = c;
       
   505   buf[1] = '\0';
       
   506   return insert( index, buf );
       
   507 }
       
   508 
       
   509 SCString& SCString::operator+=( const char *str )
       
   510 {
       
   511   if ( !str ) return *this;  // nothing to append
       
   512   uint len1 = length();
       
   513   uint len2 = qstrlen(str);
       
   514   char *newData = (char *)realloc( m_data, len1 + len2 + 1 );
       
   515   if (newData)
       
   516   {
       
   517     m_data = newData;
       
   518     memcpy( m_data + len1, str, len2 + 1 );
       
   519   }
       
   520   return *this;      
       
   521 }
       
   522 
       
   523 SCString &SCString::operator+=( char c )
       
   524 {
       
   525   uint len = length();
       
   526   char *newData = (char *)realloc( m_data, length()+2 );
       
   527   if (newData)
       
   528   {
       
   529     m_data = newData;
       
   530     m_data[len] = c;
       
   531     m_data[len+1] = '\0';
       
   532   }
       
   533   return *this;
       
   534 }
       
   535 
       
   536 SCString &SCString::remove( uint index, uint len )
       
   537 {
       
   538   uint olen = length();
       
   539   if ( index + len >= olen ) // range problems
       
   540   {             
       
   541     if ( index < olen )  // index ok
       
   542     {                  
       
   543       resize( index+1 );
       
   544     }
       
   545   } 
       
   546   else if ( len != 0 ) 
       
   547   {
       
   548     memmove( m_data+index, m_data+index+len, olen-index-len+1 );
       
   549     resize( olen-len+1 );
       
   550   }
       
   551   return *this;
       
   552 }
       
   553 
       
   554 SCString &SCString::replace( uint index, uint len, const char *s )
       
   555 {
       
   556   remove( index, len );
       
   557   insert( index, s );
       
   558   return *this;
       
   559 }
       
   560 
       
   561 SCString &SCString::replace( const QRegExp &rx, const char *str )
       
   562 {
       
   563   QString d = QString::fromLatin1( m_data );
       
   564   QString r = QString::fromLatin1( str );
       
   565   d.replace( rx, r );
       
   566   return assign(d.ascii());
       
   567 }
       
   568 
       
   569 long  SCString::toLong( bool *ok ) const
       
   570 {
       
   571   QString s(m_data);
       
   572   return s.toLong(ok);
       
   573 }
       
   574 
       
   575 ulong SCString::toULong( bool *ok ) const
       
   576 {
       
   577   QString s(m_data);
       
   578   return s.toULong(ok);
       
   579 }
       
   580 
       
   581 short SCString::toShort( bool *ok )	const
       
   582 {
       
   583   QString s(m_data);
       
   584   return s.toShort(ok);
       
   585 }
       
   586 
       
   587 ushort SCString::toUShort( bool *ok ) const
       
   588 {
       
   589   QString s(m_data);
       
   590   return s.toUShort(ok);
       
   591 }
       
   592 
       
   593 int SCString::toInt( bool *ok ) const
       
   594 {
       
   595   QString s(m_data);
       
   596   return s.toInt(ok);
       
   597 }
       
   598 
       
   599 uint SCString::toUInt( bool *ok ) const
       
   600 {
       
   601   QString s(m_data);
       
   602   return s.toUInt(ok);
       
   603 }
       
   604 
       
   605 SCString &SCString::setNum( long n )
       
   606 {
       
   607   char buf[20];
       
   608   register char *p = &buf[19];
       
   609   bool neg;
       
   610   if ( n < 0 ) 
       
   611   {
       
   612     neg = TRUE;
       
   613     n = -n;
       
   614   } 
       
   615   else 
       
   616   {
       
   617     neg = FALSE;
       
   618   }
       
   619   *p = '\0';
       
   620   do 
       
   621   {
       
   622     *--p = ((int)(n%10)) + '0';
       
   623     n /= 10;
       
   624   } while ( n );
       
   625   if ( neg ) *--p = '-';
       
   626   operator=( p );
       
   627   return *this;
       
   628 }
       
   629 
       
   630 SCString &SCString::setNum( ulong n )
       
   631 {
       
   632   char buf[20];
       
   633   register char *p = &buf[19];
       
   634   *p = '\0';
       
   635   do 
       
   636   {
       
   637     *--p = ((int)(n%10)) + '0';
       
   638     n /= 10;
       
   639   } while ( n );
       
   640   operator=( p );
       
   641   return *this;
       
   642 }
       
   643 
       
   644 void SCString::msg_index( uint index )
       
   645 {
       
   646 #if defined(CHECK_RANGE)
       
   647     qWarning( "SCString::at: Absolute index %d out of range", index );
       
   648 #else
       
   649     Q_UNUSED( index )
       
   650 #endif
       
   651 }
       
   652 
       
   653 bool SCString::stripPrefix(const char *prefix)
       
   654 {
       
   655   if (prefix==0) return FALSE;
       
   656   uint plen   = qstrlen(prefix);
       
   657   if (m_data && qstrncmp(prefix,m_data,plen)==0) // prefix matches
       
   658   {
       
   659     uint len    = qstrlen(m_data);
       
   660     uint newlen = len-plen+1;
       
   661     qmemmove(m_data,m_data+plen,newlen);
       
   662     resize(newlen);
       
   663     return TRUE;
       
   664   }
       
   665   return FALSE;
       
   666 }
       
   667 
       
   668 //---------------------------------------------------------------------------
       
   669 
       
   670 void *qmemmove( void *dst, const void *src, uint len )
       
   671 {
       
   672     register char *d;
       
   673     register char *s;
       
   674     if ( dst > src ) {
       
   675 	d = (char *)dst + len - 1;
       
   676 	s = (char *)src + len - 1;
       
   677 	while ( len-- )
       
   678 	    *d-- = *s--;
       
   679     } else if ( dst < src ) {
       
   680 	d = (char *)dst;
       
   681 	s = (char *)src;
       
   682 	while ( len-- )
       
   683 	    *d++ = *s++;
       
   684     }
       
   685     return dst;
       
   686 }
       
   687 
       
   688 char *qstrdup( const char *str )
       
   689 {
       
   690     if ( !str )
       
   691 	return 0;
       
   692     char *dst = new char[strlen(str)+1];
       
   693     CHECK_PTR( dst );
       
   694     return strcpy( dst, str );
       
   695 }
       
   696 
       
   697 char *qstrncpy( char *dst, const char *src, uint len )
       
   698 {
       
   699     if ( !src )
       
   700 	return 0;
       
   701     strncpy( dst, src, len );
       
   702     if ( len > 0 )
       
   703 	dst[len-1] = '\0';
       
   704     return dst;
       
   705 }
       
   706 
       
   707 int qstricmp( const char *str1, const char *str2 )
       
   708 {
       
   709     register const uchar *s1 = (const uchar *)str1;
       
   710     register const uchar *s2 = (const uchar *)str2;
       
   711     int res;
       
   712     uchar c;
       
   713     if ( !s1 || !s2 )
       
   714 	return s1 == s2 ? 0 : (int)((long)s2 - (long)s1);
       
   715     for ( ; !(res = (c=tolower(*s1)) - tolower(*s2)); s1++, s2++ )
       
   716 	if ( !c )				// strings are equal
       
   717 	    break;
       
   718     return res;
       
   719 }
       
   720 
       
   721 int qstrnicmp( const char *str1, const char *str2, uint len )
       
   722 {
       
   723     register const uchar *s1 = (const uchar *)str1;
       
   724     register const uchar *s2 = (const uchar *)str2;
       
   725     int res;
       
   726     uchar c;
       
   727     if ( !s1 || !s2 )
       
   728 	return (int)((long)s2 - (long)s1);
       
   729     for ( ; len--; s1++, s2++ ) {
       
   730 	if ( (res = (c=tolower(*s1)) - tolower(*s2)) )
       
   731 	    return res;
       
   732 	if ( !c )				// strings are equal
       
   733 	    break;
       
   734     }
       
   735     return 0;
       
   736 }
       
   737 
       
   738 #ifndef QT_NO_DATASTREAM
       
   739 
       
   740 QDataStream &operator<<( QDataStream &s, const QByteArray &a )
       
   741 {
       
   742     return s.writeBytes( a.data(), a.size() );
       
   743 }
       
   744 
       
   745 QDataStream &operator>>( QDataStream &s, QByteArray &a )
       
   746 {
       
   747     Q_UINT32 len;
       
   748     s >> len;					// read size of array
       
   749     if ( len == 0 || s.eof() ) {		// end of file reached
       
   750 	a.resize( 0 );
       
   751 	return s;
       
   752     }
       
   753     if ( !a.resize( (uint)len ) ) {		// resize array
       
   754 #if defined(CHECK_NULL)
       
   755 	qWarning( "QDataStream: Not enough memory to read QByteArray" );
       
   756 #endif
       
   757 	len = 0;
       
   758     }
       
   759     if ( len > 0 )				// not null array
       
   760 	s.readRawBytes( a.data(), (uint)len );
       
   761     return s;
       
   762 }
       
   763 
       
   764 QDataStream &operator<<( QDataStream &s, const SCString &str )
       
   765 {
       
   766     return s.writeBytes( str.data(), str.size() );
       
   767 }
       
   768 
       
   769 QDataStream &operator>>( QDataStream &s, SCString &str )
       
   770 {
       
   771     Q_UINT32 len;
       
   772     s >> len;					// read size of string
       
   773     if ( len == 0 || s.eof() ) {		// end of file reached
       
   774 	str.resize( 0 );
       
   775 	return s;
       
   776     }
       
   777     if ( !str.resize( (uint)len )) {// resize string
       
   778 #if defined(CHECK_NULL)
       
   779 	qWarning( "QDataStream: Not enough memory to read QCString" );
       
   780 #endif
       
   781 	len = 0;
       
   782     }
       
   783     if ( len > 0 )				// not null array
       
   784 	s.readRawBytes( str.data(), (uint)len );
       
   785     return s;
       
   786 }
       
   787 
       
   788 #endif //QT_NO_DATASTREAM
       
   789 
       
   790 
       
   791 
       
   792 #endif