1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #ifndef QHASHEDSTRING_P_H
43 #define QHASHEDSTRING_P_H
49 // This file is not part of the Qt API. It exists purely as an
50 // implementation detail. This header file may change from version to
51 // version without notice, or even be removed.
56 #include <QtCore/qglobal.h>
57 #include <QtCore/qstring.h>
58 #include <private/qv8_p.h>
62 class QHashedStringRef;
63 class Q_AUTOTEST_EXPORT QHashedString : public QString
66 inline QHashedString();
67 inline QHashedString(const QString &string);
68 inline QHashedString(const QString &string, quint32);
69 inline QHashedString(const QHashedString &string);
71 inline QHashedString &operator=(const QHashedString &string);
72 inline bool operator==(const QHashedString &string) const;
73 inline bool operator==(const QHashedStringRef &string) const;
75 inline quint32 hash() const;
76 inline quint32 existingHash() const;
78 static inline bool isUpper(const QChar &);
80 friend class QHashedStringRef;
81 friend class QStringHashNode;
83 void computeHash() const;
84 mutable quint32 m_hash;
86 static bool compare(const QChar *lhs, const QChar *rhs, int length);
87 static inline bool compare(const QChar *lhs, const char *rhs, int length);
88 static inline bool compare(const char *lhs, const char *rhs, int length);
91 class Q_AUTOTEST_EXPORT QHashedV8String
94 inline QHashedV8String();
95 explicit inline QHashedV8String(v8::Handle<v8::String>);
96 inline QHashedV8String(const QHashedV8String &string);
97 inline QHashedV8String &operator=(const QHashedV8String &other);
99 inline bool operator==(const QHashedV8String &string);
101 inline quint32 hash() const;
102 inline int length() const;
103 inline quint32 symbolId() const;
105 inline v8::Handle<v8::String> string() const;
108 v8::String::CompleteHashData m_hash;
109 v8::Handle<v8::String> m_string;
112 class Q_AUTOTEST_EXPORT QHashedStringRef
115 inline QHashedStringRef();
116 inline QHashedStringRef(const QString &);
117 inline QHashedStringRef(const QChar *, int);
118 inline QHashedStringRef(const QChar *, int, quint32);
119 inline QHashedStringRef(const QHashedString &);
120 inline QHashedStringRef(const QHashedStringRef &);
122 inline bool operator==(const QHashedString &string) const;
123 inline bool operator==(const QHashedStringRef &string) const;
125 inline quint32 hash() const;
127 inline const QChar *constData() const;
128 inline int length() const;
129 inline bool startsWithUpper() const;
132 friend class QHashedString;
134 void computeHash() const;
138 mutable quint32 m_hash;
141 class Q_AUTOTEST_EXPORT QHashedCStringRef
144 inline QHashedCStringRef();
145 inline QHashedCStringRef(const char *, int);
146 inline QHashedCStringRef(const char *, int, quint32);
147 inline QHashedCStringRef(const QHashedCStringRef &);
149 inline quint32 hash() const;
151 inline const char *constData() const;
152 inline int length() const;
154 void computeHash() const;
158 mutable quint32 m_hash;
161 class QStringHashData;
162 class Q_AUTOTEST_EXPORT QStringHashNode
166 : nlist(0), next(0), length(0), hash(0), pooled(0), ckey(0), symbolId()
170 QStringHashNode(const QHashedString &key)
171 : nlist(0), next(0), length(key.length()), hash(key.hash()), pooled(0), ckey(0), key(key), symbolId(0) {
174 QStringHashNode(const QHashedCStringRef &key)
175 : nlist(0), next(0), length(key.length()), hash(key.hash()), pooled(0), ckey(key.constData()), symbolId(0) {
178 QStringHashNode(const QStringHashNode &o)
179 : nlist(0), next(0), length(o.length), hash(o.hash), pooled(0), ckey(o.ckey), key(o.key), symbolId(o.symbolId) {
182 QStringHashNode *nlist;
183 QStringHashNode *next;
193 inline bool equals(v8::Handle<v8::String> string) {
194 return ckey?string->Equals((char*)ckey, length):
195 string->Equals((uint16_t*)key.constData(), length);
198 inline bool symbolEquals(const QHashedV8String &string) {
199 Q_ASSERT(string.symbolId() != 0);
200 return length == string.length() && hash == string.hash() &&
201 (string.symbolId() == symbolId || equals(string.string()));
204 inline bool equals(const QHashedV8String &string) {
205 return length == string.length() && hash == string.hash() &&
206 equals(string.string());
209 inline bool equals(const QHashedStringRef &string) {
210 return length == string.length() &&
211 hash == string.hash() &&
212 ckey?(QHashedString::compare(string.constData(), ckey, length)):
213 (QHashedString::compare(string.constData(), key.constData(), length));
216 inline bool equals(const QHashedCStringRef &string) {
217 return length == string.length() &&
218 hash == string.hash() &&
219 ckey?(QHashedString::compare(string.constData(), ckey, length)):
220 (QHashedString::compare(key.constData(), string.constData(), length));
224 struct Q_AUTOTEST_EXPORT QStringHashData
228 : nodes(0), buckets(0), numBuckets(0), size(0), numBits(0) {}
230 QStringHashNode *nodes;
231 QStringHashNode **buckets;
236 void rehashToBits(short);
237 void rehashToSize(int);
240 QStringHashData(const QStringHashData &);
241 QStringHashData &operator=(const QStringHashData &);
244 template<class T, int SmallThreshold = 0>
245 class Q_AUTOTEST_EXPORT QStringHash
248 struct Node : public QStringHashNode {
249 Node(const QHashedString &key, const T &value) : QStringHashNode(key), value(value) {}
250 Node(const QHashedCStringRef &key, const T &value) : QStringHashNode(key), value(value) {}
251 Node(const Node &o) : QStringHashNode(o), value(o.value) {}
255 struct ReservedNodePool
257 ReservedNodePool() : count(0), used(0), nodes(0) {}
258 ~ReservedNodePool() { delete [] nodes; }
264 QStringHashData data;
265 ReservedNodePool *nodePool;
267 inline Node *findNode(const QString &) const;
268 inline Node *findNode(const QHashedString &) const;
269 inline Node *findNode(const QHashedStringRef &) const;
270 inline Node *findNode(const QHashedCStringRef &) const;
271 inline Node *findNode(const QHashedV8String &) const;
272 inline Node *findSymbolNode(const QHashedV8String &) const;
273 inline Node *createNode(const QHashedString &, const T &);
274 inline Node *createNode(const QHashedCStringRef &, const T &);
276 inline Node *takeNode(const QHashedString &key, const T &value);
277 inline Node *takeNode(const QHashedCStringRef &key, const T &value);
278 inline Node *takeNode(const Node &o);
280 inline void copy(const QStringHash<T,SmallThreshold> &);
282 inline QStringHash();
283 inline QStringHash(const QStringHash &);
284 inline ~QStringHash();
286 QStringHash &operator=(const QStringHash<T,SmallThreshold> &);
288 void copyAndReserve(const QStringHash<T,SmallThreshold> &other, int additionalReserve);
290 inline bool isEmpty() const;
292 inline int count() const;
294 inline void insert(const QString &, const T &);
295 inline void insert(const QHashedString &, const T &);
296 inline void insert(const QHashedStringRef &, const T &);
297 inline void insert(const QHashedCStringRef &, const T &);
299 inline T *value(const QString &) const;
300 inline T *value(const QHashedString &) const;
301 inline T *value(const QHashedStringRef &) const;
302 inline T *value(const QHashedV8String &) const;
303 inline T *value(const QHashedCStringRef &) const;
305 inline bool contains(const QString &) const;
306 inline bool contains(const QHashedString &) const;
307 inline bool contains(const QHashedStringRef &) const;
308 inline bool contains(const QHashedCStringRef &) const;
310 T &operator[](const QString &);
311 T &operator[](const QHashedString &);
312 T &operator[](const QHashedStringRef &);
313 T &operator[](const QHashedCStringRef &);
315 class ConstIterator {
317 ConstIterator() : n(0) {}
318 ConstIterator(Node *n) : n(n) {}
320 ConstIterator &operator++() { n = (Node *)n->nlist; return *this; }
321 bool operator==(const ConstIterator &o) const { return n == o.n; }
322 bool operator!=(const ConstIterator &o) const { return n != o.n; }
324 QHashedString key() const {
326 return QHashedString(QString::fromLatin1(n->ckey, n->length), n->hash);
328 return QHashedString(n->key, n->hash);
331 const T &value() const { return n->value; }
332 const T &operator*() const { return n->value; }
337 ConstIterator begin() const { return ConstIterator((Node *)data.nodes); }
338 ConstIterator end() const { return ConstIterator(); }
340 inline void reserve(int);
343 template<class T, int SmallThreshold>
344 QStringHash<T,SmallThreshold>::QStringHash()
349 template<class T, int SmallThreshold>
350 QStringHash<T,SmallThreshold>::QStringHash(const QStringHash<T,SmallThreshold> &other)
353 data.numBits = other.data.numBits;
354 data.size = other.data.size;
355 reserve(other.count());
359 template<class T, int SmallThreshold>
360 QStringHash<T,SmallThreshold> &QStringHash<T,SmallThreshold>::operator=(const QStringHash<T,SmallThreshold> &other)
367 data.numBits = other.data.numBits;
368 data.size = other.data.size;
369 reserve(other.count());
375 template<class T, int SmallThreshold>
376 void QStringHash<T,SmallThreshold>::copyAndReserve(const QStringHash<T,SmallThreshold> &other, int additionalReserve)
380 data.numBits = other.data.numBits;
381 data.size = other.data.size;;
382 reserve(other.count() + additionalReserve);
386 template<class T, int SmallThreshold>
387 QStringHash<T,SmallThreshold>::~QStringHash()
392 template<class T, int SmallThreshold>
393 void QStringHash<T,SmallThreshold>::clear()
395 // If all the nodes were allocated from the node pool, we
396 // don't need to clean them individually
397 if (!nodePool || data.size != nodePool->used) {
398 QStringHashNode *n = data.nodes;
402 if (!o->pooled) delete o;
405 if (nodePool) delete nodePool;
406 delete [] data.buckets;
417 template<class T, int SmallThreshold>
418 bool QStringHash<T,SmallThreshold>::isEmpty() const
420 return data.nodes == 0;
423 template<class T, int SmallThreshold>
424 int QStringHash<T,SmallThreshold>::count() const
429 template<class T, int SmallThreshold>
430 typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::takeNode(const QHashedString &key, const T &value)
432 if (nodePool && nodePool->used != nodePool->count) {
433 Node *rv = nodePool->nodes + nodePool->used++;
434 rv->length = key.length();
435 rv->hash = key.hash();
441 return new Node(key, value);
445 template<class T, int SmallThreshold>
446 typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::takeNode(const QHashedCStringRef &key, const T &value)
448 if (nodePool && nodePool->used != nodePool->count) {
449 Node *rv = nodePool->nodes + nodePool->used++;
450 rv->length = key.length();
451 rv->hash = key.hash();
452 rv->ckey = key.constData();
457 return new Node(key, value);
461 template<class T, int SmallThreshold>
462 typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::takeNode(const Node &o)
464 if (nodePool && nodePool->used != nodePool->count) {
465 Node *rv = nodePool->nodes + nodePool->used++;
466 rv->length = o.length;
471 rv->symbolId = o.symbolId;
479 template<class T, int SmallThreshold>
480 void QStringHash<T,SmallThreshold>::copy(const QStringHash<T,SmallThreshold> &other)
482 Q_ASSERT(data.nodes == 0);
484 if (other.data.size <= SmallThreshold) {
485 QStringHashNode *n = other.data.nodes;
488 Node *mynode = takeNode(*o);
489 mynode->nlist = data.nodes;
490 mynode->next = data.nodes;
496 // Ensure buckets array is created
497 data.rehashToBits(data.numBits);
499 QStringHashNode *n = other.data.nodes;
502 Node *mynode = takeNode(*o);
503 mynode->nlist = data.nodes;
506 int bucket = mynode->hash % data.numBuckets;
507 mynode->next = data.buckets[bucket];
508 data.buckets[bucket] = mynode;
515 template<class T, int SmallThreshold>
516 typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::createNode(const QHashedString &key, const T &value)
518 Node *n = takeNode(key, value);
520 if (data.size < SmallThreshold) {
522 n->nlist = data.nodes;
523 n->next = data.nodes;
527 if (data.size >= data.numBuckets)
528 data.rehashToBits(data.numBits + 1);
530 n->nlist = data.nodes;
533 int bucket = key.hash() % data.numBuckets;
534 n->next = data.buckets[bucket];
535 data.buckets[bucket] = n;
543 template<class T, int SmallThreshold>
544 typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::createNode(const QHashedCStringRef &key, const T &value)
546 Node *n = takeNode(key, value);
548 if (data.size < SmallThreshold) {
550 n->nlist = data.nodes;
551 n->next = data.nodes;
555 if (data.size >= data.numBuckets)
556 data.rehashToBits(data.numBits + 1);
558 n->nlist = data.nodes;
561 int bucket = key.hash() % data.numBuckets;
562 n->next = data.buckets[bucket];
563 data.buckets[bucket] = n;
571 template<class T, int SmallThreshold>
572 void QStringHash<T,SmallThreshold>::insert(const QString &key, const T &value)
574 QHashedStringRef ch(key);
575 Node *n = findNode(key);
576 if (n) n->value = value;
577 else createNode(QHashedString(key, ch.hash()), value);
580 template<class T, int SmallThreshold>
581 void QStringHash<T,SmallThreshold>::insert(const QHashedString &key, const T &value)
583 Node *n = findNode(key);
584 if (n) n->value = value;
585 else createNode(key, value);
588 template<class T, int SmallThreshold>
589 void QStringHash<T,SmallThreshold>::insert(const QHashedStringRef &key, const T &value)
591 Node *n = findNode(key);
592 if (n) n->value = value;
593 else createNode(key, value);
596 template<class T, int SmallThreshold>
597 void QStringHash<T,SmallThreshold>::insert(const QHashedCStringRef &key, const T &value)
599 Node *n = findNode(key);
600 if (n) n->value = value;
601 else createNode(key, value);
604 template<class T, int SmallThreshold>
605 typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::findNode(const QString &string) const
607 return findNode(QHashedStringRef(string));
610 template<class T, int SmallThreshold>
611 typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::findNode(const QHashedString &string) const
613 return findNode(QHashedStringRef(string.constData(), string.length(), string.hash()));
616 template<class T, int SmallThreshold>
617 typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::findNode(const QHashedStringRef &string) const
619 QStringHashNode *node = (data.size <= SmallThreshold)?data.nodes:data.buckets[string.hash() % data.numBuckets];
620 while (node && !node->equals(string))
626 template<class T, int SmallThreshold>
627 typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::findNode(const QHashedCStringRef &string) const
629 QStringHashNode *node = (data.size <= SmallThreshold)?data.nodes:data.buckets[string.hash() % data.numBuckets];
630 while (node && !node->equals(string))
636 template<class T, int SmallThreshold>
637 typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::findNode(const QHashedV8String &string) const
639 QStringHashNode *node = (data.size <= SmallThreshold)?data.nodes:data.buckets[string.hash() % data.numBuckets];
640 while (node && !node->equals(string))
646 template<class T, int SmallThreshold>
647 typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::findSymbolNode(const QHashedV8String &string) const
649 Q_ASSERT(string.symbolId() != 0);
651 QStringHashNode *node = (data.size <= SmallThreshold)?data.nodes:data.buckets[string.hash() % data.numBuckets];
652 while (node && !node->symbolEquals(string))
656 node->symbolId = string.symbolId();
661 template<class T, int SmallThreshold>
662 T *QStringHash<T,SmallThreshold>::value(const QString &key) const
664 Node *n = findNode(key);
665 return n?&n->value:0;
668 template<class T, int SmallThreshold>
669 T *QStringHash<T,SmallThreshold>::value(const QHashedString &key) const
671 Node *n = findNode(key);
672 return n?&n->value:0;
675 template<class T, int SmallThreshold>
676 T *QStringHash<T,SmallThreshold>::value(const QHashedStringRef &key) const
678 Node *n = findNode(key);
679 return n?&n->value:0;
682 template<class T, int SmallThreshold>
683 T *QStringHash<T,SmallThreshold>::value(const QHashedCStringRef &key) const
685 Node *n = findNode(key);
686 return n?&n->value:0;
689 template<class T, int SmallThreshold>
690 T *QStringHash<T,SmallThreshold>::value(const QHashedV8String &string) const
692 Node *n = string.symbolId()?findSymbolNode(string):findNode(string);
693 return n?&n->value:0;
696 template<class T, int SmallThreshold>
697 bool QStringHash<T,SmallThreshold>::contains(const QString &s) const
699 return 0 != value(s);
702 template<class T, int SmallThreshold>
703 bool QStringHash<T,SmallThreshold>::contains(const QHashedString &s) const
705 return 0 != value(s);
708 template<class T, int SmallThreshold>
709 bool QStringHash<T,SmallThreshold>::contains(const QHashedStringRef &s) const
711 return 0 != value(s);
714 template<class T, int SmallThreshold>
715 bool QStringHash<T,SmallThreshold>::contains(const QHashedCStringRef &s) const
717 return 0 != value(s);
720 template<class T, int SmallThreshold>
721 T &QStringHash<T,SmallThreshold>::operator[](const QString &key)
723 QHashedStringRef cs(key);
724 Node *n = findNode(cs);
725 if (n) return n->value;
726 else return createNode(QHashedString(key, cs.hash()), T())->value;
729 template<class T, int SmallThreshold>
730 T &QStringHash<T,SmallThreshold>::operator[](const QHashedString &key)
732 Node *n = findNode(key);
733 if (n) return n->value;
734 else return createNode(key, T())->value;
737 template<class T, int SmallThreshold>
738 T &QStringHash<T,SmallThreshold>::operator[](const QHashedStringRef &key)
740 Node *n = findNode(key);
741 if (n) return n->value;
742 else return createNode(key, T())->value;
745 template<class T, int SmallThreshold>
746 T &QStringHash<T,SmallThreshold>::operator[](const QHashedCStringRef &key)
748 Node *n = findNode(key);
749 if (n) return n->value;
750 else return createNode(key, T())->value;
753 template<class T, int SmallThreshold>
754 void QStringHash<T,SmallThreshold>::reserve(int n)
756 if (nodePool || 0 == n)
758 nodePool = new ReservedNodePool;
761 nodePool->nodes = new Node[n];
763 if (n > SmallThreshold)
764 data.rehashToSize(n);
767 inline uint qHash(const QHashedString &string)
769 return uint(string.hash());
772 inline uint qHash(const QHashedStringRef &string)
774 return uint(string.hash());
777 QHashedString::QHashedString()
778 : QString(), m_hash(0)
782 QHashedString::QHashedString(const QString &string)
783 : QString(string), m_hash(0)
787 QHashedString::QHashedString(const QString &string, quint32 hash)
788 : QString(string), m_hash(hash)
792 QHashedString::QHashedString(const QHashedString &string)
793 : QString(string), m_hash(string.m_hash)
797 QHashedString &QHashedString::operator=(const QHashedString &string)
799 static_cast<QString &>(*this) = string;
800 m_hash = string.m_hash;
804 bool QHashedString::operator==(const QHashedString &string) const
806 return (string.m_hash == m_hash || !string.m_hash || !m_hash) &&
807 static_cast<const QString &>(*this) == static_cast<const QString &>(string);
810 bool QHashedString::operator==(const QHashedStringRef &string) const
812 return length() == string.m_length &&
813 (string.m_hash == m_hash || !string.m_hash || !m_hash) &&
814 QHashedString::compare(constData(), string.m_data, string.m_length);
817 quint32 QHashedString::hash() const
819 if (!m_hash) computeHash();
823 quint32 QHashedString::existingHash() const
828 bool QHashedString::isUpper(const QChar &qc)
830 ushort c = qc.unicode();
831 // Optimize for _, a-z and A-Z.
832 return ((c != '_' ) && (!(c >= 'a' && c <= 'z')) &&
833 ((c >= 'A' && c <= 'Z') || QChar::category(c) == QChar::Letter_Uppercase));
836 QHashedV8String::QHashedV8String()
840 QHashedV8String::QHashedV8String(v8::Handle<v8::String> string)
841 : m_hash(string->CompleteHash()), m_string(string)
843 Q_ASSERT(!m_string.IsEmpty());
846 QHashedV8String::QHashedV8String(const QHashedV8String &string)
847 : m_hash(string.m_hash), m_string(string.m_string)
851 QHashedV8String &QHashedV8String::operator=(const QHashedV8String &other)
853 m_hash = other.m_hash;
854 m_string = other.m_string;
858 bool QHashedV8String::operator==(const QHashedV8String &string)
860 return m_hash.hash == string.m_hash.hash && m_hash.length == string.m_hash.length &&
861 m_string.IsEmpty() == m_string.IsEmpty() &&
862 (m_string.IsEmpty() || m_string->StrictEquals(string.m_string));
865 quint32 QHashedV8String::hash() const
870 int QHashedV8String::length() const
872 return m_hash.length;
875 quint32 QHashedV8String::symbolId() const
877 return m_hash.symbol_id;
880 v8::Handle<v8::String> QHashedV8String::string() const
885 QHashedStringRef::QHashedStringRef()
886 : m_data(0), m_length(0), m_hash(0)
890 QHashedStringRef::QHashedStringRef(const QString &str)
891 : m_data(str.constData()), m_length(str.length()), m_hash(0)
895 QHashedStringRef::QHashedStringRef(const QChar *data, int length)
896 : m_data(data), m_length(length), m_hash(0)
900 QHashedStringRef::QHashedStringRef(const QChar *data, int length, quint32 hash)
901 : m_data(data), m_length(length), m_hash(hash)
905 QHashedStringRef::QHashedStringRef(const QHashedString &string)
906 : m_data(string.constData()), m_length(string.length()), m_hash(string.m_hash)
910 QHashedStringRef::QHashedStringRef(const QHashedStringRef &string)
911 : m_data(string.m_data), m_length(string.m_length), m_hash(string.m_hash)
915 bool QHashedStringRef::operator==(const QHashedString &string) const
917 return m_length == string.length() &&
918 (m_hash == string.m_hash || !m_hash || !string.m_hash) &&
919 QHashedString::compare(string.constData(), m_data, m_length);
922 bool QHashedStringRef::operator==(const QHashedStringRef &string) const
924 return m_length == string.m_length &&
925 (m_hash == string.m_hash || !m_hash || !string.m_hash) &&
926 QHashedString::compare(string.m_data, m_data, m_length);
929 const QChar *QHashedStringRef::constData() const
934 int QHashedStringRef::length() const
939 bool QHashedStringRef::startsWithUpper() const
941 if (m_length < 1) return false;
942 return QHashedString::isUpper(m_data[0]);
945 quint32 QHashedStringRef::hash() const
947 if (!m_hash) computeHash();
951 QHashedCStringRef::QHashedCStringRef()
952 : m_data(0), m_length(0), m_hash(0)
956 QHashedCStringRef::QHashedCStringRef(const char *data, int length)
957 : m_data(data), m_length(length), m_hash(0)
961 QHashedCStringRef::QHashedCStringRef(const char *data, int length, quint32 hash)
962 : m_data(data), m_length(length), m_hash(hash)
966 QHashedCStringRef::QHashedCStringRef(const QHashedCStringRef &o)
967 : m_data(o.m_data), m_length(o.m_length), m_hash(o.m_hash)
971 quint32 QHashedCStringRef::hash() const
973 if (!m_hash) computeHash();
977 const char *QHashedCStringRef::constData() const
982 int QHashedCStringRef::length() const
987 bool QHashedString::compare(const QChar *lhs, const char *rhs, int length)
989 Q_ASSERT(lhs && rhs);
990 const quint16 *l = (const quint16*)lhs;
992 if (*l++ != *rhs++) return false;
996 bool QHashedString::compare(const char *lhs, const char *rhs, int length)
998 Q_ASSERT(lhs && rhs);
999 return 0 == ::memcmp(lhs, rhs, length);
1004 #endif // QHASHEDSTRING_P_H