-rw-r--r-- | qmake/tools/qgdict.cpp | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/qmake/tools/qgdict.cpp b/qmake/tools/qgdict.cpp index c431ff8..3d49fc7 100644 --- a/qmake/tools/qgdict.cpp +++ b/qmake/tools/qgdict.cpp @@ -15,385 +15,388 @@ ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition ** licenses may use this file in accordance with the Qt Commercial License ** Agreement provided with the Software. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for ** information about Qt Commercial License Agreements. ** See http://www.trolltech.com/qpl/ for QPL licensing information. ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #include "qgdict.h" #include "qptrlist.h" #include "qstring.h" #include "qdatastream.h" #include <ctype.h> /*! \class QGDict \reentrant \ingroup collection \brief The QGDict class is an internal class for implementing QDict template classes. \internal QGDict is a strictly internal class that acts as a base class for the \link collection.html collection classes\endlink QDict and QIntDict. QGDict has some virtual functions that can be reimplemented to customize the subclasses. \list \i read() reads a collection/dictionary item from a QDataStream. \i write() writes a collection/dictionary item to a QDataStream. \endlist Normally, you do not have to reimplement any of these functions. */ static const int op_find = 0; static const int op_insert = 1; static const int op_replace = 2; class QGDItList : public QPtrList<QGDictIterator> { public: QGDItList() : QPtrList<QGDictIterator>() {} QGDItList( const QGDItList &list ) : QPtrList<QGDictIterator>(list) {} ~QGDItList() { clear(); } QGDItList &operator=(const QGDItList &list) { return (QGDItList&)QPtrList<QGDictIterator>::operator=(list); } }; /***************************************************************************** Default implementation of special and virtual functions *****************************************************************************/ /*! Returns the hash key for \a key, when key is a string. */ int QGDict::hashKeyString( const QString &key ) { #if defined(QT_CHECK_NULL) if ( key.isNull() ) qWarning( "QGDict::hashKeyString: Invalid null key" ); #endif int i; register uint h=0; uint g; const QChar *p = key.unicode(); if ( cases ) { // case sensitive for ( i=0; i<(int)key.length(); i++ ) { h = (h<<4) + p[i].cell(); if ( (g = h & 0xf0000000) ) h ^= g >> 24; h &= ~g; } } else { // case insensitive for ( i=0; i<(int)key.length(); i++ ) { h = (h<<4) + p[i].lower().cell(); if ( (g = h & 0xf0000000) ) h ^= g >> 24; h &= ~g; } } int index = h; if ( index < 0 ) // adjust index to table size index = -index; return index; } /*! Returns the hash key for \a key, which is a C string. */ int QGDict::hashKeyAscii( const char *key ) { #if defined(QT_CHECK_NULL) if ( key == 0 ) qWarning( "QGDict::hashAsciiKey: Invalid null key" ); #endif register const char *k = key; register uint h=0; uint g; if ( cases ) { // case sensitive while ( *k ) { h = (h<<4) + *k++; if ( (g = h & 0xf0000000) ) h ^= g >> 24; h &= ~g; } } else { // case insensitive while ( *k ) { h = (h<<4) + tolower((uchar) *k); if ( (g = h & 0xf0000000) ) h ^= g >> 24; h &= ~g; k++; } } int index = h; if ( index < 0 ) // adjust index to table size index = -index; return index; } #ifndef QT_NO_DATASTREAM /*! \overload Reads a collection/dictionary item from the stream \a s and returns a reference to the stream. The default implementation sets \a item to 0. \sa write() */ QDataStream& QGDict::read( QDataStream &s, QPtrCollection::Item &item ) { item = 0; return s; } /*! \overload Writes a collection/dictionary item to the stream \a s and returns a reference to the stream. \sa read() */ QDataStream& QGDict::write( QDataStream &s, QPtrCollection::Item ) const { return s; } #endif //QT_NO_DATASTREAM /***************************************************************************** QGDict member functions *****************************************************************************/ /*! Constructs a dictionary. \a len is the initial size of the dictionary. The key type is \a kt which may be \c StringKey, \c AsciiKey, \c IntKey or \c PtrKey. The case-sensitivity of lookups is set with \a caseSensitive. Keys are copied if \a copyKeys is TRUE. */ QGDict::QGDict( uint len, KeyType kt, bool caseSensitive, bool copyKeys ) { init( len, kt, caseSensitive, copyKeys ); } void QGDict::init( uint len, KeyType kt, bool caseSensitive, bool copyKeys ) { - vec = new QBaseBucket *[vlen = len]; // allocate hash table + vlen = len; + if ( vlen == 0 ) + vlen = 17; + vec = new QBaseBucket *[vlen]; Q_CHECK_PTR( vec ); memset( (char*)vec, 0, vlen*sizeof(QBaseBucket*) ); numItems = 0; iterators = 0; // The caseSensitive and copyKey options don't make sense for // all dict types. switch ( (keytype = (uint)kt) ) { case StringKey: cases = caseSensitive; copyk = FALSE; break; case AsciiKey: cases = caseSensitive; copyk = copyKeys; break; default: cases = FALSE; copyk = FALSE; break; } } /*! Constructs a copy of \a dict. */ QGDict::QGDict( const QGDict & dict ) : QPtrCollection( dict ) { init( dict.vlen, (KeyType)dict.keytype, dict.cases, dict.copyk ); QGDictIterator it( dict ); while ( it.get() ) { // copy from other dict switch ( keytype ) { case StringKey: look_string( it.getKeyString(), it.get(), op_insert ); break; case AsciiKey: look_ascii( it.getKeyAscii(), it.get(), op_insert ); break; case IntKey: look_int( it.getKeyInt(), it.get(), op_insert ); break; case PtrKey: look_ptr( it.getKeyPtr(), it.get(), op_insert ); break; } ++it; } } /*! Removes all items from the dictionary and destroys it. */ QGDict::~QGDict() { clear(); // delete everything delete [] vec; if ( !iterators ) // no iterators for this dict return; QGDictIterator *i = iterators->first(); while ( i ) { // notify all iterators that i->dict = 0; // this dict is deleted i = iterators->next(); } delete iterators; } /*! Assigns \a dict to this dictionary. */ QGDict &QGDict::operator=( const QGDict &dict ) { if ( &dict == this ) return *this; clear(); QGDictIterator it( dict ); while ( it.get() ) { // copy from other dict switch ( keytype ) { case StringKey: look_string( it.getKeyString(), it.get(), op_insert ); break; case AsciiKey: look_ascii( it.getKeyAscii(), it.get(), op_insert ); break; case IntKey: look_int( it.getKeyInt(), it.get(), op_insert ); break; case PtrKey: look_ptr( it.getKeyPtr(), it.get(), op_insert ); break; } ++it; } return *this; } /*! \fn uint QGDict::count() const Returns the number of items in the dictionary. */ /*! \fn uint QGDict::size() const Returns the size of the hash array. */ /*! The do-it-all function; \a op is one of op_find, op_insert, op_replace. The key is \a key and the item is \a d. */ QPtrCollection::Item QGDict::look_string( const QString &key, QPtrCollection::Item d, int op ) { QStringBucket *n = 0; int index = hashKeyString(key) % vlen; if ( op == op_find ) { // find if ( cases ) { n = (QStringBucket*)vec[index]; while( n != 0 ) { if ( key == n->getKey() ) return n->getData(); // item found n = (QStringBucket*)n->getNext(); } } else { QString k = key.lower(); n = (QStringBucket*)vec[index]; while( n != 0 ) { if ( k == n->getKey().lower() ) return n->getData(); // item found n = (QStringBucket*)n->getNext(); } } return 0; // not found } if ( op == op_replace ) { // replace if ( vec[index] != 0 ) // maybe something there remove_string( key ); } // op_insert or op_replace n = new QStringBucket(key,newItem(d),vec[index]); Q_CHECK_PTR( n ); #if defined(QT_CHECK_NULL) if ( n->getData() == 0 ) qWarning( "QDict: Cannot insert null item" ); #endif vec[index] = n; numItems++; return n->getData(); } QPtrCollection::Item QGDict::look_ascii( const char *key, QPtrCollection::Item d, int op ) { QAsciiBucket *n; int index = hashKeyAscii(key) % vlen; if ( op == op_find ) { // find if ( cases ) { for ( n=(QAsciiBucket*)vec[index]; n; n=(QAsciiBucket*)n->getNext() ) { if ( qstrcmp(n->getKey(),key) == 0 ) return n->getData(); // item found } } else { for ( n=(QAsciiBucket*)vec[index]; n; n=(QAsciiBucket*)n->getNext() ) { if ( qstricmp(n->getKey(),key) == 0 ) return n->getData(); // item found } } return 0; // not found } if ( op == op_replace ) { // replace if ( vec[index] != 0 ) // maybe something there remove_ascii( key ); } // op_insert or op_replace n = new QAsciiBucket(copyk ? qstrdup(key) : key,newItem(d),vec[index]); Q_CHECK_PTR( n ); #if defined(QT_CHECK_NULL) if ( n->getData() == 0 ) qWarning( "QAsciiDict: Cannot insert null item" ); #endif vec[index] = n; numItems++; return n->getData(); |