Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qhashedstring_p.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant
4
5#ifndef QHASHEDSTRING_P_H
6#define QHASHEDSTRING_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <QtCore/qglobal.h>
20#include <QtCore/qstring.h>
21#include <private/qv4string_p.h>
22
23#if defined(Q_OS_QNX)
24#include <stdlib.h>
25#endif
26
27QT_BEGIN_NAMESPACE
28
29class QHashedStringRef;
30class Q_QML_EXPORT QHashedString : public QString
31{
32public:
33 inline QHashedString();
34 inline QHashedString(const QString &string);
35 inline QHashedString(const QString &string, quint32);
36 inline QHashedString(const QHashedString &string);
37
38 inline QHashedString &operator=(const QHashedString &string);
39 inline bool operator==(const QHashedString &string) const;
40 inline bool operator==(const QHashedStringRef &string) const;
41
42 inline quint32 hash() const;
43 inline quint32 existingHash() const;
44
45 static inline bool compare(const QChar *lhs, const char *rhs, int length);
46 static inline bool compare(const char *lhs, const char *rhs, int length);
47
48 static inline quint32 stringHash(const QChar* data, int length);
49 static inline quint32 stringHash(const char *data, int length);
50
51private:
52 friend class QHashedStringRef;
53 friend class QStringHashNode;
54
55 friend size_t qHash(const QHashedString &key, size_t seed = 0)
56 { return size_t{key.hash()} ^ seed; }
57
58 inline void computeHash() const;
59 mutable quint32 m_hash = 0;
60};
61
63class Q_QML_EXPORT QHashedStringRef
64{
65public:
66 inline QHashedStringRef();
67 inline QHashedStringRef(const QString &);
68 inline QHashedStringRef(QStringView);
69 inline QHashedStringRef(const QChar *, int);
70 inline QHashedStringRef(const QChar *, int, quint32);
71 inline QHashedStringRef(const QHashedString &);
72 inline QHashedStringRef(const QHashedStringRef &);
73 inline QHashedStringRef &operator=(const QHashedStringRef &);
74
75 inline bool operator==(const QString &string) const;
76 inline bool operator==(const QHashedString &string) const;
77 inline bool operator==(const QHashedStringRef &string) const;
78 inline bool operator==(const QHashedCStringRef &string) const;
79 inline bool operator!=(const QString &string) const;
80 inline bool operator!=(const QHashedString &string) const;
81 inline bool operator!=(const QHashedStringRef &string) const;
82 inline bool operator!=(const QHashedCStringRef &string) const;
83
84 inline quint32 hash() const;
85
86 inline QChar *data();
87 inline const QChar &at(int) const;
88 inline const QChar *constData() const;
89 bool startsWith(const QString &) const;
90 bool endsWith(const QString &) const;
91 int indexOf(const QChar &, int from=0) const;
92 QHashedStringRef mid(int, int) const;
93 QList<QHashedStringRef> split(const QChar sep) const;
94
95 inline bool isEmpty() const;
96 inline int length() const;
97 inline bool startsWithUpper() const;
98
99 QString toString() const;
100
101 inline bool isLatin1() const;
102
103private:
104 friend class QHashedString;
105
106 friend size_t qHash(const QHashedStringRef &key, size_t seed = 0)
107 { return size_t{key.hash()} ^ seed; }
108
109 inline void computeHash() const;
110
111 const QChar *m_data = nullptr;
112 int m_length = 0;
113 mutable quint32 m_hash = 0;
114};
115
117{
118public:
119 inline QHashedCStringRef();
120 inline QHashedCStringRef(const char *, int);
121 inline QHashedCStringRef(const char *, int, quint32);
122 inline QHashedCStringRef(const QHashedCStringRef &);
123
124 inline quint32 hash() const;
125
126 inline const char *constData() const;
127 inline int length() const;
128
129 Q_AUTOTEST_EXPORT QString toUtf16() const;
130 inline int utf16length() const;
131 inline void writeUtf16(QChar *) const;
132 inline void writeUtf16(quint16 *) const;
133private:
134 friend class QHashedStringRef;
135
136 inline void computeHash() const;
137
138 const char *m_data = nullptr;
139 int m_length = 0;
140 mutable quint32 m_hash = 0;
141};
142
143QHashedString::QHashedString()
144: QString()
145{
146}
147
148QHashedString::QHashedString(const QString &string)
149: QString(string), m_hash(0)
150{
151}
152
153QHashedString::QHashedString(const QString &string, quint32 hash)
154: QString(string), m_hash(hash)
155{
156}
157
158QHashedString::QHashedString(const QHashedString &string)
159: QString(string), m_hash(string.m_hash)
160{
161}
162
163QHashedString &QHashedString::operator=(const QHashedString &string)
164{
165 static_cast<QString &>(*this) = string;
166 m_hash = string.m_hash;
167 return *this;
168}
169
170bool QHashedString::operator==(const QHashedString &string) const
171{
172 return (string.m_hash == m_hash || !string.m_hash || !m_hash) &&
173 static_cast<const QString &>(*this) == static_cast<const QString &>(string);
174}
175
176bool QHashedString::operator==(const QHashedStringRef &string) const
177{
178 if (m_hash && string.m_hash && m_hash != string.m_hash)
179 return false;
180 QStringView otherView {string.m_data, string.m_length};
181 return static_cast<const QString &>(*this) == otherView;
182}
183
184quint32 QHashedString::hash() const
185{
186 if (!m_hash) computeHash();
187 return m_hash;
188}
189
190quint32 QHashedString::existingHash() const
191{
192 return m_hash;
193}
194
195QHashedStringRef::QHashedStringRef()
196{
197}
198
199// QHashedStringRef is meant for identifiers, property names, etc.
200// Those should alsways be smaller than std::numeric_limits<int>::max())
201QHashedStringRef::QHashedStringRef(const QString &str)
202: m_data(str.constData()), m_length(int(str.size())), m_hash(0)
203{
204 Q_ASSERT(str.size() <= std::numeric_limits<int>::max());
205}
206
207QHashedStringRef::QHashedStringRef(QStringView str)
208: m_data(str.constData()), m_length(int(str.size())), m_hash(0)
209{
210 Q_ASSERT(str.size() <= std::numeric_limits<int>::max());
211}
212
213QHashedStringRef::QHashedStringRef(const QChar *data, int length)
214: m_data(data), m_length(length), m_hash(0)
215{
216}
217
218QHashedStringRef::QHashedStringRef(const QChar *data, int length, quint32 hash)
219: m_data(data), m_length(length), m_hash(hash)
220{
221}
222
223QHashedStringRef::QHashedStringRef(const QHashedString &string)
224: m_data(string.constData()), m_length(int(string.size())), m_hash(string.m_hash)
225{
226 Q_ASSERT(string.size() <= std::numeric_limits<int>::max());
227}
228
229QHashedStringRef::QHashedStringRef(const QHashedStringRef &string)
230: m_data(string.m_data), m_length(string.m_length), m_hash(string.m_hash)
231{
232}
233
234QHashedStringRef &QHashedStringRef::operator=(const QHashedStringRef &o)
235{
236 m_data = o.m_data;
237 m_length = o.m_length;
238 m_hash = o.m_hash;
239 return *this;
240}
241
242bool QHashedStringRef::operator==(const QString &string) const
243{
244 QStringView view {m_data, m_length};
245 return view == string;
246}
247
248bool QHashedStringRef::operator==(const QHashedString &string) const
249{
250 if (m_hash && string.m_hash && m_hash != string.m_hash)
251 return false;
252 QStringView view {m_data, m_length};
253 QStringView otherView {string.constData(), string.size()};
254 return view == otherView;
255}
256
257bool QHashedStringRef::operator==(const QHashedStringRef &string) const
258{
259 if (m_hash && string.m_hash && m_hash != string.m_hash)
260 return false;
261 QStringView view {m_data, m_length};
262 QStringView otherView {string.m_data, string.m_length};
263 return view == otherView;
264}
265
266bool QHashedStringRef::operator==(const QHashedCStringRef &string) const
267{
268 return m_length == string.m_length &&
269 (m_hash == string.m_hash || !m_hash || !string.m_hash) &&
270 QHashedString::compare(m_data, string.m_data, m_length);
271}
272
273bool QHashedStringRef::operator!=(const QString &string) const
274{
275 return !(*this == string);
276}
277
278bool QHashedStringRef::operator!=(const QHashedString &string) const
279{
280 return !(*this == string);
281}
282
283bool QHashedStringRef::operator!=(const QHashedStringRef &string) const
284{
285 return !(*this == string);
286}
287
288bool QHashedStringRef::operator!=(const QHashedCStringRef &string) const
289{
290 return !(*this == string);
291}
292
293QChar *QHashedStringRef::data()
294{
295 return const_cast<QChar *>(m_data);
296}
297
298const QChar &QHashedStringRef::at(int index) const
299{
300 Q_ASSERT(index < m_length);
301 return m_data[index];
302}
303
304const QChar *QHashedStringRef::constData() const
305{
306 return m_data;
307}
308
309bool QHashedStringRef::isEmpty() const
310{
311 return m_length == 0;
312}
313
314int QHashedStringRef::length() const
315{
316 return m_length;
317}
318
319bool QHashedStringRef::isLatin1() const
320{
321 for (int ii = 0; ii < m_length; ++ii)
322 if (m_data[ii].unicode() > 127) return false;
323 return true;
324}
325
326void QHashedStringRef::computeHash() const
327{
328 m_hash = QHashedString::stringHash(m_data, m_length);
329}
330
331bool QHashedStringRef::startsWithUpper() const
332{
333 if (m_length < 1) return false;
334 return m_data[0].isUpper();
335}
336
337quint32 QHashedStringRef::hash() const
338{
339 if (!m_hash) computeHash();
340 return m_hash;
341}
342
346
347QHashedCStringRef::QHashedCStringRef(const char *data, int length)
348: m_data(data), m_length(length), m_hash(0)
349{
350}
351
352QHashedCStringRef::QHashedCStringRef(const char *data, int length, quint32 hash)
353: m_data(data), m_length(length), m_hash(hash)
354{
355}
356
358: m_data(o.m_data), m_length(o.m_length), m_hash(o.m_hash)
359{
360}
361
363{
364 if (!m_hash) computeHash();
365 return m_hash;
366}
367
368const char *QHashedCStringRef::constData() const
369{
370 return m_data;
371}
372
374{
375 return m_length;
376}
377
379{
380 return m_length;
381}
382
383void QHashedCStringRef::writeUtf16(QChar *output) const
384{
385 writeUtf16((quint16 *)output);
386}
387
388void QHashedCStringRef::writeUtf16(quint16 *output) const
389{
390 int l = m_length;
391 const char *d = m_data;
392 while (l--)
393 *output++ = *d++;
394}
395
396void QHashedCStringRef::computeHash() const
397{
398 m_hash = QHashedString::stringHash(m_data, m_length);
399}
400
401bool QHashedString::compare(const QChar *lhs, const char *rhs, int length)
402{
403 Q_ASSERT(lhs && rhs);
404 const quint16 *l = (const quint16*)lhs;
405 while (length--)
406 if (*l++ != *rhs++) return false;
407 return true;
408}
409
410bool QHashedString::compare(const char *lhs, const char *rhs, int length)
411{
412 Q_ASSERT(lhs && rhs);
413 return 0 == ::memcmp(lhs, rhs, length);
414}
415
416
417quint32 QHashedString::stringHash(const QChar *data, int length)
418{
419 return QV4::String::createHashValue(data, length, nullptr);
420}
421
422quint32 QHashedString::stringHash(const char *data, int length)
423{
424 return QV4::String::createHashValue(data, length, nullptr);
425}
426
427void QHashedString::computeHash() const
428{
429 m_hash = stringHash(constData(), int(size()));
430}
431
432namespace QtPrivate {
433inline QString asString(const QHashedCStringRef &ref) { return ref.toUtf16(); }
434inline QString asString(const QHashedStringRef &ref) { return ref.toString(); }
435}
436
437QT_END_NAMESPACE
438
439#endif // QHASHEDSTRING_P_H
quint32 hash() const
QHashedCStringRef(const QHashedCStringRef &)
const char * constData() const
void writeUtf16(QChar *) const
int utf16length() const
QHashedCStringRef(const char *, int, quint32)
QHashedCStringRef(const char *, int)
Combined button and popup list for selecting options.
QString asString(const QHashedStringRef &ref)
QString asString(const QHashedCStringRef &ref)