Chameleon

Chameleon Svn Source Tree

Root/branches/xZenu/src/util/doxygen/qtools/scstring.cpp

Source at commit 1322 created 12 years 8 months ago.
By meklort, Add doxygen to utils folder
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
37SCString::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
54SCString::SCString( const SCString &s )
55{
56 duplicate(s);
57}
58
59SCString::SCString( const char *str )
60{
61 duplicate(str);
62}
63
64SCString::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
79SCString::~SCString()
80{
81 if (m_data) free(m_data);
82 m_data=0;
83}
84
85SCString &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
93bool 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
113bool 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
139SCString &SCString::sprintf( const char *format, ... )
140{
141 va_list ap;
142 va_start( ap, format );
143 uint l = length();
144 const uint minlen=4095;
145 if (l<minlen)
146 {
147 if (m_data)
148 m_data = (char *)realloc(m_data,minlen+1);
149 else
150 m_data = (char *)malloc(minlen+1);
151 m_data[minlen]='\0';
152 }
153 vsnprintf( m_data, minlen, format, ap );
154 resize( qstrlen(m_data) + 1 ); // truncate
155 va_end( ap );
156 return *this;
157}
158
159
160int SCString::find( char c, int index, bool cs ) const
161{
162 uint len = length();
163 if ( m_data==0 || (uint)index>len ) // index outside string
164 return -1;
165 register const char *d;
166 if ( cs ) // case sensitive
167 {
168 d = strchr( m_data+index, c );
169 }
170 else
171 {
172 d = m_data+index;
173 c = tolower( (uchar) c );
174 while ( *d && tolower((uchar) *d) != c )
175 d++;
176 if ( !*d && c ) // not found
177 d = 0;
178 }
179 return d ? (int)(d - m_data) : -1;
180}
181
182int SCString::find( const char *str, int index, bool cs ) const
183{
184 uint l = length();
185 if ( m_data==0 || (uint)index > l ) // index outside string
186 return -1;
187 if ( !str ) // no search string
188 return -1;
189 if ( !*str ) // zero-length search string
190 return index;
191 register const char *d;
192 if ( cs ) // case sensitive
193 {
194 d = strstr( m_data+index, str );
195 }
196 else // case insensitive
197 {
198 d = m_data+index;
199 int len = qstrlen( str );
200 while ( *d )
201 {
202 if ( qstrnicmp(d, str, len) == 0 )
203 break;
204 d++;
205 }
206 if ( !*d ) // not found
207 d = 0;
208 }
209 return d ? (int)(d - m_data) : -1;
210}
211
212int SCString::find( const QCString &str, int index, bool cs ) const
213{
214 return find(str.data(),index,cs);
215}
216
217int SCString::find( const QRegExp &rx, int index ) const
218{
219 QString d = QString::fromLatin1( m_data );
220 return d.find( rx, index );
221}
222
223int SCString::findRev( char c, int index, bool cs) const
224{
225 const char *b = m_data;
226 const char *d;
227 uint len = length();
228 if ( b == 0 ) return -1; // empty string
229 if ( index < 0 ) // neg index ==> start from end
230 {
231 if ( len == 0 ) return -1;
232 if ( cs )
233 {
234 d = strrchr( b, c );
235 return d ? (int)(d - b) : -1;
236 }
237 index = len;
238 }
239 else if ( (uint)index > len ) // bad index
240 {
241 return -1;
242 }
243 d = b+index;
244 if ( cs ) // case sensitive
245 {
246 while ( d >= b && *d != c )
247 d--;
248 }
249 else // case insensitive
250 {
251 c = tolower( (uchar) c );
252 while ( d >= b && tolower((uchar) *d) != c )
253 d--;
254 }
255 return d >= b ? (int)(d - b) : -1;
256}
257
258int SCString::findRev( const char *str, int index, bool cs) const
259{
260 int slen = qstrlen(str);
261 uint len = length();
262 if ( index < 0 ) // neg index ==> start from end
263 index = len-slen;
264 else if ( (uint)index > len ) // bad index
265 return -1;
266 else if ( (uint)(index + slen) > len ) // str would be too long
267 index = len - slen;
268 if ( index < 0 )
269 return -1;
270
271 register char *d = m_data + index;
272 if ( cs ) // case sensitive
273 {
274 for ( int i=index; i>=0; i-- )
275 if ( qstrncmp(d--,str,slen)==0 )
276 return i;
277 }
278 else // case insensitive
279 {
280 for ( int i=index; i>=0; i-- )
281 if ( qstrnicmp(d--,str,slen)==0 )
282 return i;
283 }
284 return -1;
285
286}
287
288int SCString::findRev( const QRegExp &rx, int index ) const
289{
290 QString d = QString::fromLatin1( m_data );
291 return d.findRev( rx, index );
292}
293
294int SCString::contains( char c, bool cs ) const
295{
296 int count = 0;
297 char *d = m_data;
298 if ( !d )
299 return 0;
300 if ( cs ) // case sensitive
301 {
302 while ( *d )
303 if ( *d++ == c )
304 count++;
305 }
306 else // case insensitive
307 {
308 c = tolower( (uchar) c );
309 while ( *d ) {
310 if ( tolower((uchar) *d) == c )
311 count++;
312 d++;
313 }
314 }
315 return count;
316}
317
318int SCString::contains( const char *str, bool cs ) const
319{
320 int count = 0;
321 char *d = data();
322 if ( !d )
323 return 0;
324 int len = qstrlen( str );
325 while ( *d ) // counts overlapping strings
326 {
327 if ( cs )
328 {
329 if ( qstrncmp( d, str, len ) == 0 )
330 count++;
331 }
332 else
333 {
334 if ( qstrnicmp(d, str, len) == 0 )
335 count++;
336 }
337 d++;
338 }
339 return count;
340}
341
342int SCString::contains( const QRegExp &rx ) const
343{
344 QString d = QString::fromLatin1( m_data );
345 return d.contains( rx );
346}
347
348SCString SCString::left( uint len ) const
349{
350 if ( isEmpty() )
351 {
352 return SCString();
353 }
354 else if ( len >= length() )
355 {
356 return *this;
357 }
358 else
359 {
360 SCString s( len+1 );
361 strncpy( s.data(), m_data, len );
362 *(s.data()+len) = '\0';
363 return s;
364 }
365}
366
367SCString SCString::right( uint len ) const
368{
369 if ( isEmpty() )
370 {
371 return SCString();
372 }
373 else
374 {
375 uint l = length();
376 if ( len > l ) len = l;
377 char *p = m_data + (l - len);
378 return SCString( p );
379 }
380}
381
382SCString SCString::mid( uint index, uint len) const
383{
384 uint slen = length();
385 if ( len == 0xffffffff ) len = slen-index;
386 if ( isEmpty() || index >= slen )
387 {
388 return SCString();
389 }
390 else
391 {
392 register char *p = data()+index;
393 SCString s( len+1 );
394 strncpy( s.data(), p, len );
395 *(s.data()+len) = '\0';
396 return s;
397 }
398}
399
400SCString SCString::lower() const
401{
402 SCString s( m_data );
403 register char *p = s.data();
404 if ( p )
405 {
406 while ( *p )
407 {
408 *p = tolower((uchar) *p);
409 p++;
410 }
411 }
412 return s;
413}
414
415SCString SCString::upper() const
416{
417 SCString s( m_data );
418 register char *p = s.data();
419 if ( p ) {
420 while ( *p ) {
421 *p = toupper((uchar)*p);
422 p++;
423 }
424 }
425 return s;
426}
427
428SCString SCString::stripWhiteSpace()const
429{
430 if ( isEmpty() ) // nothing to do
431 return *this;
432
433 register char *s = m_data;
434 int reslen = length();
435 if ( !isspace((uchar) s[0]) && !isspace((uchar) s[reslen-1]) )
436 return *this; // returns a copy
437
438 SCString result(s);
439 s = result.data();
440 int start = 0;
441 int end = reslen - 1;
442 while ( isspace((uchar) s[start]) ) // skip white space from start
443 start++;
444 if ( s[start] == '\0' )
445 { // only white space
446 return SCString();
447 }
448 while ( end && isspace((uchar) s[end]) ) // skip white space from end
449 end--;
450 end -= start - 1;
451 memmove( result.data(), &s[start], end );
452 result.resize( end + 1 );
453 return result;
454}
455
456SCString SCString::simplifyWhiteSpace() const
457{
458 if ( isEmpty() ) // nothing to do
459 return *this;
460
461 SCString result( length()+1 );
462 char *from = data();
463 char *to = result.data();
464 char *first = to;
465 while ( TRUE )
466 {
467 while ( *from && isspace((uchar) *from) )
468 from++;
469 while ( *from && !isspace((uchar)*from) )
470 *to++ = *from++;
471 if ( *from )
472 *to++ = 0x20; // ' '
473 else
474 break;
475 }
476 if ( to > first && *(to-1) == 0x20 )
477 to--;
478 *to = '\0';
479 result.resize( (int)((long)to - (long)result.data()) + 1 );
480 return result;
481}
482
483SCString &SCString::insert( uint index, const char *s )
484{
485 int len = qstrlen(s);
486 if ( len == 0 )
487 return *this;
488 uint olen = length();
489 int nlen = olen + len;
490 if ( index >= olen ) // insert after end of string
491 {
492 m_data = (char *)realloc(m_data,nlen+index-olen+1);
493 if ( m_data )
494 {
495 memset( m_data+olen, ' ', index-olen );
496 memcpy( m_data+index, s, len+1 );
497 }
498 }
499 else if ( (m_data = (char *)realloc(m_data,nlen+1)) ) // normal insert
500 {
501 memmove( m_data+index+len, m_data+index, olen-index+1 );
502 memcpy( m_data+index, s, len );
503 }
504 return *this;
505}
506
507SCString &SCString::insert( uint index, char c ) // insert char
508{
509 char buf[2];
510 buf[0] = c;
511 buf[1] = '\0';
512 return insert( index, buf );
513}
514
515SCString& SCString::operator+=( const char *str )
516{
517 if ( !str ) return *this; // nothing to append
518 uint len1 = length();
519 uint len2 = qstrlen(str);
520 char *newData = (char *)realloc( m_data, len1 + len2 + 1 );
521 if (newData)
522 {
523 m_data = newData;
524 memcpy( m_data + len1, str, len2 + 1 );
525 }
526 return *this;
527}
528
529SCString &SCString::operator+=( char c )
530{
531 uint len = length();
532 char *newData = (char *)realloc( m_data, length()+2 );
533 if (newData)
534 {
535 m_data = newData;
536 m_data[len] = c;
537 m_data[len+1] = '\0';
538 }
539 return *this;
540}
541
542SCString &SCString::remove( uint index, uint len )
543{
544 uint olen = length();
545 if ( index + len >= olen ) // range problems
546 {
547 if ( index < olen ) // index ok
548 {
549 resize( index+1 );
550 }
551 }
552 else if ( len != 0 )
553 {
554 memmove( m_data+index, m_data+index+len, olen-index-len+1 );
555 resize( olen-len+1 );
556 }
557 return *this;
558}
559
560SCString &SCString::replace( uint index, uint len, const char *s )
561{
562 remove( index, len );
563 insert( index, s );
564 return *this;
565}
566
567SCString &SCString::replace( const QRegExp &rx, const char *str )
568{
569 QString d = QString::fromLatin1( m_data );
570 QString r = QString::fromLatin1( str );
571 d.replace( rx, r );
572 return assign(d.ascii());
573}
574
575long SCString::toLong( bool *ok ) const
576{
577 QString s(m_data);
578 return s.toLong(ok);
579}
580
581ulong SCString::toULong( bool *ok ) const
582{
583 QString s(m_data);
584 return s.toULong(ok);
585}
586
587short SCString::toShort( bool *ok )const
588{
589 QString s(m_data);
590 return s.toShort(ok);
591}
592
593ushort SCString::toUShort( bool *ok ) const
594{
595 QString s(m_data);
596 return s.toUShort(ok);
597}
598
599int SCString::toInt( bool *ok ) const
600{
601 QString s(m_data);
602 return s.toInt(ok);
603}
604
605uint SCString::toUInt( bool *ok ) const
606{
607 QString s(m_data);
608 return s.toUInt(ok);
609}
610
611SCString &SCString::setNum( long n )
612{
613 char buf[20];
614 register char *p = &buf[19];
615 bool neg;
616 if ( n < 0 )
617 {
618 neg = TRUE;
619 n = -n;
620 }
621 else
622 {
623 neg = FALSE;
624 }
625 *p = '\0';
626 do
627 {
628 *--p = ((int)(n%10)) + '0';
629 n /= 10;
630 } while ( n );
631 if ( neg ) *--p = '-';
632 operator=( p );
633 return *this;
634}
635
636SCString &SCString::setNum( ulong n )
637{
638 char buf[20];
639 register char *p = &buf[19];
640 *p = '\0';
641 do
642 {
643 *--p = ((int)(n%10)) + '0';
644 n /= 10;
645 } while ( n );
646 operator=( p );
647 return *this;
648}
649
650void SCString::msg_index( uint index )
651{
652#if defined(CHECK_RANGE)
653 qWarning( "SCString::at: Absolute index %d out of range", index );
654#else
655 Q_UNUSED( index )
656#endif
657}
658
659bool SCString::stripPrefix(const char *prefix)
660{
661 if (prefix==0) return FALSE;
662 uint plen = qstrlen(prefix);
663 if (m_data && qstrncmp(prefix,m_data,plen)==0) // prefix matches
664 {
665 uint len = qstrlen(m_data);
666 uint newlen = len-plen+1;
667 qmemmove(m_data,m_data+plen,newlen);
668 resize(newlen);
669 return TRUE;
670 }
671 return FALSE;
672}
673
674//---------------------------------------------------------------------------
675
676void *qmemmove( void *dst, const void *src, uint len )
677{
678 register char *d;
679 register char *s;
680 if ( dst > src ) {
681d = (char *)dst + len - 1;
682s = (char *)src + len - 1;
683while ( len-- )
684 *d-- = *s--;
685 } else if ( dst < src ) {
686d = (char *)dst;
687s = (char *)src;
688while ( len-- )
689 *d++ = *s++;
690 }
691 return dst;
692}
693
694char *qstrdup( const char *str )
695{
696 if ( !str )
697return 0;
698 char *dst = new char[strlen(str)+1];
699 CHECK_PTR( dst );
700 return strcpy( dst, str );
701}
702
703char *qstrncpy( char *dst, const char *src, uint len )
704{
705 if ( !src )
706return 0;
707 strncpy( dst, src, len );
708 if ( len > 0 )
709dst[len-1] = '\0';
710 return dst;
711}
712
713int qstricmp( const char *str1, const char *str2 )
714{
715 register const uchar *s1 = (const uchar *)str1;
716 register const uchar *s2 = (const uchar *)str2;
717 int res;
718 uchar c;
719 if ( !s1 || !s2 )
720return s1 == s2 ? 0 : (int)((long)s2 - (long)s1);
721 for ( ; !(res = (c=tolower(*s1)) - tolower(*s2)); s1++, s2++ )
722if ( !c )// strings are equal
723 break;
724 return res;
725}
726
727int qstrnicmp( const char *str1, const char *str2, uint len )
728{
729 register const uchar *s1 = (const uchar *)str1;
730 register const uchar *s2 = (const uchar *)str2;
731 int res;
732 uchar c;
733 if ( !s1 || !s2 )
734return (int)((long)s2 - (long)s1);
735 for ( ; len--; s1++, s2++ ) {
736if ( (res = (c=tolower(*s1)) - tolower(*s2)) )
737 return res;
738if ( !c )// strings are equal
739 break;
740 }
741 return 0;
742}
743
744#ifndef QT_NO_DATASTREAM
745
746QDataStream &operator<<( QDataStream &s, const QByteArray &a )
747{
748 return s.writeBytes( a.data(), a.size() );
749}
750
751QDataStream &operator>>( QDataStream &s, QByteArray &a )
752{
753 Q_UINT32 len;
754 s >> len;// read size of array
755 if ( len == 0 || s.eof() ) {// end of file reached
756a.resize( 0 );
757return s;
758 }
759 if ( !a.resize( (uint)len ) ) {// resize array
760#if defined(CHECK_NULL)
761qWarning( "QDataStream: Not enough memory to read QByteArray" );
762#endif
763len = 0;
764 }
765 if ( len > 0 )// not null array
766s.readRawBytes( a.data(), (uint)len );
767 return s;
768}
769
770QDataStream &operator<<( QDataStream &s, const SCString &str )
771{
772 return s.writeBytes( str.data(), str.size() );
773}
774
775QDataStream &operator>>( QDataStream &s, SCString &str )
776{
777 Q_UINT32 len;
778 s >> len;// read size of string
779 if ( len == 0 || s.eof() ) {// end of file reached
780str.resize( 0 );
781return s;
782 }
783 if ( !str.resize( (uint)len )) {// resize string
784#if defined(CHECK_NULL)
785qWarning( "QDataStream: Not enough memory to read QCString" );
786#endif
787len = 0;
788 }
789 if ( len > 0 )// not null array
790s.readRawBytes( str.data(), (uint)len );
791 return s;
792}
793
794#endif //QT_NO_DATASTREAM
795
796
797
798#endif
799

Archive Download this file

Revision: 1322