|
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 |