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 static bool compare(const QChar *lhs, const QChar *rhs, int length);
81 static inline bool compare(const QChar *lhs, const char *rhs, int length);
82 static inline bool compare(const char *lhs, const char *rhs, int length);
84 friend class QHashedStringRef;
85 friend class QStringHashNode;
87 void computeHash() const;
88 mutable quint32 m_hash;
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 QStringRef &);
118 inline QHashedStringRef(const QChar *, int);
119 inline QHashedStringRef(const QChar *, int, quint32);
120 inline QHashedStringRef(const QHashedString &);
121 inline QHashedStringRef(const QHashedStringRef &);
122 inline QHashedStringRef &operator=(const QHashedStringRef &);
124 inline bool operator==(const QString &string) const;
125 inline bool operator==(const QHashedString &string) const;
126 inline bool operator==(const QHashedStringRef &string) const;
127 inline bool operator!=(const QString &string) const;
128 inline bool operator!=(const QHashedString &string) const;
129 inline bool operator!=(const QHashedStringRef &string) const;
131 inline quint32 hash() const;
133 inline const QChar &at(int) const;
134 inline const QChar *constData() const;
135 bool startsWith(const QString &) const;
136 bool endsWith(const QString &) const;
137 QHashedStringRef mid(int, int) const;
139 inline bool isEmpty() const;
140 inline int length() const;
141 inline bool startsWithUpper() const;
143 QString toString() const;
145 inline int utf8length() const;
146 QByteArray toUtf8() const;
147 void writeUtf8(char *) const;
149 friend class QHashedString;
151 void computeHash() const;
152 void computeUtf8Length() const;
156 mutable int m_utf8length;
157 mutable quint32 m_hash;
160 class Q_AUTOTEST_EXPORT QHashedCStringRef
163 inline QHashedCStringRef();
164 inline QHashedCStringRef(const char *, int);
165 inline QHashedCStringRef(const char *, int, quint32);
166 inline QHashedCStringRef(const QHashedCStringRef &);
168 inline quint32 hash() const;
170 inline const char *constData() const;
171 inline int length() const;
173 void computeHash() const;
177 mutable quint32 m_hash;
180 class QStringHashData;
181 class Q_AUTOTEST_EXPORT QStringHashNode
185 : nlist(0), next(0), length(0), hash(0), pooled(0), ckey(0), ukey(0), symbolId()
189 QStringHashNode(const QHashedString &key)
190 : nlist(0), next(0), length(key.length()), hash(key.hash()), pooled(0), ckey(0), key(key),
191 ukey(key.constData()), symbolId(0) {
194 QStringHashNode(const QHashedCStringRef &key)
195 : nlist(0), next(0), length(key.length()), hash(key.hash()), pooled(0), ckey(key.constData()),
196 ukey(0), symbolId(0) {
199 QStringHashNode(const QStringHashNode &o)
200 : nlist(0), next(0), length(o.length), hash(o.hash), pooled(0), ckey(o.ckey), key(o.key),
201 ukey(o.ukey), symbolId(o.symbolId) {
204 QStringHashNode *nlist;
205 QStringHashNode *next;
216 inline bool equals(v8::Handle<v8::String> string) {
217 return ckey?string->Equals((char*)ckey, length):
218 string->Equals((uint16_t*)ukey, length);
221 inline bool symbolEquals(const QHashedV8String &string) {
222 Q_ASSERT(string.symbolId() != 0);
223 return length == string.length() && hash == string.hash() &&
224 (string.symbolId() == symbolId || equals(string.string()));
227 inline bool equals(const QHashedV8String &string) {
228 return length == string.length() && hash == string.hash() &&
229 equals(string.string());
232 inline bool equals(const QHashedStringRef &string) {
233 return length == string.length() &&
234 hash == string.hash() &&
235 (ckey?(QHashedString::compare(string.constData(), ckey, length)):
236 (QHashedString::compare(string.constData(), ukey, length)));
239 inline bool equals(const QHashedCStringRef &string) {
240 return length == string.length() &&
241 hash == string.hash() &&
242 (ckey?(QHashedString::compare(string.constData(), ckey, length)):
243 (QHashedString::compare(ukey, string.constData(), length)));
247 struct Q_AUTOTEST_EXPORT QStringHashData
251 : nodes(0), buckets(0), numBuckets(0), size(0), numBits(0) {}
253 QStringHashNode *nodes;
254 QStringHashNode **buckets;
259 void rehashToBits(short);
260 void rehashToSize(int);
263 QStringHashData(const QStringHashData &);
264 QStringHashData &operator=(const QStringHashData &);
267 template<class T, int SmallThreshold = 0>
268 class Q_AUTOTEST_EXPORT QStringHash
271 struct Node : public QStringHashNode {
272 Node(const QHashedString &key, const T &value) : QStringHashNode(key), value(value) {}
273 Node(const QHashedCStringRef &key, const T &value) : QStringHashNode(key), value(value) {}
274 Node(const Node &o) : QStringHashNode(o), value(o.value) {}
278 struct ReservedNodePool
280 ReservedNodePool() : count(0), used(0), nodes(0) {}
281 ~ReservedNodePool() { delete [] nodes; }
287 QStringHashData data;
288 ReservedNodePool *nodePool;
290 inline Node *findNode(const QString &) const;
291 inline Node *findNode(const QHashedString &) const;
292 inline Node *findNode(const QHashedStringRef &) const;
293 inline Node *findNode(const QHashedCStringRef &) const;
294 inline Node *findNode(const QHashedV8String &) const;
295 inline Node *findSymbolNode(const QHashedV8String &) const;
296 inline Node *createNode(const QHashedString &, const T &);
297 inline Node *createNode(const QHashedCStringRef &, const T &);
299 inline Node *takeNode(const QHashedString &key, const T &value);
300 inline Node *takeNode(const QHashedCStringRef &key, const T &value);
301 inline Node *takeNode(const Node &o);
303 inline void copy(const QStringHash<T,SmallThreshold> &);
305 inline QStringHash();
306 inline QStringHash(const QStringHash &);
307 inline ~QStringHash();
309 QStringHash &operator=(const QStringHash<T,SmallThreshold> &);
311 void copyAndReserve(const QStringHash<T,SmallThreshold> &other, int additionalReserve);
313 inline bool isEmpty() const;
315 inline int count() const;
317 inline void insert(const QString &, const T &);
318 inline void insert(const QHashedString &, const T &);
319 inline void insert(const QHashedStringRef &, const T &);
320 inline void insert(const QHashedCStringRef &, const T &);
322 inline T *value(const QString &) const;
323 inline T *value(const QHashedString &) const;
324 inline T *value(const QHashedStringRef &) const;
325 inline T *value(const QHashedV8String &) const;
326 inline T *value(const QHashedCStringRef &) const;
328 inline bool contains(const QString &) const;
329 inline bool contains(const QHashedString &) const;
330 inline bool contains(const QHashedStringRef &) const;
331 inline bool contains(const QHashedCStringRef &) const;
333 T &operator[](const QString &);
334 T &operator[](const QHashedString &);
335 T &operator[](const QHashedStringRef &);
336 T &operator[](const QHashedCStringRef &);
338 class ConstIterator {
340 ConstIterator() : n(0) {}
341 ConstIterator(Node *n) : n(n) {}
343 ConstIterator &operator++() { n = (Node *)n->nlist; return *this; }
344 bool operator==(const ConstIterator &o) const { return n == o.n; }
345 bool operator!=(const ConstIterator &o) const { return n != o.n; }
347 QHashedString key() const {
349 return QHashedString(QString::fromLatin1(n->ckey, n->length), n->hash);
351 return QHashedString(n->key, n->hash);
354 const T &value() const { return n->value; }
355 const T &operator*() const { return n->value; }
360 ConstIterator begin() const { return ConstIterator((Node *)data.nodes); }
361 ConstIterator end() const { return ConstIterator(); }
363 inline void reserve(int);
366 template<class T, int SmallThreshold>
367 QStringHash<T,SmallThreshold>::QStringHash()
372 template<class T, int SmallThreshold>
373 QStringHash<T,SmallThreshold>::QStringHash(const QStringHash<T,SmallThreshold> &other)
376 data.numBits = other.data.numBits;
377 data.size = other.data.size;
378 reserve(other.count());
382 template<class T, int SmallThreshold>
383 QStringHash<T,SmallThreshold> &QStringHash<T,SmallThreshold>::operator=(const QStringHash<T,SmallThreshold> &other)
390 data.numBits = other.data.numBits;
391 data.size = other.data.size;
392 reserve(other.count());
398 template<class T, int SmallThreshold>
399 void QStringHash<T,SmallThreshold>::copyAndReserve(const QStringHash<T,SmallThreshold> &other, int additionalReserve)
403 data.numBits = other.data.numBits;
404 data.size = other.data.size;;
405 reserve(other.count() + additionalReserve);
409 template<class T, int SmallThreshold>
410 QStringHash<T,SmallThreshold>::~QStringHash()
415 template<class T, int SmallThreshold>
416 void QStringHash<T,SmallThreshold>::clear()
418 // If all the nodes were allocated from the node pool, we
419 // don't need to clean them individually
420 if (!nodePool || data.size != nodePool->used) {
421 QStringHashNode *n = data.nodes;
425 if (!o->pooled) delete o;
428 if (nodePool) delete nodePool;
429 delete [] data.buckets;
440 template<class T, int SmallThreshold>
441 bool QStringHash<T,SmallThreshold>::isEmpty() const
443 return data.nodes == 0;
446 template<class T, int SmallThreshold>
447 int QStringHash<T,SmallThreshold>::count() const
452 template<class T, int SmallThreshold>
453 typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::takeNode(const QHashedString &key, const T &value)
455 if (nodePool && nodePool->used != nodePool->count) {
456 Node *rv = nodePool->nodes + nodePool->used++;
457 rv->length = key.length();
458 rv->hash = key.hash();
460 rv->ukey = rv->key.constData();
465 return new Node(key, value);
469 template<class T, int SmallThreshold>
470 typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::takeNode(const QHashedCStringRef &key, const T &value)
472 if (nodePool && nodePool->used != nodePool->count) {
473 Node *rv = nodePool->nodes + nodePool->used++;
474 rv->length = key.length();
475 rv->hash = key.hash();
476 rv->ckey = key.constData();
481 return new Node(key, value);
485 template<class T, int SmallThreshold>
486 typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::takeNode(const Node &o)
488 if (nodePool && nodePool->used != nodePool->count) {
489 Node *rv = nodePool->nodes + nodePool->used++;
490 rv->length = o.length;
496 rv->symbolId = o.symbolId;
504 template<class T, int SmallThreshold>
505 void QStringHash<T,SmallThreshold>::copy(const QStringHash<T,SmallThreshold> &other)
507 Q_ASSERT(data.nodes == 0);
509 if (other.data.size <= SmallThreshold) {
510 QStringHashNode *n = other.data.nodes;
513 Node *mynode = takeNode(*o);
514 mynode->nlist = data.nodes;
515 mynode->next = data.nodes;
521 // Ensure buckets array is created
522 data.rehashToBits(data.numBits);
524 QStringHashNode *n = other.data.nodes;
527 Node *mynode = takeNode(*o);
528 mynode->nlist = data.nodes;
531 int bucket = mynode->hash % data.numBuckets;
532 mynode->next = data.buckets[bucket];
533 data.buckets[bucket] = mynode;
540 template<class T, int SmallThreshold>
541 typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::createNode(const QHashedString &key, const T &value)
543 Node *n = takeNode(key, value);
545 if (data.size < SmallThreshold) {
547 n->nlist = data.nodes;
548 n->next = data.nodes;
552 if (data.size >= data.numBuckets)
553 data.rehashToBits(data.numBits + 1);
555 n->nlist = data.nodes;
558 int bucket = key.hash() % data.numBuckets;
559 n->next = data.buckets[bucket];
560 data.buckets[bucket] = n;
568 template<class T, int SmallThreshold>
569 typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::createNode(const QHashedCStringRef &key, const T &value)
571 Node *n = takeNode(key, value);
573 if (data.size < SmallThreshold) {
575 n->nlist = data.nodes;
576 n->next = data.nodes;
580 if (data.size >= data.numBuckets)
581 data.rehashToBits(data.numBits + 1);
583 n->nlist = data.nodes;
586 int bucket = key.hash() % data.numBuckets;
587 n->next = data.buckets[bucket];
588 data.buckets[bucket] = n;
596 template<class T, int SmallThreshold>
597 void QStringHash<T,SmallThreshold>::insert(const QString &key, const T &value)
599 QHashedStringRef ch(key);
600 Node *n = findNode(key);
601 if (n) n->value = value;
602 else createNode(QHashedString(key, ch.hash()), value);
605 template<class T, int SmallThreshold>
606 void QStringHash<T,SmallThreshold>::insert(const QHashedString &key, const T &value)
608 Node *n = findNode(key);
609 if (n) n->value = value;
610 else createNode(key, value);
613 template<class T, int SmallThreshold>
614 void QStringHash<T,SmallThreshold>::insert(const QHashedStringRef &key, const T &value)
616 Node *n = findNode(key);
617 if (n) n->value = value;
618 else createNode(key, value);
621 template<class T, int SmallThreshold>
622 void QStringHash<T,SmallThreshold>::insert(const QHashedCStringRef &key, const T &value)
624 Node *n = findNode(key);
625 if (n) n->value = value;
626 else createNode(key, value);
629 template<class T, int SmallThreshold>
630 typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::findNode(const QString &string) const
632 return findNode(QHashedStringRef(string));
635 template<class T, int SmallThreshold>
636 typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::findNode(const QHashedString &string) const
638 return findNode(QHashedStringRef(string.constData(), string.length(), string.hash()));
641 template<class T, int SmallThreshold>
642 typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::findNode(const QHashedStringRef &string) const
644 QStringHashNode *node = (data.size <= SmallThreshold)?data.nodes:data.buckets[string.hash() % data.numBuckets];
645 while (node && !node->equals(string))
651 template<class T, int SmallThreshold>
652 typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::findNode(const QHashedCStringRef &string) const
654 QStringHashNode *node = (data.size <= SmallThreshold)?data.nodes:data.buckets[string.hash() % data.numBuckets];
655 while (node && !node->equals(string))
661 template<class T, int SmallThreshold>
662 typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::findNode(const QHashedV8String &string) const
664 QStringHashNode *node = (data.size <= SmallThreshold)?data.nodes:data.buckets[string.hash() % data.numBuckets];
665 while (node && !node->equals(string))
671 template<class T, int SmallThreshold>
672 typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::findSymbolNode(const QHashedV8String &string) const
674 Q_ASSERT(string.symbolId() != 0);
676 QStringHashNode *node = (data.size <= SmallThreshold)?data.nodes:data.buckets[string.hash() % data.numBuckets];
677 while (node && !node->symbolEquals(string))
681 node->symbolId = string.symbolId();
686 template<class T, int SmallThreshold>
687 T *QStringHash<T,SmallThreshold>::value(const QString &key) const
689 Node *n = findNode(key);
690 return n?&n->value:0;
693 template<class T, int SmallThreshold>
694 T *QStringHash<T,SmallThreshold>::value(const QHashedString &key) const
696 Node *n = findNode(key);
697 return n?&n->value:0;
700 template<class T, int SmallThreshold>
701 T *QStringHash<T,SmallThreshold>::value(const QHashedStringRef &key) const
703 Node *n = findNode(key);
704 return n?&n->value:0;
707 template<class T, int SmallThreshold>
708 T *QStringHash<T,SmallThreshold>::value(const QHashedCStringRef &key) const
710 Node *n = findNode(key);
711 return n?&n->value:0;
714 template<class T, int SmallThreshold>
715 T *QStringHash<T,SmallThreshold>::value(const QHashedV8String &string) const
717 Node *n = string.symbolId()?findSymbolNode(string):findNode(string);
718 return n?&n->value:0;
721 template<class T, int SmallThreshold>
722 bool QStringHash<T,SmallThreshold>::contains(const QString &s) const
724 return 0 != value(s);
727 template<class T, int SmallThreshold>
728 bool QStringHash<T,SmallThreshold>::contains(const QHashedString &s) const
730 return 0 != value(s);
733 template<class T, int SmallThreshold>
734 bool QStringHash<T,SmallThreshold>::contains(const QHashedStringRef &s) const
736 return 0 != value(s);
739 template<class T, int SmallThreshold>
740 bool QStringHash<T,SmallThreshold>::contains(const QHashedCStringRef &s) const
742 return 0 != value(s);
745 template<class T, int SmallThreshold>
746 T &QStringHash<T,SmallThreshold>::operator[](const QString &key)
748 QHashedStringRef cs(key);
749 Node *n = findNode(cs);
750 if (n) return n->value;
751 else return createNode(QHashedString(key, cs.hash()), T())->value;
754 template<class T, int SmallThreshold>
755 T &QStringHash<T,SmallThreshold>::operator[](const QHashedString &key)
757 Node *n = findNode(key);
758 if (n) return n->value;
759 else return createNode(key, T())->value;
762 template<class T, int SmallThreshold>
763 T &QStringHash<T,SmallThreshold>::operator[](const QHashedStringRef &key)
765 Node *n = findNode(key);
766 if (n) return n->value;
767 else return createNode(key, T())->value;
770 template<class T, int SmallThreshold>
771 T &QStringHash<T,SmallThreshold>::operator[](const QHashedCStringRef &key)
773 Node *n = findNode(key);
774 if (n) return n->value;
775 else return createNode(key, T())->value;
778 template<class T, int SmallThreshold>
779 void QStringHash<T,SmallThreshold>::reserve(int n)
781 if (nodePool || 0 == n)
783 nodePool = new ReservedNodePool;
786 nodePool->nodes = new Node[n];
788 if (n > SmallThreshold)
789 data.rehashToSize(n);
792 inline uint qHash(const QHashedString &string)
794 return uint(string.hash());
797 inline uint qHash(const QHashedStringRef &string)
799 return uint(string.hash());
802 QHashedString::QHashedString()
803 : QString(), m_hash(0)
807 QHashedString::QHashedString(const QString &string)
808 : QString(string), m_hash(0)
812 QHashedString::QHashedString(const QString &string, quint32 hash)
813 : QString(string), m_hash(hash)
817 QHashedString::QHashedString(const QHashedString &string)
818 : QString(string), m_hash(string.m_hash)
822 QHashedString &QHashedString::operator=(const QHashedString &string)
824 static_cast<QString &>(*this) = string;
825 m_hash = string.m_hash;
829 bool QHashedString::operator==(const QHashedString &string) const
831 return (string.m_hash == m_hash || !string.m_hash || !m_hash) &&
832 static_cast<const QString &>(*this) == static_cast<const QString &>(string);
835 bool QHashedString::operator==(const QHashedStringRef &string) const
837 return length() == string.m_length &&
838 (string.m_hash == m_hash || !string.m_hash || !m_hash) &&
839 QHashedString::compare(constData(), string.m_data, string.m_length);
842 quint32 QHashedString::hash() const
844 if (!m_hash) computeHash();
848 quint32 QHashedString::existingHash() const
853 bool QHashedString::isUpper(const QChar &qc)
855 ushort c = qc.unicode();
856 // Optimize for _, a-z and A-Z.
857 return ((c != '_' ) && (!(c >= 'a' && c <= 'z')) &&
858 ((c >= 'A' && c <= 'Z') || QChar::category(c) == QChar::Letter_Uppercase));
861 QHashedV8String::QHashedV8String()
865 QHashedV8String::QHashedV8String(v8::Handle<v8::String> string)
866 : m_hash(string->CompleteHash()), m_string(string)
868 Q_ASSERT(!m_string.IsEmpty());
871 QHashedV8String::QHashedV8String(const QHashedV8String &string)
872 : m_hash(string.m_hash), m_string(string.m_string)
876 QHashedV8String &QHashedV8String::operator=(const QHashedV8String &other)
878 m_hash = other.m_hash;
879 m_string = other.m_string;
883 bool QHashedV8String::operator==(const QHashedV8String &string)
885 return m_hash.hash == string.m_hash.hash && m_hash.length == string.m_hash.length &&
886 m_string.IsEmpty() == m_string.IsEmpty() &&
887 (m_string.IsEmpty() || m_string->StrictEquals(string.m_string));
890 quint32 QHashedV8String::hash() const
895 int QHashedV8String::length() const
897 return m_hash.length;
900 quint32 QHashedV8String::symbolId() const
902 return m_hash.symbol_id;
905 v8::Handle<v8::String> QHashedV8String::string() const
910 QHashedStringRef::QHashedStringRef()
911 : m_data(0), m_length(0), m_utf8length(-1), m_hash(0)
915 QHashedStringRef::QHashedStringRef(const QString &str)
916 : m_data(str.constData()), m_length(str.length()), m_utf8length(0), m_hash(0)
920 QHashedStringRef::QHashedStringRef(const QStringRef &str)
921 : m_data(str.constData()), m_length(str.length()), m_utf8length(0), m_hash(0)
925 QHashedStringRef::QHashedStringRef(const QChar *data, int length)
926 : m_data(data), m_length(length), m_utf8length(0), m_hash(0)
930 QHashedStringRef::QHashedStringRef(const QChar *data, int length, quint32 hash)
931 : m_data(data), m_length(length), m_utf8length(0), m_hash(hash)
935 QHashedStringRef::QHashedStringRef(const QHashedString &string)
936 : m_data(string.constData()), m_length(string.length()), m_utf8length(0), m_hash(string.m_hash)
940 QHashedStringRef::QHashedStringRef(const QHashedStringRef &string)
941 : m_data(string.m_data), m_length(string.m_length), m_utf8length(string.m_utf8length),
942 m_hash(string.m_hash)
946 QHashedStringRef &QHashedStringRef::operator=(const QHashedStringRef &o)
949 m_length = o.m_length;
950 m_utf8length = o.m_utf8length;
955 bool QHashedStringRef::operator==(const QString &string) const
957 return m_length == string.length() &&
958 QHashedString::compare(string.constData(), m_data, m_length);
961 bool QHashedStringRef::operator==(const QHashedString &string) const
963 return m_length == string.length() &&
964 (m_hash == string.m_hash || !m_hash || !string.m_hash) &&
965 QHashedString::compare(string.constData(), m_data, m_length);
968 bool QHashedStringRef::operator==(const QHashedStringRef &string) const
970 return m_length == string.m_length &&
971 (m_hash == string.m_hash || !m_hash || !string.m_hash) &&
972 QHashedString::compare(string.m_data, m_data, m_length);
975 bool QHashedStringRef::operator!=(const QString &string) const
977 return m_length != string.length() ||
978 !QHashedString::compare(string.constData(), m_data, m_length);
981 bool QHashedStringRef::operator!=(const QHashedString &string) const
983 return m_length != string.length() ||
984 (m_hash != string.m_hash && m_hash && string.m_hash) ||
985 !QHashedString::compare(string.constData(), m_data, m_length);
988 bool QHashedStringRef::operator!=(const QHashedStringRef &string) const
990 return m_length != string.m_length ||
991 (m_hash != string.m_hash && m_hash && string.m_hash) ||
992 QHashedString::compare(string.m_data, m_data, m_length);
995 const QChar &QHashedStringRef::at(int index) const
997 Q_ASSERT(index < m_length);
998 return m_data[index];
1001 const QChar *QHashedStringRef::constData() const
1006 bool QHashedStringRef::isEmpty() const
1008 return m_length == 0;
1011 int QHashedStringRef::length() const
1016 int QHashedStringRef::utf8length() const
1018 if (m_utf8length < m_length)
1019 computeUtf8Length();
1020 return m_utf8length;
1023 bool QHashedStringRef::startsWithUpper() const
1025 if (m_length < 1) return false;
1026 return QHashedString::isUpper(m_data[0]);
1029 quint32 QHashedStringRef::hash() const
1031 if (!m_hash) computeHash();
1035 QHashedCStringRef::QHashedCStringRef()
1036 : m_data(0), m_length(0), m_hash(0)
1040 QHashedCStringRef::QHashedCStringRef(const char *data, int length)
1041 : m_data(data), m_length(length), m_hash(0)
1045 QHashedCStringRef::QHashedCStringRef(const char *data, int length, quint32 hash)
1046 : m_data(data), m_length(length), m_hash(hash)
1050 QHashedCStringRef::QHashedCStringRef(const QHashedCStringRef &o)
1051 : m_data(o.m_data), m_length(o.m_length), m_hash(o.m_hash)
1055 quint32 QHashedCStringRef::hash() const
1057 if (!m_hash) computeHash();
1061 const char *QHashedCStringRef::constData() const
1066 int QHashedCStringRef::length() const
1071 bool QHashedString::compare(const QChar *lhs, const char *rhs, int length)
1073 Q_ASSERT(lhs && rhs);
1074 const quint16 *l = (const quint16*)lhs;
1076 if (*l++ != *rhs++) return false;
1080 bool QHashedString::compare(const char *lhs, const char *rhs, int length)
1082 Q_ASSERT(lhs && rhs);
1083 return 0 == ::memcmp(lhs, rhs, length);
1088 #endif // QHASHEDSTRING_P_H