00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "qgdict.h"
00039 #include "qptrlist.h"
00040 #include "qstring.h"
00041 #include "qdatastream.h"
00042 #include <ctype.h>
00043
00064 static const int op_find = 0;
00065 static const int op_insert = 1;
00066 static const int op_replace = 2;
00067
00068
00069 class QGDItList : public QPtrList<QGDictIterator>
00070 {
00071 public:
00072 QGDItList() : QPtrList<QGDictIterator>() {}
00073 QGDItList( const QGDItList &list ) : QPtrList<QGDictIterator>(list) {}
00074 ~QGDItList() { clear(); }
00075 QGDItList &operator=(const QGDItList &list)
00076 { return (QGDItList&)QPtrList<QGDictIterator>::operator=(list); }
00077 };
00078
00079
00080
00081
00082
00083
00088 int QGDict::hashKeyString( const QString &key )
00089 {
00090 #if defined(QT_CHECK_NULL)
00091 if ( key.isNull() )
00092 qWarning( "QGDict::hashKeyString: Invalid null key" );
00093 #endif
00094 int i;
00095 register uint h=0;
00096 uint g;
00097 const QChar *p = key.unicode();
00098 if ( cases ) {
00099 for ( i=0; i<(int)key.length(); i++ ) {
00100 h = (h<<4) + p[i].cell();
00101 if ( (g = h & 0xf0000000) )
00102 h ^= g >> 24;
00103 h &= ~g;
00104 }
00105 } else {
00106 for ( i=0; i<(int)key.length(); i++ ) {
00107 h = (h<<4) + p[i].lower().cell();
00108 if ( (g = h & 0xf0000000) )
00109 h ^= g >> 24;
00110 h &= ~g;
00111 }
00112 }
00113 int index = h;
00114 if ( index < 0 )
00115 index = -index;
00116 return index;
00117 }
00118
00123 int QGDict::hashKeyAscii( const char *key )
00124 {
00125 #if defined(QT_CHECK_NULL)
00126 if ( key == 0 )
00127 qWarning( "QGDict::hashAsciiKey: Invalid null key" );
00128 #endif
00129 register const char *k = key;
00130 register uint h=0;
00131 uint g;
00132 if ( cases ) {
00133 while ( *k ) {
00134 h = (h<<4) + *k++;
00135 if ( (g = h & 0xf0000000) )
00136 h ^= g >> 24;
00137 h &= ~g;
00138 }
00139 } else {
00140 while ( *k ) {
00141 h = (h<<4) + tolower((uchar) *k);
00142 if ( (g = h & 0xf0000000) )
00143 h ^= g >> 24;
00144 h &= ~g;
00145 k++;
00146 }
00147 }
00148 int index = h;
00149 if ( index < 0 )
00150 index = -index;
00151 return index;
00152 }
00153
00154 #ifndef QT_NO_DATASTREAM
00155
00166 QDataStream& QGDict::read( QDataStream &s, QPtrCollection::Item &item )
00167 {
00168 item = 0;
00169 return s;
00170 }
00171
00180 QDataStream& QGDict::write( QDataStream &s, QPtrCollection::Item ) const
00181 {
00182 return s;
00183 }
00184 #endif //QT_NO_DATASTREAM
00185
00186
00187
00188
00189
00199 QGDict::QGDict( uint len, KeyType kt, bool caseSensitive, bool copyKeys )
00200 {
00201 init( len, kt, caseSensitive, copyKeys );
00202 }
00203
00204
00205 void QGDict::init( uint len, KeyType kt, bool caseSensitive, bool copyKeys )
00206 {
00207 vlen = len;
00208 if ( vlen == 0 )
00209 vlen = 17;
00210 vec = new QBaseBucket *[vlen];
00211 Q_CHECK_PTR( vec );
00212 memset( (char*)vec, 0, vlen*sizeof(QBaseBucket*) );
00213 numItems = 0;
00214 iterators = 0;
00215
00216
00217 switch ( (keytype = (uint)kt) ) {
00218 case StringKey:
00219 cases = caseSensitive;
00220 copyk = FALSE;
00221 break;
00222 case AsciiKey:
00223 cases = caseSensitive;
00224 copyk = copyKeys;
00225 break;
00226 default:
00227 cases = FALSE;
00228 copyk = FALSE;
00229 break;
00230 }
00231 }
00232
00233
00238 QGDict::QGDict( const QGDict & dict )
00239 : QPtrCollection( dict )
00240 {
00241 init( dict.vlen, (KeyType)dict.keytype, dict.cases, dict.copyk );
00242 QGDictIterator it( dict );
00243 while ( it.get() ) {
00244 switch ( keytype ) {
00245 case StringKey:
00246 look_string( it.getKeyString(), it.get(), op_insert );
00247 break;
00248 case AsciiKey:
00249 look_ascii( it.getKeyAscii(), it.get(), op_insert );
00250 break;
00251 case IntKey:
00252 look_int( it.getKeyInt(), it.get(), op_insert );
00253 break;
00254 case PtrKey:
00255 look_ptr( it.getKeyPtr(), it.get(), op_insert );
00256 break;
00257 }
00258 ++it;
00259 }
00260 }
00261
00262
00267 QGDict::~QGDict()
00268 {
00269 clear();
00270 delete [] vec;
00271 if ( !iterators )
00272 return;
00273 QGDictIterator *i = iterators->first();
00274 while ( i ) {
00275 i->dict = 0;
00276 i = iterators->next();
00277 }
00278 delete iterators;
00279 }
00280
00281
00286 QGDict &QGDict::operator=( const QGDict &dict )
00287 {
00288 if ( &dict == this )
00289 return *this;
00290 clear();
00291 QGDictIterator it( dict );
00292 while ( it.get() ) {
00293 switch ( keytype ) {
00294 case StringKey:
00295 look_string( it.getKeyString(), it.get(), op_insert );
00296 break;
00297 case AsciiKey:
00298 look_ascii( it.getKeyAscii(), it.get(), op_insert );
00299 break;
00300 case IntKey:
00301 look_int( it.getKeyInt(), it.get(), op_insert );
00302 break;
00303 case PtrKey:
00304 look_ptr( it.getKeyPtr(), it.get(), op_insert );
00305 break;
00306 }
00307 ++it;
00308 }
00309 return *this;
00310 }
00311
00329 QPtrCollection::Item QGDict::look_string( const QString &key, QPtrCollection::Item d,
00330 int op )
00331 {
00332 QStringBucket *n = 0;
00333 int index = hashKeyString(key) % vlen;
00334 if ( op == op_find ) {
00335 if ( cases ) {
00336 n = (QStringBucket*)vec[index];
00337 while( n != 0 ) {
00338 if ( key == n->getKey() )
00339 return n->getData();
00340 n = (QStringBucket*)n->getNext();
00341 }
00342 } else {
00343 QString k = key.lower();
00344 n = (QStringBucket*)vec[index];
00345 while( n != 0 ) {
00346 if ( k == n->getKey().lower() )
00347 return n->getData();
00348 n = (QStringBucket*)n->getNext();
00349 }
00350 }
00351 return 0;
00352 }
00353 if ( op == op_replace ) {
00354 if ( vec[index] != 0 )
00355 remove_string( key );
00356 }
00357
00358 n = new QStringBucket(key,newItem(d),vec[index]);
00359 Q_CHECK_PTR( n );
00360 #if defined(QT_CHECK_NULL)
00361 if ( n->getData() == 0 )
00362 qWarning( "QDict: Cannot insert null item" );
00363 #endif
00364 vec[index] = n;
00365 numItems++;
00366 return n->getData();
00367 }
00368
00369 QPtrCollection::Item QGDict::look_ascii( const char *key, QPtrCollection::Item d, int op )
00370 {
00371 QAsciiBucket *n;
00372 int index = hashKeyAscii(key) % vlen;
00373 if ( op == op_find ) {
00374 if ( cases ) {
00375 for ( n=(QAsciiBucket*)vec[index]; n;
00376 n=(QAsciiBucket*)n->getNext() ) {
00377 if ( qstrcmp(n->getKey(),key) == 0 )
00378 return n->getData();
00379 }
00380 } else {
00381 for ( n=(QAsciiBucket*)vec[index]; n;
00382 n=(QAsciiBucket*)n->getNext() ) {
00383 if ( qstricmp(n->getKey(),key) == 0 )
00384 return n->getData();
00385 }
00386 }
00387 return 0;
00388 }
00389 if ( op == op_replace ) {
00390 if ( vec[index] != 0 )
00391 remove_ascii( key );
00392 }
00393
00394 n = new QAsciiBucket(copyk ? qstrdup(key) : key,newItem(d),vec[index]);
00395 Q_CHECK_PTR( n );
00396 #if defined(QT_CHECK_NULL)
00397 if ( n->getData() == 0 )
00398 qWarning( "QAsciiDict: Cannot insert null item" );
00399 #endif
00400 vec[index] = n;
00401 numItems++;
00402 return n->getData();
00403 }
00404
00405 QPtrCollection::Item QGDict::look_int( long key, QPtrCollection::Item d, int op )
00406 {
00407 QIntBucket *n;
00408 int index = (int)((ulong)key % vlen);
00409 if ( op == op_find ) {
00410 for ( n=(QIntBucket*)vec[index]; n;
00411 n=(QIntBucket*)n->getNext() ) {
00412 if ( n->getKey() == key )
00413 return n->getData();
00414 }
00415 return 0;
00416 }
00417 if ( op == op_replace ) {
00418 if ( vec[index] != 0 )
00419 remove_int( key );
00420 }
00421
00422 n = new QIntBucket(key,newItem(d),vec[index]);
00423 Q_CHECK_PTR( n );
00424 #if defined(QT_CHECK_NULL)
00425 if ( n->getData() == 0 )
00426 qWarning( "QIntDict: Cannot insert null item" );
00427 #endif
00428 vec[index] = n;
00429 numItems++;
00430 return n->getData();
00431 }
00432
00433 QPtrCollection::Item QGDict::look_ptr( void *key, QPtrCollection::Item d, int op )
00434 {
00435 QPtrBucket *n;
00436 int index = (int)((ulong)key % vlen);
00437 if ( op == op_find ) {
00438 for ( n=(QPtrBucket*)vec[index]; n;
00439 n=(QPtrBucket*)n->getNext() ) {
00440 if ( n->getKey() == key )
00441 return n->getData();
00442 }
00443 return 0;
00444 }
00445 if ( op == op_replace ) {
00446 if ( vec[index] != 0 )
00447 remove_ptr( key );
00448 }
00449
00450 n = new QPtrBucket(key,newItem(d),vec[index]);
00451 Q_CHECK_PTR( n );
00452 #if defined(QT_CHECK_NULL)
00453 if ( n->getData() == 0 )
00454 qWarning( "QPtrDict: Cannot insert null item" );
00455 #endif
00456 vec[index] = n;
00457 numItems++;
00458 return n->getData();
00459 }
00460
00461
00467 void QGDict::resize( uint newsize )
00468 {
00469
00470 QBaseBucket **old_vec = vec;
00471 uint old_vlen = vlen;
00472 bool old_copyk = copyk;
00473
00474 vec = new QBaseBucket *[vlen = newsize];
00475 Q_CHECK_PTR( vec );
00476 memset( (char*)vec, 0, vlen*sizeof(QBaseBucket*) );
00477 numItems = 0;
00478 copyk = FALSE;
00479
00480
00481 for ( uint index = 0; index < old_vlen; index++ ) {
00482 switch ( keytype ) {
00483 case StringKey:
00484 {
00485 QStringBucket *n=(QStringBucket *)old_vec[index];
00486 while ( n ) {
00487 look_string( n->getKey(), n->getData(), op_insert );
00488 QStringBucket *t=(QStringBucket *)n->getNext();
00489 delete n;
00490 n = t;
00491 }
00492 }
00493 break;
00494 case AsciiKey:
00495 {
00496 QAsciiBucket *n=(QAsciiBucket *)old_vec[index];
00497 while ( n ) {
00498 look_ascii( n->getKey(), n->getData(), op_insert );
00499 QAsciiBucket *t=(QAsciiBucket *)n->getNext();
00500 delete n;
00501 n = t;
00502 }
00503 }
00504 break;
00505 case IntKey:
00506 {
00507 QIntBucket *n=(QIntBucket *)old_vec[index];
00508 while ( n ) {
00509 look_int( n->getKey(), n->getData(), op_insert );
00510 QIntBucket *t=(QIntBucket *)n->getNext();
00511 delete n;
00512 n = t;
00513 }
00514 }
00515 break;
00516 case PtrKey:
00517 {
00518 QPtrBucket *n=(QPtrBucket *)old_vec[index];
00519 while ( n ) {
00520 look_ptr( n->getKey(), n->getData(), op_insert );
00521 QPtrBucket *t=(QPtrBucket *)n->getNext();
00522 delete n;
00523 n = t;
00524 }
00525 }
00526 break;
00527 }
00528 }
00529 delete [] old_vec;
00530
00531
00532 copyk = old_copyk;
00533
00534
00535 if ( iterators && iterators->count() ) {
00536 QGDictIterator *i = iterators->first();
00537 while ( i ) {
00538 i->toFirst();
00539 i = iterators->next();
00540 }
00541 }
00542 }
00543
00549 void QGDict::unlink_common( int index, QBaseBucket *node, QBaseBucket *prev )
00550 {
00551 if ( iterators && iterators->count() ) {
00552 QGDictIterator *i = iterators->first();
00553 while ( i ) {
00554 if ( i->curNode == node )
00555 i->operator++();
00556 i = iterators->next();
00557 }
00558 }
00559 if ( prev )
00560 prev->setNext( node->getNext() );
00561 else
00562 vec[index] = node->getNext();
00563 numItems--;
00564 }
00565
00566 QStringBucket *QGDict::unlink_string( const QString &key, QPtrCollection::Item d )
00567 {
00568 if ( numItems == 0 )
00569 return 0;
00570 QStringBucket *n;
00571 QStringBucket *prev = 0;
00572 int index = hashKeyString(key) % vlen;
00573 if ( cases ) {
00574 for ( n=(QStringBucket*)vec[index]; n;
00575 n=(QStringBucket*)n->getNext() ) {
00576 bool found = (key == n->getKey());
00577 if ( found && d )
00578 found = (n->getData() == d);
00579 if ( found ) {
00580 unlink_common(index,n,prev);
00581 return n;
00582 }
00583 prev = n;
00584 }
00585 } else {
00586 QString k = key.lower();
00587 for ( n=(QStringBucket*)vec[index]; n;
00588 n=(QStringBucket*)n->getNext() ) {
00589 bool found = (k == n->getKey().lower());
00590 if ( found && d )
00591 found = (n->getData() == d);
00592 if ( found ) {
00593 unlink_common(index,n,prev);
00594 return n;
00595 }
00596 prev = n;
00597 }
00598 }
00599 return 0;
00600 }
00601
00602 QAsciiBucket *QGDict::unlink_ascii( const char *key, QPtrCollection::Item d )
00603 {
00604 if ( numItems == 0 )
00605 return 0;
00606 QAsciiBucket *n;
00607 QAsciiBucket *prev = 0;
00608 int index = hashKeyAscii(key) % vlen;
00609 for ( n=(QAsciiBucket *)vec[index]; n; n=(QAsciiBucket *)n->getNext() ) {
00610 bool found = (cases ? qstrcmp(n->getKey(),key)
00611 : qstricmp(n->getKey(),key)) == 0;
00612 if ( found && d )
00613 found = (n->getData() == d);
00614 if ( found ) {
00615 unlink_common(index,n,prev);
00616 return n;
00617 }
00618 prev = n;
00619 }
00620 return 0;
00621 }
00622
00623 QIntBucket *QGDict::unlink_int( long key, QPtrCollection::Item d )
00624 {
00625 if ( numItems == 0 )
00626 return 0;
00627 QIntBucket *n;
00628 QIntBucket *prev = 0;
00629 int index = (int)((ulong)key % vlen);
00630 for ( n=(QIntBucket *)vec[index]; n; n=(QIntBucket *)n->getNext() ) {
00631 bool found = (n->getKey() == key);
00632 if ( found && d )
00633 found = (n->getData() == d);
00634 if ( found ) {
00635 unlink_common(index,n,prev);
00636 return n;
00637 }
00638 prev = n;
00639 }
00640 return 0;
00641 }
00642
00643 QPtrBucket *QGDict::unlink_ptr( void *key, QPtrCollection::Item d )
00644 {
00645 if ( numItems == 0 )
00646 return 0;
00647 QPtrBucket *n;
00648 QPtrBucket *prev = 0;
00649 int index = (int)((ulong)key % vlen);
00650 for ( n=(QPtrBucket *)vec[index]; n; n=(QPtrBucket *)n->getNext() ) {
00651 bool found = (n->getKey() == key);
00652 if ( found && d )
00653 found = (n->getData() == d);
00654 if ( found ) {
00655 unlink_common(index,n,prev);
00656 return n;
00657 }
00658 prev = n;
00659 }
00660 return 0;
00661 }
00662
00663
00670 bool QGDict::remove_string( const QString &key, QPtrCollection::Item item )
00671 {
00672 QStringBucket *n = unlink_string( key, item );
00673 if ( n ) {
00674 deleteItem( n->getData() );
00675 delete n;
00676 return TRUE;
00677 } else {
00678 return FALSE;
00679 }
00680 }
00681
00682 bool QGDict::remove_ascii( const char *key, QPtrCollection::Item item )
00683 {
00684 QAsciiBucket *n = unlink_ascii( key, item );
00685 if ( n ) {
00686 if ( copyk )
00687 delete [] (char *)n->getKey();
00688 deleteItem( n->getData() );
00689 delete n;
00690 }
00691 return n != 0;
00692 }
00693
00694 bool QGDict::remove_int( long key, QPtrCollection::Item item )
00695 {
00696 QIntBucket *n = unlink_int( key, item );
00697 if ( n ) {
00698 deleteItem( n->getData() );
00699 delete n;
00700 }
00701 return n != 0;
00702 }
00703
00704 bool QGDict::remove_ptr( void *key, QPtrCollection::Item item )
00705 {
00706 QPtrBucket *n = unlink_ptr( key, item );
00707 if ( n ) {
00708 deleteItem( n->getData() );
00709 delete n;
00710 }
00711 return n != 0;
00712 }
00713
00714 QPtrCollection::Item QGDict::take_string( const QString &key )
00715 {
00716 QStringBucket *n = unlink_string( key );
00717 Item d;
00718 if ( n ) {
00719 d = n->getData();
00720 delete n;
00721 } else {
00722 d = 0;
00723 }
00724 return d;
00725 }
00726
00727 QPtrCollection::Item QGDict::take_ascii( const char *key )
00728 {
00729 QAsciiBucket *n = unlink_ascii( key );
00730 Item d;
00731 if ( n ) {
00732 if ( copyk )
00733 delete [] (char *)n->getKey();
00734 d = n->getData();
00735 delete n;
00736 } else {
00737 d = 0;
00738 }
00739 return d;
00740 }
00741
00742 QPtrCollection::Item QGDict::take_int( long key )
00743 {
00744 QIntBucket *n = unlink_int( key );
00745 Item d;
00746 if ( n ) {
00747 d = n->getData();
00748 delete n;
00749 } else {
00750 d = 0;
00751 }
00752 return d;
00753 }
00754
00755 QPtrCollection::Item QGDict::take_ptr( void *key )
00756 {
00757 QPtrBucket *n = unlink_ptr( key );
00758 Item d;
00759 if ( n ) {
00760 d = n->getData();
00761 delete n;
00762 } else {
00763 d = 0;
00764 }
00765 return d;
00766 }
00767
00771 void QGDict::clear()
00772 {
00773 if ( !numItems )
00774 return;
00775 numItems = 0;
00776 for ( uint j=0; j<vlen; j++ ) {
00777 if ( vec[j] ) {
00778 switch ( keytype ) {
00779 case StringKey:
00780 {
00781 QStringBucket *n=(QStringBucket *)vec[j];
00782 while ( n ) {
00783 QStringBucket *next = (QStringBucket*)n->getNext();
00784 deleteItem( n->getData() );
00785 delete n;
00786 n = next;
00787 }
00788 }
00789 break;
00790 case AsciiKey:
00791 {
00792 QAsciiBucket *n=(QAsciiBucket *)vec[j];
00793 while ( n ) {
00794 QAsciiBucket *next = (QAsciiBucket*)n->getNext();
00795 if ( copyk )
00796 delete [] (char *)n->getKey();
00797 deleteItem( n->getData() );
00798 delete n;
00799 n = next;
00800 }
00801 }
00802 break;
00803 case IntKey:
00804 {
00805 QIntBucket *n=(QIntBucket *)vec[j];
00806 while ( n ) {
00807 QIntBucket *next = (QIntBucket*)n->getNext();
00808 deleteItem( n->getData() );
00809 delete n;
00810 n = next;
00811 }
00812 }
00813 break;
00814 case PtrKey:
00815 {
00816 QPtrBucket *n=(QPtrBucket *)vec[j];
00817 while ( n ) {
00818 QPtrBucket *next = (QPtrBucket*)n->getNext();
00819 deleteItem( n->getData() );
00820 delete n;
00821 n = next;
00822 }
00823 }
00824 break;
00825 }
00826 vec[j] = 0;
00827 }
00828 }
00829 if ( iterators && iterators->count() ) {
00830 QGDictIterator *i = iterators->first();
00831 while ( i ) {
00832 i->curNode = 0;
00833 i = iterators->next();
00834 }
00835 }
00836 }
00837
00841 void QGDict::statistics() const
00842 {
00843 #if defined(QT_DEBUG)
00844 QString line;
00845 line.fill( '-', 60 );
00846 double real, ideal;
00847 qDebug( line.ascii() );
00848 qDebug( "DICTIONARY STATISTICS:" );
00849 if ( count() == 0 ) {
00850 qDebug( "Empty!" );
00851 qDebug( line.ascii() );
00852 return;
00853 }
00854 real = 0.0;
00855 ideal = (float)count()/(2.0*size())*(count()+2.0*size()-1);
00856 uint i = 0;
00857 while ( i<size() ) {
00858 QBaseBucket *n = vec[i];
00859 int b = 0;
00860 while ( n ) {
00861 b++;
00862 n = n->getNext();
00863 }
00864 real = real + (double)b * ((double)b+1.0)/2.0;
00865 char buf[80], *pbuf;
00866 if ( b > 78 )
00867 b = 78;
00868 pbuf = buf;
00869 while ( b-- )
00870 *pbuf++ = '*';
00871 *pbuf = '\0';
00872 qDebug( buf );
00873 i++;
00874 }
00875 qDebug( "Array size = %d", size() );
00876 qDebug( "# items = %d", count() );
00877 qDebug( "Real dist = %g", real );
00878 qDebug( "Rand dist = %g", ideal );
00879 qDebug( "Real/Rand = %g", real/ideal );
00880 qDebug( line.ascii() );
00881 #endif // QT_DEBUG
00882 }
00883
00884
00885
00886
00887
00888 #ifndef QT_NO_DATASTREAM
00889 QDataStream &operator>>( QDataStream &s, QGDict &dict )
00890 {
00891 return dict.read( s );
00892 }
00893
00894 QDataStream &operator<<( QDataStream &s, const QGDict &dict )
00895 {
00896 return dict.write( s );
00897 }
00898
00899 #if defined(Q_CC_DEC) && defined(__alpha) && (__DECCXX_VER-0 >= 50190001)
00900 #pragma message disable narrowptr
00901 #endif
00902
00907 QDataStream &QGDict::read( QDataStream &s )
00908 {
00909 uint num;
00910 s >> num;
00911 clear();
00912 while ( num-- ) {
00913 Item d;
00914 switch ( keytype ) {
00915 case StringKey:
00916 {
00917 QString k;
00918 s >> k;
00919 read( s, d );
00920 look_string( k, d, op_insert );
00921 }
00922 break;
00923 case AsciiKey:
00924 {
00925 char *k;
00926 s >> k;
00927 read( s, d );
00928 look_ascii( k, d, op_insert );
00929 if ( copyk )
00930 delete [] k;
00931 }
00932 break;
00933 case IntKey:
00934 {
00935 Q_UINT32 k;
00936 s >> k;
00937 read( s, d );
00938 look_int( k, d, op_insert );
00939 }
00940 break;
00941 case PtrKey:
00942 {
00943 Q_UINT32 k;
00944 s >> k;
00945 read( s, d );
00946
00947
00948
00949
00950 if ( k )
00951 look_ptr( (void *)k, d, op_insert );
00952 }
00953 break;
00954 }
00955 }
00956 return s;
00957 }
00958
00963 QDataStream& QGDict::write( QDataStream &s ) const
00964 {
00965 s << count();
00966 uint i = 0;
00967 while ( i<size() ) {
00968 QBaseBucket *n = vec[i];
00969 while ( n ) {
00970 switch ( keytype ) {
00971 case StringKey:
00972 s << ((QStringBucket*)n)->getKey();
00973 break;
00974 case AsciiKey:
00975 s << ((QAsciiBucket*)n)->getKey();
00976 break;
00977 case IntKey:
00978 s << (Q_UINT32)((QIntBucket*)n)->getKey();
00979 break;
00980 case PtrKey:
00981 s << (Q_UINT32)0;
00982 break;
00983 }
00984 write( s, n->getData() );
00985 n = n->getNext();
00986 }
00987 i++;
00988 }
00989 return s;
00990 }
00991 #endif //QT_NO_DATASTREAM
00992
00993
00994
00995
00996
01013 QGDictIterator::QGDictIterator( const QGDict &d )
01014 {
01015 dict = (QGDict *)&d;
01016 toFirst();
01017 if ( !dict->iterators ) {
01018 dict->iterators = new QGDItList;
01019 Q_CHECK_PTR( dict->iterators );
01020 }
01021 dict->iterators->append( this );
01022 }
01023
01028 QGDictIterator::QGDictIterator( const QGDictIterator &it )
01029 {
01030 dict = it.dict;
01031 curNode = it.curNode;
01032 curIndex = it.curIndex;
01033 if ( dict )
01034 dict->iterators->append( this );
01035 }
01036
01042 QGDictIterator &QGDictIterator::operator=( const QGDictIterator &it )
01043 {
01044 if ( dict )
01045 dict->iterators->removeRef( this );
01046 dict = it.dict;
01047 curNode = it.curNode;
01048 curIndex = it.curIndex;
01049 if ( dict )
01050 dict->iterators->append( this );
01051 return *this;
01052 }
01053
01058 QGDictIterator::~QGDictIterator()
01059 {
01060 if ( dict )
01061 dict->iterators->removeRef( this );
01062 }
01063
01064
01069 QPtrCollection::Item QGDictIterator::toFirst()
01070 {
01071 if ( !dict ) {
01072 #if defined(QT_CHECK_NULL)
01073 qWarning( "QGDictIterator::toFirst: Dictionary has been deleted" );
01074 #endif
01075 return 0;
01076 }
01077 if ( dict->count() == 0 ) {
01078 curNode = 0;
01079 return 0;
01080 }
01081 register uint i = 0;
01082 register QBaseBucket **v = dict->vec;
01083 while ( !(*v++) )
01084 i++;
01085 curNode = dict->vec[i];
01086 curIndex = i;
01087 return curNode->getData();
01088 }
01089
01090
01095 QPtrCollection::Item QGDictIterator::operator()()
01096 {
01097 if ( !dict ) {
01098 #if defined(QT_CHECK_NULL)
01099 qWarning( "QGDictIterator::operator(): Dictionary has been deleted" );
01100 #endif
01101 return 0;
01102 }
01103 if ( !curNode )
01104 return 0;
01105 QPtrCollection::Item d = curNode->getData();
01106 this->operator++();
01107 return d;
01108 }
01109
01114 QPtrCollection::Item QGDictIterator::operator++()
01115 {
01116 if ( !dict ) {
01117 #if defined(QT_CHECK_NULL)
01118 qWarning( "QGDictIterator::operator++: Dictionary has been deleted" );
01119 #endif
01120 return 0;
01121 }
01122 if ( !curNode )
01123 return 0;
01124 curNode = curNode->getNext();
01125 if ( !curNode ) {
01126 register uint i = curIndex + 1;
01127 register QBaseBucket **v = &dict->vec[i];
01128 while ( i < dict->size() && !(*v++) )
01129 i++;
01130 if ( i == dict->size() ) {
01131 curNode = 0;
01132 return 0;
01133 }
01134 curNode = dict->vec[i];
01135 curIndex = i;
01136 }
01137 return curNode->getData();
01138 }
01139
01144 QPtrCollection::Item QGDictIterator::operator+=( uint jumps )
01145 {
01146 while ( curNode && jumps-- )
01147 operator++();
01148 return curNode ? curNode->getData() : 0;
01149 }