Qt 4.8
qstring.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qstringlist.h"
43 #include "qregexp.h"
44 #include "qunicodetables_p.h"
45 #ifndef QT_NO_TEXTCODEC
46 #include <qtextcodec.h>
47 #endif
48 #include <private/qutfcodec_p.h>
49 #include "qsimd_p.h"
50 #include <qdatastream.h>
51 #include <qlist.h>
52 #include "qlocale.h"
53 #include "qlocale_p.h"
54 #include "qstringmatcher.h"
55 #include "qvarlengtharray.h"
56 #include "qtools_p.h"
57 #include "qhash.h"
58 #include "qdebug.h"
59 #include "qendian.h"
60 #include "qmutex.h"
61 
62 #ifdef Q_OS_MAC
63 #include <private/qcore_mac_p.h>
64 #endif
65 
66 #include <private/qfunctions_p.h>
67 
68 #if defined(Q_OS_WINCE)
69 #include <windows.h>
70 #include <winnls.h>
71 #endif
72 
73 #ifdef Q_OS_SYMBIAN
74 #include <e32cmn.h>
75 #endif
76 
77 #include <limits.h>
78 #include <string.h>
79 #include <stdlib.h>
80 #include <stdio.h>
81 #include <stdarg.h>
82 
83 #ifdef truncate
84 #undef truncate
85 #endif
86 
87 #include "qchar.cpp"
88 #include "qstringmatcher.cpp"
89 
90 #ifndef LLONG_MAX
91 #define LLONG_MAX qint64_C(9223372036854775807)
92 #endif
93 #ifndef LLONG_MIN
94 #define LLONG_MIN (-LLONG_MAX - qint64_C(1))
95 #endif
96 #ifndef ULLONG_MAX
97 #define ULLONG_MAX quint64_C(18446744073709551615)
98 #endif
99 
101 
102 #ifndef QT_NO_TEXTCODEC
104 #endif
105 
106 #ifdef QT3_SUPPORT
107 static QHash<void *, QByteArray> *asciiCache = 0;
108 Q_GLOBAL_STATIC(QMutex, asciiCacheMutex)
109 
110 #endif
111 
112 #ifdef QT_USE_ICU
113 // qlocale_icu.cpp
114 extern bool qt_ucol_strcoll(const QChar *source, int sourceLength, const QChar *target, int targetLength, int *result);
115 #endif
116 
117 // internal
118 int qFindString(const QChar *haystack, int haystackLen, int from,
119  const QChar *needle, int needleLen, Qt::CaseSensitivity cs);
120 int qFindStringBoyerMoore(const QChar *haystack, int haystackLen, int from,
121  const QChar *needle, int needleLen, Qt::CaseSensitivity cs);
122 static inline int qt_last_index_of(const QChar *haystack, int haystackLen, const QChar &needle,
123  int from, Qt::CaseSensitivity cs);
124 static inline int qt_string_count(const QChar *haystack, int haystackLen,
125  const QChar *needle, int needleLen,
127 static inline int qt_string_count(const QChar *haystack, int haystackLen,
128  const QChar &needle, Qt::CaseSensitivity cs);
129 static inline int qt_find_latin1_string(const QChar *hay, int size, const QLatin1String &needle,
130  int from, Qt::CaseSensitivity cs);
131 static inline bool qt_starts_with(const QChar *haystack, int haystackLen,
132  const QChar *needle, int needleLen, Qt::CaseSensitivity cs);
133 static inline bool qt_starts_with(const QChar *haystack, int haystackLen,
134  const QLatin1String &needle, Qt::CaseSensitivity cs);
135 static inline bool qt_ends_with(const QChar *haystack, int haystackLen,
136  const QChar *needle, int needleLen, Qt::CaseSensitivity cs);
137 static inline bool qt_ends_with(const QChar *haystack, int haystackLen,
138  const QLatin1String &needle, Qt::CaseSensitivity cs);
139 
140 // Unicode case-insensitive comparison
141 static int ucstricmp(const ushort *a, const ushort *ae, const ushort *b, const ushort *be)
142 {
143  if (a == b)
144  return (ae - be);
145  if (a == 0)
146  return 1;
147  if (b == 0)
148  return -1;
149 
150  const ushort *e = ae;
151  if (be - b < ae - a)
152  e = a + (be - b);
153 
154  uint alast = 0;
155  uint blast = 0;
156  while (a < e) {
157 // qDebug() << hex << alast << blast;
158 // qDebug() << hex << "*a=" << *a << "alast=" << alast << "folded=" << foldCase (*a, alast);
159 // qDebug() << hex << "*b=" << *b << "blast=" << blast << "folded=" << foldCase (*b, blast);
160  int diff = foldCase(*a, alast) - foldCase(*b, blast);
161  if ((diff))
162  return diff;
163  ++a;
164  ++b;
165  }
166  if (a == ae) {
167  if (b == be)
168  return 0;
169  return -1;
170  }
171  return 1;
172 }
173 
174 // Case-insensitive comparison between a Unicode string and a QLatin1String
175 static int ucstricmp(const ushort *a, const ushort *ae, const uchar *b)
176 {
177  if (a == 0) {
178  if (b == 0)
179  return 0;
180  return 1;
181  }
182  if (b == 0)
183  return -1;
184 
185  while (a < ae && *b) {
186  int diff = foldCase(*a) - foldCase(*b);
187  if ((diff))
188  return diff;
189  ++a;
190  ++b;
191  }
192  if (a == ae) {
193  if (!*b)
194  return 0;
195  return -1;
196  }
197  return 1;
198 }
199 
200 // Unicode case-sensitive compare two same-sized strings
201 static int ucstrncmp(const QChar *a, const QChar *b, int l)
202 {
203  while (l-- && *a == *b)
204  a++,b++;
205  if (l==-1)
206  return 0;
207  return a->unicode() - b->unicode();
208 }
209 
210 // Unicode case-sensitive comparison
211 static int ucstrcmp(const QChar *a, int alen, const QChar *b, int blen)
212 {
213  if (a == b && alen == blen)
214  return 0;
215  int l = qMin(alen, blen);
216  int cmp = ucstrncmp(a, b, l);
217  return cmp ? cmp : (alen-blen);
218 }
219 
220 // Unicode case-insensitive compare two same-sized strings
221 static int ucstrnicmp(const ushort *a, const ushort *b, int l)
222 {
223  return ucstricmp(a, a + l, b, b + l);
224 }
225 
226 // Benchmarking indicates that doing memcmp is much slower than
227 // executing the comparison ourselves.
228 //
229 // The profiling was done on a population of calls to qMemEquals, generated
230 // during a run of the demo browser. The profile of the data (32-bit x86
231 // Linux) was:
232 //
233 // total number of comparisons: 21353
234 // longest string compared: 95
235 // average comparison length: 14.8786
236 // cache-line crosses: 5661 (13.3%)
237 // alignment histogram:
238 // 0xXXX0 = 512 (1.2%) strings, 0 (0.0%) of which same-aligned
239 // 0xXXX2 = 15087 (35.3%) strings, 5145 (34.1%) of which same-aligned
240 // 0xXXX4 = 525 (1.2%) strings, 0 (0.0%) of which same-aligned
241 // 0xXXX6 = 557 (1.3%) strings, 6 (1.1%) of which same-aligned
242 // 0xXXX8 = 509 (1.2%) strings, 0 (0.0%) of which same-aligned
243 // 0xXXXa = 24358 (57.0%) strings, 9901 (40.6%) of which same-aligned
244 // 0xXXXc = 557 (1.3%) strings, 0 (0.0%) of which same-aligned
245 // 0xXXXe = 601 (1.4%) strings, 15 (2.5%) of which same-aligned
246 // total = 42706 (100%) strings, 15067 (35.3%) of which same-aligned
247 //
248 // 92% of the strings have alignment of 2 or 10, which is due to malloc on
249 // 32-bit Linux returning values aligned to 8 bytes, and offsetof(array, QString::Data) == 18.
250 //
251 // The profile on 64-bit will be different since offsetof(array, QString::Data) == 26.
252 //
253 // The benchmark results were, for a Core-i7 @ 2.67 GHz 32-bit, compiled with -O3 -funroll-loops:
254 // 16-bit loads only: 872,301 CPU ticks [Qt 4.5 / memcmp]
255 // 32- and 16-bit loads: 773,362 CPU ticks [Qt 4.6]
256 // SSE2 "movdqu" 128-bit loads: 618,736 CPU ticks
257 // SSE3 "lddqu" 128-bit loads: 619,954 CPU ticks
258 // SSSE3 "palignr" corrections: 852,147 CPU ticks
259 // SSE4.2 "pcmpestrm": 738,702 CPU ticks
260 //
261 // The same benchmark on an Atom N450 @ 1.66 GHz, is:
262 // 16-bit loads only: 2,185,882 CPU ticks
263 // 32- and 16-bit loads: 1,805,060 CPU ticks
264 // SSE2 "movdqu" 128-bit loads: 2,529,843 CPU ticks
265 // SSE3 "lddqu" 128-bit loads: 2,514,858 CPU ticks
266 // SSSE3 "palignr" corrections: 2,160,325 CPU ticks
267 // SSE4.2 not available
268 //
269 // The conclusion we reach is that alignment the SSE2 unaligned code can gain
270 // 20% improvement in performance in some systems, but suffers a penalty due
271 // to the unaligned loads on others.
272 
273 static bool qMemEquals(const quint16 *a, const quint16 *b, int length)
274 {
275  if (a == b || !length)
276  return true;
277 
278  register union {
279  const quint16 *w;
280  const quint32 *d;
281  quintptr value;
282  } sa, sb;
283  sa.w = a;
284  sb.w = b;
285 
286  // check alignment
287  if ((sa.value & 2) == (sb.value & 2)) {
288  // both addresses have the same alignment
289  if (sa.value & 2) {
290  // both addresses are not aligned to 4-bytes boundaries
291  // compare the first character
292  if (*sa.w != *sb.w)
293  return false;
294  --length;
295  ++sa.w;
296  ++sb.w;
297 
298  // now both addresses are 4-bytes aligned
299  }
300 
301  // both addresses are 4-bytes aligned
302  // do a fast 32-bit comparison
303  register const quint32 *e = sa.d + (length >> 1);
304  for ( ; sa.d != e; ++sa.d, ++sb.d) {
305  if (*sa.d != *sb.d)
306  return false;
307  }
308 
309  // do we have a tail?
310  return (length & 1) ? *sa.w == *sb.w : true;
311  } else {
312  // one of the addresses isn't 4-byte aligned but the other is
313  register const quint16 *e = sa.w + length;
314  for ( ; sa.w != e; ++sa.w, ++sb.w) {
315  if (*sa.w != *sb.w)
316  return false;
317  }
318  }
319  return true;
320 }
321 
333 static int findChar(const QChar *str, int len, QChar ch, int from,
335 {
336  const ushort *s = (const ushort *)str;
337  ushort c = ch.unicode();
338  if (from < 0)
339  from = qMax(from + len, 0);
340  if (from < len) {
341  const ushort *n = s + from - 1;
342  const ushort *e = s + len;
343  if (cs == Qt::CaseSensitive) {
344  while (++n != e)
345  if (*n == c)
346  return n - s;
347  } else {
348  c = foldCase(c);
349  while (++n != e)
350  if (foldCase(*n) == c)
351  return n - s;
352  }
353  }
354  return -1;
355 }
356 
357 #define REHASH(a) \
358  if (sl_minus_1 < (int)sizeof(int) * CHAR_BIT) \
359  hashHaystack -= (a) << sl_minus_1; \
360  hashHaystack <<= 1
361 
362 inline bool qIsUpper(char ch)
363 {
364  return ch >= 'A' && ch <= 'Z';
365 }
366 
367 inline bool qIsDigit(char ch)
368 {
369  return ch >= '0' && ch <= '9';
370 }
371 
372 inline char qToLower(char ch)
373 {
374  if (ch >= 'A' && ch <= 'Z')
375  return ch - 'A' + 'a';
376  else
377  return ch;
378 }
379 
380 const QString::Null QString::null = { };
381 
818  0, 0, shared_null.array, 0, 0, 0, 0, 0, 0, {0} };
820  0, 0, shared_empty.array, 0, 0, 0, 0, 0, 0, {0} };
821 
822 int QString::grow(int size)
823 {
824  return qAllocMore(size * sizeof(QChar), sizeof(Data)) / sizeof(QChar);
825 }
826 
1019 QString QString::fromWCharArray(const wchar_t *string, int size)
1020 {
1021  if (sizeof(wchar_t) == sizeof(QChar)) {
1022  return fromUtf16((const ushort *)string, size);
1023  } else {
1024  return fromUcs4((uint *)string, size);
1025  }
1026 }
1027 
1047 template<typename T> int toUcs4_helper(const unsigned short *uc, int length, T *out)
1048 {
1049  int i = 0;
1050  for (; i < length; ++i) {
1051  uint u = uc[i];
1052  if (QChar::isHighSurrogate(u) && i < length-1) {
1053  ushort low = uc[i+1];
1054  if (QChar::isLowSurrogate(low)) {
1055  ++i;
1056  u = QChar::surrogateToUcs4(u, low);
1057  }
1058  }
1059  *out = T(u);
1060  ++out;
1061  }
1062  return i;
1063 }
1064 
1086 int QString::toWCharArray(wchar_t *array) const
1087 {
1088  if (sizeof(wchar_t) == sizeof(QChar)) {
1089  memcpy(array, utf16(), sizeof(wchar_t)*length());
1090  return length();
1091  } else {
1092  return toUcs4_helper<wchar_t>(utf16(), length(), array);
1093  }
1094 }
1095 
1119 {
1120  if (!unicode) {
1121  d = &shared_null;
1122  d->ref.ref();
1123  } else if (size <= 0) {
1124  d = &shared_empty;
1125  d->ref.ref();
1126  } else {
1127  d = (Data*) qMalloc(sizeof(Data)+size*sizeof(QChar));
1128  Q_CHECK_PTR(d);
1129  d->ref = 1;
1130  d->alloc = d->size = size;
1131  d->clean = d->asciiCache = d->simpletext = d->righttoleft = d->capacity = 0;
1132  d->data = d->array;
1133  memcpy(d->array, unicode, size * sizeof(QChar));
1134  d->array[size] = '\0';
1135  }
1136 }
1137 
1151 {
1152  if (!unicode) {
1153  d = &shared_null;
1154  d->ref.ref();
1155  } else {
1156  int size = 0;
1157  while (unicode[size] != 0)
1158  ++size;
1159  if (!size) {
1160  d = &shared_empty;
1161  d->ref.ref();
1162  } else {
1163  d = (Data*) qMalloc(sizeof(Data)+size*sizeof(QChar));
1164  Q_CHECK_PTR(d);
1165  d->ref = 1;
1166  d->alloc = d->size = size;
1167  d->clean = d->asciiCache = d->simpletext = d->righttoleft = d->capacity = 0;
1168  d->data = d->array;
1169  memcpy(d->array, unicode, size * sizeof(QChar));
1170  d->array[size] = '\0';
1171  }
1172  }
1173 }
1174 
1175 
1183 {
1184  if (size <= 0) {
1185  d = &shared_empty;
1186  d->ref.ref();
1187  } else {
1188  d = (Data*) qMalloc(sizeof(Data)+size*sizeof(QChar));
1189  Q_CHECK_PTR(d);
1190  d->ref = 1;
1191  d->alloc = d->size = size;
1192  d->clean = d->asciiCache = d->simpletext = d->righttoleft = d->capacity = 0;
1193  d->data = d->array;
1194  d->array[size] = '\0';
1195  ushort *i = d->array + size;
1196  ushort *b = d->array;
1197  const ushort value = ch.unicode();
1198  while (i != b)
1199  *--i = value;
1200  }
1201 }
1202 
1213 {
1214  d = (Data*) qMalloc(sizeof(Data)+size*sizeof(QChar));
1215  Q_CHECK_PTR(d);
1216  d->ref = 1;
1217  d->alloc = d->size = size;
1218  d->clean = d->asciiCache = d->simpletext = d->righttoleft = d->capacity = 0;
1219  d->data = d->array;
1220  d->array[size] = '\0';
1221 }
1222 
1237 {
1238  void *buf = qMalloc(sizeof(Data) + sizeof(QChar));
1239  Q_CHECK_PTR(buf);
1240  d = reinterpret_cast<Data *>(buf);
1241  d->ref = 1;
1242  d->alloc = d->size = 1;
1243  d->clean = d->asciiCache = d->simpletext = d->righttoleft = d->capacity = 0;
1244  d->data = d->array;
1245  d->array[0] = ch.unicode();
1246  d->array[1] = '\0';
1247 }
1248 
1310 // ### Qt 5: rename freeData() to avoid confusion. See task 197625.
1312 {
1313 #ifdef QT3_SUPPORT
1314  if (d->asciiCache) {
1315  QMutexLocker locker(asciiCacheMutex());
1316  Q_ASSERT(asciiCache);
1317  asciiCache->remove(d);
1318  }
1319 #endif
1320  qFree(d);
1321 }
1322 
1354 {
1355  if (size < 0)
1356  size = 0;
1357 
1358  if (size == 0 && !d->capacity) {
1359  Data *x = &shared_empty;
1360  x->ref.ref();
1361  if (!d->ref.deref())
1362  QString::free(d);
1363  d = x;
1364  } else {
1365  if (d->ref != 1 || size > d->alloc ||
1366  (!d->capacity && size < d->size && size < d->alloc >> 1))
1367  realloc(grow(size));
1368  if (d->alloc >= size) {
1369  d->size = size;
1370  if (d->data == d->array) {
1371  d->array[size] = '\0';
1372  }
1373  }
1374  }
1375 }
1376 
1436 // ### Qt 5: rename reallocData() to avoid confusion. 197625
1437 void QString::realloc(int alloc)
1438 {
1439  if (d->ref != 1 || d->data != d->array) {
1440  Data *x = static_cast<Data *>(qMalloc(sizeof(Data) + alloc * sizeof(QChar)));
1441  Q_CHECK_PTR(x);
1442  x->size = qMin(alloc, d->size);
1443  ::memcpy(x->array, d->data, x->size * sizeof(QChar));
1444  x->array[x->size] = 0;
1445  x->asciiCache = 0;
1446  x->ref = 1;
1447  x->alloc = alloc;
1448  x->clean = d->clean;
1449  x->simpletext = d->simpletext;
1450  x->righttoleft = d->righttoleft;
1451  x->capacity = d->capacity;
1452  x->data = x->array;
1453  if (!d->ref.deref())
1454  QString::free(d);
1455  d = x;
1456  } else {
1457 #ifdef QT3_SUPPORT
1458  if (d->asciiCache) {
1459  QMutexLocker locker(asciiCacheMutex());
1460  Q_ASSERT(asciiCache);
1461  asciiCache->remove(d);
1462  }
1463 #endif
1464  Data *p = static_cast<Data *>(qRealloc(d, sizeof(Data) + alloc * sizeof(QChar)));
1465  Q_CHECK_PTR(p);
1466  d = p;
1467  d->alloc = alloc;
1468  d->data = d->array;
1469  }
1470 }
1471 
1473 {
1474  realloc(d->size);
1475 }
1476 
1477 void QString::expand(int i)
1478 {
1479  int sz = d->size;
1480  resize(qMax(i + 1, sz));
1481  if (d->size - 1 > sz) {
1482  ushort *n = d->data + d->size - 1;
1483  ushort *e = d->data + sz;
1484  while (n != e)
1485  * --n = ' ';
1486  }
1487 }
1488 
1509 {
1510  other.d->ref.ref();
1511  if (!d->ref.deref())
1512  QString::free(d);
1513  d = other.d;
1514  return *this;
1515 }
1516 
1517 
1583 {
1584  return operator=(QString(ch));
1585 }
1586 
1617 {
1618  const uchar *s = (const uchar *)str.latin1();
1619  if (i < 0 || !s || !(*s))
1620  return *this;
1621 
1622  int len = qstrlen(str.latin1());
1623  expand(qMax(d->size, i) + len - 1);
1624 
1625  ::memmove(d->data + i + len, d->data + i, (d->size - i - len) * sizeof(QChar));
1626  for (int j = 0; j < len; ++j)
1627  d->data[i + j] = s[j];
1628  return *this;
1629 }
1630 
1639 {
1640  if (i < 0 || size <= 0)
1641  return *this;
1642 
1643  const ushort *s = (const ushort *)unicode;
1644  if (s >= d->data && s < d->data + d->alloc) {
1645  // Part of me - take a copy
1646  ushort *tmp = static_cast<ushort *>(qMalloc(size * sizeof(QChar)));
1647  Q_CHECK_PTR(tmp);
1648  memcpy(tmp, s, size * sizeof(QChar));
1649  insert(i, reinterpret_cast<const QChar *>(tmp), size);
1650  qFree(tmp);
1651  return *this;
1652  }
1653 
1654  expand(qMax(d->size, i) + size - 1);
1655 
1656  ::memmove(d->data + i + size, d->data + i, (d->size - i - size) * sizeof(QChar));
1657  memcpy(d->data + i, s, size * sizeof(QChar));
1658  return *this;
1659 }
1660 
1672 {
1673  if (i < 0)
1674  i += d->size;
1675  if (i < 0)
1676  return *this;
1677  expand(qMax(i, d->size));
1678  ::memmove(d->data + i + 1, d->data + i, (d->size - i) * sizeof(QChar));
1679  d->data[i] = ch.unicode();
1680  return *this;
1681 }
1682 
1702 {
1703  if (str.d != &shared_null) {
1704  if (d == &shared_null) {
1705  operator=(str);
1706  } else {
1707  if (d->ref != 1 || d->size + str.d->size > d->alloc)
1708  realloc(grow(d->size + str.d->size));
1709  memcpy(d->data + d->size, str.d->data, str.d->size * sizeof(QChar));
1710  d->size += str.d->size;
1711  d->data[d->size] = '\0';
1712  }
1713  }
1714  return *this;
1715 }
1716 
1726 {
1727  const uchar *s = (const uchar *)str.latin1();
1728  if (s) {
1729  int len = qstrlen((char *)s);
1730  if (d->ref != 1 || d->size + len > d->alloc)
1731  realloc(grow(d->size + len));
1732  ushort *i = d->data + d->size;
1733  while ((*i++ = *s++))
1734  ;
1735  d->size += len;
1736  }
1737  return *this;
1738 }
1739 
1778 {
1779  if (d->ref != 1 || d->size + 1 > d->alloc)
1780  realloc(grow(d->size + 1));
1781  d->data[d->size++] = ch.unicode();
1782  d->data[d->size] = '\0';
1783  return *this;
1784 }
1785 
1867 QString &QString::remove(int pos, int len)
1868 {
1869  if (pos < 0) // count from end of string
1870  pos += d->size;
1871  if (pos < 0 || pos >= d->size) {
1872  // range problems
1873  } else if (len >= d->size - pos) {
1874  resize(pos); // truncate
1875  } else if (len > 0) {
1876  detach();
1877  memmove(d->data + pos, d->data + pos + len,
1878  (d->size - pos - len + 1) * sizeof(ushort));
1879  d->size -= len;
1880  }
1881  return *this;
1882 }
1883 
1896 {
1897  if (str.d->size) {
1898  int i = 0;
1899  while ((i = indexOf(str, i, cs)) != -1)
1900  remove(i, str.d->size);
1901  }
1902  return *this;
1903 }
1904 
1921 {
1922  int i = 0;
1923  ushort c = ch.unicode();
1924  if (cs == Qt::CaseSensitive) {
1925  while (i < d->size)
1926  if (d->data[i] == ch)
1927  remove(i, 1);
1928  else
1929  i++;
1930  } else {
1931  c = foldCase(c);
1932  while (i < d->size)
1933  if (foldCase(d->data[i]) == c)
1934  remove(i, 1);
1935  else
1936  i++;
1937  }
1938  return *this;
1939 }
1940 
1970 QString &QString::replace(int pos, int len, const QString &after)
1971 {
1972  QString copy = after;
1973  return replace(pos, len, copy.constData(), copy.length());
1974 }
1975 
1983 QString &QString::replace(int pos, int len, const QChar *unicode, int size)
1984 {
1985  if (pos < 0 || pos > d->size)
1986  return *this;
1987  if (pos + len > d->size)
1988  len = d->size - pos;
1989 
1990  uint index = pos;
1991  replace_helper(&index, 1, len, unicode, size);
1992  return *this;
1993 }
1994 
2005 QString &QString::replace(int pos, int len, QChar after)
2006 {
2007  return replace(pos, len, &after, 1);
2008 }
2009 
2032 {
2033  return replace(before.constData(), before.size(), after.constData(), after.size(), cs);
2034 }
2035 
2039 void QString::replace_helper(uint *indices, int nIndices, int blen, const QChar *after, int alen)
2040 {
2041  // copy *after in case it lies inside our own d->data area
2042  // (which we could possibly invalidate via a realloc or corrupt via memcpy operations.)
2043  QChar *afterBuffer = const_cast<QChar *>(after);
2044  if (after >= reinterpret_cast<QChar *>(d->data) && after < reinterpret_cast<QChar *>(d->data) + d->size) {
2045  afterBuffer = static_cast<QChar *>(qMalloc(alen*sizeof(QChar)));
2046  Q_CHECK_PTR(afterBuffer);
2047  ::memcpy(afterBuffer, after, alen*sizeof(QChar));
2048  }
2049 
2050  QT_TRY {
2051  if (blen == alen) {
2052  // replace in place
2053  detach();
2054  for (int i = 0; i < nIndices; ++i)
2055  memcpy(d->data + indices[i], afterBuffer, alen * sizeof(QChar));
2056  } else if (alen < blen) {
2057  // replace from front
2058  detach();
2059  uint to = indices[0];
2060  if (alen)
2061  memcpy(d->data+to, after, alen*sizeof(QChar));
2062  to += alen;
2063  uint movestart = indices[0] + blen;
2064  for (int i = 1; i < nIndices; ++i) {
2065  int msize = indices[i] - movestart;
2066  if (msize > 0) {
2067  memmove(d->data + to, d->data + movestart, msize * sizeof(QChar));
2068  to += msize;
2069  }
2070  if (alen) {
2071  memcpy(d->data + to, afterBuffer, alen*sizeof(QChar));
2072  to += alen;
2073  }
2074  movestart = indices[i] + blen;
2075  }
2076  int msize = d->size - movestart;
2077  if (msize > 0)
2078  memmove(d->data + to, d->data + movestart, msize * sizeof(QChar));
2079  resize(d->size - nIndices*(blen-alen));
2080  } else {
2081  // replace from back
2082  int adjust = nIndices*(alen-blen);
2083  int newLen = d->size + adjust;
2084  int moveend = d->size;
2085  resize(newLen);
2086 
2087  while (nIndices) {
2088  --nIndices;
2089  int movestart = indices[nIndices] + blen;
2090  int insertstart = indices[nIndices] + nIndices*(alen-blen);
2091  int moveto = insertstart + alen;
2092  memmove(d->data + moveto, d->data + movestart,
2093  (moveend - movestart)*sizeof(QChar));
2094  memcpy(d->data + insertstart, afterBuffer, alen*sizeof(QChar));
2095  moveend = movestart-blen;
2096  }
2097  }
2098  } QT_CATCH(const std::bad_alloc &) {
2099  if (afterBuffer != after)
2100  qFree(afterBuffer);
2101  QT_RETHROW;
2102  }
2103  if (afterBuffer != after)
2104  qFree(afterBuffer);
2105 }
2106 
2121 QString &QString::replace(const QChar *before, int blen,
2122  const QChar *after, int alen,
2124 {
2125  if (d->size == 0) {
2126  if (blen)
2127  return *this;
2128  } else {
2129  if (cs == Qt::CaseSensitive && before == after && blen == alen)
2130  return *this;
2131  }
2132  if (alen == 0 && blen == 0)
2133  return *this;
2134 
2135  QStringMatcher matcher(before, blen, cs);
2136 
2137  int index = 0;
2138  while (1) {
2139  uint indices[1024];
2140  uint pos = 0;
2141  while (pos < 1023) {
2142  index = matcher.indexIn(*this, index);
2143  if (index == -1)
2144  break;
2145  indices[pos++] = index;
2146  index += blen;
2147  // avoid infinite loop
2148  if (!blen)
2149  index++;
2150  }
2151  if (!pos)
2152  break;
2153 
2154  replace_helper(indices, pos, blen, after, alen);
2155 
2156  if (index == -1)
2157  break;
2158  // index has to be adjusted in case we get back into the loop above.
2159  index += pos*(alen-blen);
2160  }
2161 
2162  return *this;
2163 }
2164 
2177 {
2178  if (after.d->size == 0)
2179  return remove(ch, cs);
2180 
2181  if (after.d->size == 1)
2182  return replace(ch, after.d->data[0], cs);
2183 
2184  if (d->size == 0)
2185  return *this;
2186 
2187  ushort cc = (cs == Qt::CaseSensitive ? ch.unicode() : ch.toCaseFolded().unicode());
2188 
2189  int index = 0;
2190  while (1) {
2191  uint indices[1024];
2192  uint pos = 0;
2193  if (cs == Qt::CaseSensitive) {
2194  while (pos < 1023 && index < d->size) {
2195  if (d->data[index] == cc)
2196  indices[pos++] = index;
2197  index++;
2198  }
2199  } else {
2200  while (pos < 1023 && index < d->size) {
2201  if (QChar::toCaseFolded(d->data[index]) == cc)
2202  indices[pos++] = index;
2203  index++;
2204  }
2205  }
2206  if (!pos)
2207  break;
2208 
2209  replace_helper(indices, pos, 1, after.constData(), after.d->size);
2210 
2211  if (index == -1)
2212  break;
2213  // index has to be adjusted in case we get back into the loop above.
2214  index += pos*(after.d->size - 1);
2215  }
2216  return *this;
2217 }
2218 
2231 {
2232  ushort a = after.unicode();
2233  ushort b = before.unicode();
2234  if (d->size) {
2235  detach();
2236  ushort *i = d->data;
2237  const ushort *e = i + d->size;
2238  if (cs == Qt::CaseSensitive) {
2239  for (; i != e; ++i)
2240  if (*i == b)
2241  *i = a;
2242  } else {
2243  b = foldCase(b);
2244  for (; i != e; ++i)
2245  if (foldCase(*i) == b)
2246  *i = a;
2247  }
2248  }
2249  return *this;
2250 }
2251 
2268  const QLatin1String &after,
2270 {
2271  int alen = qstrlen(after.latin1());
2272  QVarLengthArray<ushort> a(alen);
2273  for (int i = 0; i < alen; ++i)
2274  a[i] = (uchar)after.latin1()[i];
2275  int blen = qstrlen(before.latin1());
2276  QVarLengthArray<ushort> b(blen);
2277  for (int i = 0; i < blen; ++i)
2278  b[i] = (uchar)before.latin1()[i];
2279  return replace((const QChar *)b.data(), blen, (const QChar *)a.data(), alen, cs);
2280 }
2281 
2298  const QString &after,
2300 {
2301  int blen = qstrlen(before.latin1());
2302  QVarLengthArray<ushort> b(blen);
2303  for (int i = 0; i < blen; ++i)
2304  b[i] = (uchar)before.latin1()[i];
2305  return replace((const QChar *)b.data(), blen, after.constData(), after.d->size, cs);
2306 }
2307 
2324  const QLatin1String &after,
2326 {
2327  int alen = qstrlen(after.latin1());
2328  QVarLengthArray<ushort> a(alen);
2329  for (int i = 0; i < alen; ++i)
2330  a[i] = (uchar)after.latin1()[i];
2331  return replace(before.constData(), before.d->size, (const QChar *)a.data(), alen, cs);
2332 }
2333 
2350 {
2351  int alen = qstrlen(after.latin1());
2352  QVarLengthArray<ushort> a(alen);
2353  for (int i = 0; i < alen; ++i)
2354  a[i] = (uchar)after.latin1()[i];
2355  return replace(&c, 1, (const QChar *)a.data(), alen, cs);
2356 }
2357 
2358 
2368 bool QString::operator==(const QString &other) const
2369 {
2370  if (d->size != other.d->size)
2371  return false;
2372 
2373  return qMemEquals(d->data, other.d->data, d->size);
2374 }
2375 
2379 bool QString::operator==(const QLatin1String &other) const
2380 {
2381  const ushort *uc = d->data;
2382  const ushort *e = uc + d->size;
2383  const uchar *c = (uchar *)other.latin1();
2384 
2385  if (!c)
2386  return isEmpty();
2387 
2388  while (*c) {
2389  if (uc == e || *uc != *c)
2390  return false;
2391  ++uc;
2392  ++c;
2393  }
2394  return (uc == e);
2395 }
2396 
2436 bool QString::operator<(const QString &other) const
2437 {
2438  return ucstrcmp(constData(), length(), other.constData(), other.length()) < 0;
2439 }
2440 
2444 bool QString::operator<(const QLatin1String &other) const
2445 {
2446  const ushort *uc = d->data;
2447  const ushort *e = uc + d->size;
2448  const uchar *c = (uchar *) other.latin1();
2449 
2450  if (!c || *c == 0)
2451  return false;
2452 
2453  while (*c) {
2454  if (uc == e || *uc != *c)
2455  break;
2456  ++uc;
2457  ++c;
2458  }
2459  return (uc == e ? *c : *uc < *c);
2460 }
2461 
2558 bool QString::operator>(const QLatin1String &other) const
2559 {
2560  const ushort *uc = d->data;;
2561  const ushort *e = uc + d->size;
2562  const uchar *c = (uchar *) other.latin1();
2563 
2564  if (!c || *c == '\0')
2565  return !isEmpty();
2566 
2567  while (*c) {
2568  if (uc == e || *uc != *c)
2569  break;
2570  ++uc;
2571  ++c;
2572  }
2573  return (uc == e ? false : *uc > *c);
2574 }
2575 
2721 int QString::indexOf(const QString &str, int from, Qt::CaseSensitivity cs) const
2722 {
2723  return qFindString(unicode(), length(), from, str.unicode(), str.length(), cs);
2724 }
2725 
2748 int QString::indexOf(const QLatin1String &str, int from, Qt::CaseSensitivity cs) const
2749 {
2750  return qt_find_latin1_string(unicode(), size(), str, from, cs);
2751 }
2752 
2754  const QChar *haystack0, int haystackLen, int from,
2755  const QChar *needle0, int needleLen, Qt::CaseSensitivity cs)
2756 {
2757  const int l = haystackLen;
2758  const int sl = needleLen;
2759  if (from < 0)
2760  from += l;
2761  if (uint(sl + from) > (uint)l)
2762  return -1;
2763  if (!sl)
2764  return from;
2765  if (!l)
2766  return -1;
2767 
2768  if (sl == 1)
2769  return findChar(haystack0, haystackLen, needle0[0], from, cs);
2770 
2771  /*
2772  We use the Boyer-Moore algorithm in cases where the overhead
2773  for the skip table should pay off, otherwise we use a simple
2774  hash function.
2775  */
2776  if (l > 500 && sl > 5)
2777  return qFindStringBoyerMoore(haystack0, haystackLen, from,
2778  needle0, needleLen, cs);
2779 
2780  /*
2781  We use some hashing for efficiency's sake. Instead of
2782  comparing strings, we compare the hash value of str with that
2783  of a part of this QString. Only if that matches, we call
2784  ucstrncmp() or ucstrnicmp().
2785  */
2786  const ushort *needle = (const ushort *)needle0;
2787  const ushort *haystack = (const ushort *)haystack0 + from;
2788  const ushort *end = (const ushort *)haystack0 + (l-sl);
2789  const int sl_minus_1 = sl-1;
2790  int hashNeedle = 0, hashHaystack = 0, idx;
2791 
2792  if (cs == Qt::CaseSensitive) {
2793  for (idx = 0; idx < sl; ++idx) {
2794  hashNeedle = ((hashNeedle<<1) + needle[idx]);
2795  hashHaystack = ((hashHaystack<<1) + haystack[idx]);
2796  }
2797  hashHaystack -= haystack[sl_minus_1];
2798 
2799  while (haystack <= end) {
2800  hashHaystack += haystack[sl_minus_1];
2801  if (hashHaystack == hashNeedle
2802  && ucstrncmp((const QChar *)needle, (const QChar *)haystack, sl) == 0)
2803  return haystack - (const ushort *)haystack0;
2804 
2805  REHASH(*haystack);
2806  ++haystack;
2807  }
2808  } else {
2809  const ushort *haystack_start = (const ushort *)haystack0;
2810  for (idx = 0; idx < sl; ++idx) {
2811  hashNeedle = (hashNeedle<<1) + foldCase(needle + idx, needle);
2812  hashHaystack = (hashHaystack<<1) + foldCase(haystack + idx, haystack_start);
2813  }
2814  hashHaystack -= foldCase(haystack + sl_minus_1, haystack_start);
2815 
2816  while (haystack <= end) {
2817  hashHaystack += foldCase(haystack + sl_minus_1, haystack_start);
2818  if (hashHaystack == hashNeedle && ucstrnicmp(needle, haystack, sl) == 0)
2819  return haystack - (const ushort *)haystack0;
2820 
2821  REHASH(foldCase(haystack, haystack_start));
2822  ++haystack;
2823  }
2824  }
2825  return -1;
2826 }
2827 
2838 int QString::indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
2839 {
2840  return findChar(unicode(), length(), ch, from, cs);
2841 }
2842 
2858 int QString::indexOf(const QStringRef &str, int from, Qt::CaseSensitivity cs) const
2859 {
2860  return qFindString(unicode(), length(), from, str.unicode(), str.length(), cs);
2861 }
2862 
2863 static int lastIndexOfHelper(const ushort *haystack, int from, const ushort *needle, int sl, Qt::CaseSensitivity cs)
2864 {
2865  /*
2866  See indexOf() for explanations.
2867  */
2868 
2869  const ushort *end = haystack;
2870  haystack += from;
2871  const int sl_minus_1 = sl-1;
2872  const ushort *n = needle+sl_minus_1;
2873  const ushort *h = haystack+sl_minus_1;
2874  int hashNeedle = 0, hashHaystack = 0, idx;
2875 
2876  if (cs == Qt::CaseSensitive) {
2877  for (idx = 0; idx < sl; ++idx) {
2878  hashNeedle = ((hashNeedle<<1) + *(n-idx));
2879  hashHaystack = ((hashHaystack<<1) + *(h-idx));
2880  }
2881  hashHaystack -= *haystack;
2882 
2883  while (haystack >= end) {
2884  hashHaystack += *haystack;
2885  if (hashHaystack == hashNeedle
2886  && ucstrncmp((const QChar *)needle, (const QChar *)haystack, sl) == 0)
2887  return haystack - end;
2888  --haystack;
2889  REHASH(haystack[sl]);
2890  }
2891  } else {
2892  for (idx = 0; idx < sl; ++idx) {
2893  hashNeedle = ((hashNeedle<<1) + foldCase(n-idx, needle));
2894  hashHaystack = ((hashHaystack<<1) + foldCase(h-idx, end));
2895  }
2896  hashHaystack -= foldCase(haystack, end);
2897 
2898  while (haystack >= end) {
2899  hashHaystack += foldCase(haystack, end);
2900  if (hashHaystack == hashNeedle && ucstrnicmp(needle, haystack, sl) == 0)
2901  return haystack - end;
2902  --haystack;
2903  REHASH(foldCase(haystack + sl, end));
2904  }
2905  }
2906  return -1;
2907 }
2908 
2925 int QString::lastIndexOf(const QString &str, int from, Qt::CaseSensitivity cs) const
2926 {
2927  const int sl = str.d->size;
2928  if (sl == 1)
2929  return lastIndexOf(QChar(str.d->data[0]), from, cs);
2930 
2931  const int l = d->size;
2932  if (from < 0)
2933  from += l;
2934  int delta = l-sl;
2935  if (from == l && sl == 0)
2936  return from;
2937  if (from < 0 || from >= l || delta < 0)
2938  return -1;
2939  if (from > delta)
2940  from = delta;
2941 
2942  return lastIndexOfHelper(d->data, from, str.d->data, str.d->size, cs);
2943 }
2944 
2967 int QString::lastIndexOf(const QLatin1String &str, int from, Qt::CaseSensitivity cs) const
2968 {
2969  const int sl = qstrlen(str.latin1());
2970  if (sl == 1)
2971  return lastIndexOf(QLatin1Char(str.latin1()[0]), from, cs);
2972 
2973  const int l = d->size;
2974  if (from < 0)
2975  from += l;
2976  int delta = l-sl;
2977  if (from == l && sl == 0)
2978  return from;
2979  if (from < 0 || from >= l || delta < 0)
2980  return -1;
2981  if (from > delta)
2982  from = delta;
2983 
2985  for (int i = 0; i < sl; ++i)
2986  s[i] = str.latin1()[i];
2987 
2988  return lastIndexOfHelper(d->data, from, s.data(), sl, cs);
2989 }
2990 
3001 {
3002  return qt_last_index_of(unicode(), size(), ch, from, cs);
3003  }
3004 
3023 int QString::lastIndexOf(const QStringRef &str, int from, Qt::CaseSensitivity cs) const
3024 {
3025  const int sl = str.size();
3026  if (sl == 1)
3027  return lastIndexOf(str.at(0), from, cs);
3028 
3029  const int l = d->size;
3030  if (from < 0)
3031  from += l;
3032  int delta = l - sl;
3033  if (from == l && sl == 0)
3034  return from;
3035  if (from < 0 || from >= l || delta < 0)
3036  return -1;
3037  if (from > delta)
3038  from = delta;
3039 
3040  return lastIndexOfHelper(d->data, from, reinterpret_cast<const ushort*>(str.unicode()),
3041  str.size(), cs);
3042 }
3043 
3044 #ifndef QT_NO_REGEXP
3046 {
3047  int pos;
3048  int len;
3049  int no;
3050 };
3051 
3072 QString& QString::replace(const QRegExp &rx, const QString &after)
3073 {
3074  QRegExp rx2(rx);
3075 
3076  if (isEmpty() && rx2.indexIn(*this) == -1)
3077  return *this;
3078 
3079  realloc();
3080 
3081  int index = 0;
3082  int numCaptures = rx2.captureCount();
3083  int al = after.length();
3085 
3086  if (numCaptures > 0) {
3087  const QChar *uc = after.unicode();
3088  int numBackRefs = 0;
3089 
3090  for (int i = 0; i < al - 1; i++) {
3091  if (uc[i] == QLatin1Char('\\')) {
3092  int no = uc[i + 1].digitValue();
3093  if (no > 0 && no <= numCaptures)
3094  numBackRefs++;
3095  }
3096  }
3097 
3098  /*
3099  This is the harder case where we have back-references.
3100  */
3101  if (numBackRefs > 0) {
3102  QVarLengthArray<QStringCapture, 16> captures(numBackRefs);
3103  int j = 0;
3104 
3105  for (int i = 0; i < al - 1; i++) {
3106  if (uc[i] == QLatin1Char('\\')) {
3107  int no = uc[i + 1].digitValue();
3108  if (no > 0 && no <= numCaptures) {
3109  QStringCapture capture;
3110  capture.pos = i;
3111  capture.len = 2;
3112 
3113  if (i < al - 2) {
3114  int secondDigit = uc[i + 2].digitValue();
3115  if (secondDigit != -1 && ((no * 10) + secondDigit) <= numCaptures) {
3116  no = (no * 10) + secondDigit;
3117  ++capture.len;
3118  }
3119  }
3120 
3121  capture.no = no;
3122  captures[j++] = capture;
3123  }
3124  }
3125  }
3126 
3127  while (index <= length()) {
3128  index = rx2.indexIn(*this, index, caretMode);
3129  if (index == -1)
3130  break;
3131 
3132  QString after2(after);
3133  for (j = numBackRefs - 1; j >= 0; j--) {
3134  const QStringCapture &capture = captures[j];
3135  after2.replace(capture.pos, capture.len, rx2.cap(capture.no));
3136  }
3137 
3138  replace(index, rx2.matchedLength(), after2);
3139  index += after2.length();
3140 
3141  // avoid infinite loop on 0-length matches (e.g., QRegExp("[a-z]*"))
3142  if (rx2.matchedLength() == 0)
3143  ++index;
3144 
3145  caretMode = QRegExp::CaretWontMatch;
3146  }
3147  return *this;
3148  }
3149  }
3150 
3151  /*
3152  This is the simple and optimized case where we don't have
3153  back-references.
3154  */
3155  while (index != -1) {
3156  struct {
3157  int pos;
3158  int length;
3159  } replacements[2048];
3160 
3161  int pos = 0;
3162  int adjust = 0;
3163  while (pos < 2047) {
3164  index = rx2.indexIn(*this, index, caretMode);
3165  if (index == -1)
3166  break;
3167  int ml = rx2.matchedLength();
3168  replacements[pos].pos = index;
3169  replacements[pos++].length = ml;
3170  index += ml;
3171  adjust += al - ml;
3172  // avoid infinite loop
3173  if (!ml)
3174  index++;
3175  }
3176  if (!pos)
3177  break;
3178  replacements[pos].pos = d->size;
3179  int newlen = d->size + adjust;
3180 
3181  // to continue searching at the right position after we did
3182  // the first round of replacements
3183  if (index != -1)
3184  index += adjust;
3185  QString newstring;
3186  newstring.reserve(newlen + 1);
3187  QChar *newuc = newstring.data();
3188  QChar *uc = newuc;
3189  int copystart = 0;
3190  int i = 0;
3191  while (i < pos) {
3192  int copyend = replacements[i].pos;
3193  int size = copyend - copystart;
3194  memcpy(uc, d->data + copystart, size * sizeof(QChar));
3195  uc += size;
3196  memcpy(uc, after.d->data, al * sizeof(QChar));
3197  uc += al;
3198  copystart = copyend + replacements[i].length;
3199  i++;
3200  }
3201  memcpy(uc, d->data + copystart, (d->size - copystart) * sizeof(QChar));
3202  newstring.resize(newlen);
3203  *this = newstring;
3204  caretMode = QRegExp::CaretWontMatch;
3205  }
3206  return *this;
3207 }
3208 #endif
3209 
3220 int QString::count(const QString &str, Qt::CaseSensitivity cs) const
3221 {
3222  return qt_string_count(unicode(), size(), str.unicode(), str.size(), cs);
3223 }
3224 
3235 {
3236  return qt_string_count(unicode(), size(), ch, cs);
3237  }
3238 
3254 {
3255  return qt_string_count(unicode(), size(), str.unicode(), str.size(), cs);
3256 }
3257 
3258 
3327 #ifndef QT_NO_REGEXP
3328 
3342 int QString::indexOf(const QRegExp& rx, int from) const
3343 {
3344  QRegExp rx2(rx);
3345  return rx2.indexIn(*this, from);
3346 }
3347 
3366 int QString::indexOf(QRegExp& rx, int from) const
3367 {
3368  return rx.indexIn(*this, from);
3369 }
3370 
3385 int QString::lastIndexOf(const QRegExp& rx, int from) const
3386 {
3387  QRegExp rx2(rx);
3388  return rx2.lastIndexIn(*this, from);
3389 }
3390 
3409 int QString::lastIndexOf(QRegExp& rx, int from) const
3410 {
3411  return rx.lastIndexIn(*this, from);
3412 }
3413 
3429 int QString::count(const QRegExp& rx) const
3430 {
3431  QRegExp rx2(rx);
3432  int count = 0;
3433  int index = -1;
3434  int len = length();
3435  while (index < len - 1) { // count overlapping matches
3436  index = rx2.indexIn(*this, index + 1);
3437  if (index == -1)
3438  break;
3439  count++;
3440  }
3441  return count;
3442 }
3443 #endif // QT_NO_REGEXP
3444 
3526 QString QString::section(const QString &sep, int start, int end, SectionFlags flags) const
3527 {
3528  QStringList sections = split(sep, KeepEmptyParts,
3530  if (sections.isEmpty())
3531  return QString();
3532  if (!(flags & SectionSkipEmpty)) {
3533  if (start < 0)
3534  start += sections.count();
3535  if (end < 0)
3536  end += sections.count();
3537  } else {
3538  int skip = 0;
3539  for (int k=0; k<sections.size(); ++k) {
3540  if (sections.at(k).isEmpty())
3541  skip++;
3542  }
3543  if (start < 0)
3544  start += sections.count() - skip;
3545  if (end < 0)
3546  end += sections.count() - skip;
3547  }
3548  int x = 0;
3549  QString ret;
3550  int first_i = start, last_i = end;
3551  for (int i = 0; x <= end && i < sections.size(); ++i) {
3552  QString section = sections.at(i);
3553  const bool empty = section.isEmpty();
3554  if (x >= start) {
3555  if(x == start)
3556  first_i = i;
3557  if(x == end)
3558  last_i = i;
3559  if(x > start)
3560  ret += sep;
3561  ret += section;
3562  }
3563  if (!empty || !(flags & SectionSkipEmpty))
3564  x++;
3565  }
3566  if((flags & SectionIncludeLeadingSep) && first_i)
3567  ret.prepend(sep);
3568  if((flags & SectionIncludeTrailingSep) && last_i < sections.size()-1)
3569  ret += sep;
3570  return ret;
3571 }
3572 
3573 #ifndef QT_NO_REGEXP
3575 public:
3576  qt_section_chunk(int l, QString s) { length = l; string = s; }
3577  int length;
3579 };
3580 
3597 QString QString::section(const QRegExp &reg, int start, int end, SectionFlags flags) const
3598 {
3599  const QChar *uc = unicode();
3600  if(!uc)
3601  return QString();
3602 
3603  QRegExp sep(reg);
3605  : Qt::CaseSensitive);
3606 
3607  QList<qt_section_chunk> sections;
3608  int n = length(), m = 0, last_m = 0, last_len = 0;
3609  while ((m = sep.indexIn(*this, m)) != -1) {
3610  sections.append(qt_section_chunk(last_len, QString(uc + last_m, m - last_m)));
3611  last_m = m;
3612  last_len = sep.matchedLength();
3613  m += qMax(sep.matchedLength(), 1);
3614  }
3615  sections.append(qt_section_chunk(last_len, QString(uc + last_m, n - last_m)));
3616 
3617  if(start < 0)
3618  start += sections.count();
3619  if(end < 0)
3620  end += sections.count();
3621 
3622  QString ret;
3623  int x = 0;
3624  int first_i = start, last_i = end;
3625  for (int i = 0; x <= end && i < sections.size(); ++i) {
3626  const qt_section_chunk &section = sections.at(i);
3627  const bool empty = (section.length == section.string.length());
3628  if (x >= start) {
3629  if(x == start)
3630  first_i = i;
3631  if(x == end)
3632  last_i = i;
3633  if(x != start)
3634  ret += section.string;
3635  else
3636  ret += section.string.mid(section.length);
3637  }
3638  if (!empty || !(flags & SectionSkipEmpty))
3639  x++;
3640  }
3641  if((flags & SectionIncludeLeadingSep) && first_i < sections.size()) {
3642  const qt_section_chunk &section = sections.at(first_i);
3643  ret.prepend(section.string.left(section.length));
3644  }
3645  if((flags & SectionIncludeTrailingSep) && last_i+1 <= sections.size()-1) {
3646  const qt_section_chunk &section = sections.at(last_i+1);
3647  ret += section.string.left(section.length);
3648  }
3649  return ret;
3650 }
3651 #endif
3652 
3665 {
3666  if (n >= d->size || n < 0)
3667  return *this;
3668  return QString((const QChar*) d->data, n);
3669 }
3670 
3683 {
3684  if (n >= d->size || n < 0)
3685  return *this;
3686  return QString((const QChar*) d->data + d->size - n, n);
3687 }
3688 
3706 QString QString::mid(int position, int n) const
3707 {
3708  if (d == &shared_null || position >= d->size)
3709  return QString();
3710  if (n < 0)
3711  n = d->size - position;
3712  if (position < 0) {
3713  n += position;
3714  position = 0;
3715  }
3716  if (n + position > d->size)
3717  n = d->size - position;
3718  if (position == 0 && n == d->size)
3719  return *this;
3720  return QString((const QChar*) d->data + position, n);
3721 }
3722 
3735 {
3736  return qt_starts_with(isNull() ? 0 : unicode(), size(),
3737  s.isNull() ? 0 : s.unicode(), s.size(), cs);
3738 }
3739 
3744 {
3745  return qt_starts_with(isNull() ? 0 : unicode(), size(), s, cs);
3746 }
3747 
3758 {
3759  return d->size
3760  && (cs == Qt::CaseSensitive
3761  ? d->data[0] == c
3762  : foldCase(d->data[0]) == foldCase(c.unicode()));
3763 }
3764 
3780 {
3781  return qt_starts_with(isNull() ? 0 : unicode(), size(),
3782  s.isNull() ? 0 : s.unicode(), s.size(), cs);
3783 }
3784 
3797 {
3798  return qt_ends_with(isNull() ? 0 : unicode(), size(),
3799  s.isNull() ? 0 : s.unicode(), s.size(), cs);
3800  }
3801 
3817 {
3818  return qt_ends_with(isNull() ? 0 : unicode(), size(),
3819  s.isNull() ? 0 : s.unicode(), s.size(), cs);
3820 }
3821 
3822 
3827 {
3828  return qt_ends_with(isNull() ? 0 : unicode(), size(), s, cs);
3829 }
3830 
3838 {
3839  return d->size
3840  && (cs == Qt::CaseSensitive
3841  ? d->data[d->size - 1] == c
3842  : foldCase(d->data[d->size - 1]) == foldCase(c.unicode()));
3843 }
3844 
3869 #if defined(QT_ALWAYS_HAVE_SSE2)
3870 static inline __m128i mergeQuestionMarks(__m128i chunk)
3871 {
3872  const __m128i questionMark = _mm_set1_epi16('?');
3873 
3874 # ifdef __SSE4_2__
3875  // compare the unsigned shorts for the range 0x0100-0xFFFF
3876  // note on the use of _mm_cmpestrm:
3877  // The MSDN documentation online (http://technet.microsoft.com/en-us/library/bb514080.aspx)
3878  // says for range search the following:
3879  // For each character c in a, determine whether b0 <= c <= b1 or b2 <= c <= b3
3880  //
3881  // However, all examples on the Internet, including from Intel
3882  // (see http://software.intel.com/en-us/articles/xml-parsing-accelerator-with-intel-streaming-simd-extensions-4-intel-sse4/)
3883  // put the range to be searched first
3884  //
3885  // Disassembly and instruction-level debugging with GCC and ICC show
3886  // that they are doing the right thing. Inverting the arguments in the
3887  // instruction does cause a bunch of test failures.
3888 
3889  const int mode = _SIDD_UWORD_OPS | _SIDD_CMP_RANGES | _SIDD_UNIT_MASK;
3890  const __m128i rangeMatch = _mm_cvtsi32_si128(0xffff0100);
3891  const __m128i offLimitMask = _mm_cmpestrm(rangeMatch, 2, chunk, 8, mode);
3892 
3893  // replace the non-Latin 1 characters in the chunk with question marks
3894  chunk = _mm_blendv_epi8(chunk, questionMark, offLimitMask);
3895 # else
3896  // SSE has no compare instruction for unsigned comparison.
3897  // The variables must be shiffted + 0x8000 to be compared
3898  const __m128i signedBitOffset = _mm_set1_epi16(0x8000);
3899  const __m128i thresholdMask = _mm_set1_epi16(0xff + 0x8000);
3900 
3901  const __m128i signedChunk = _mm_add_epi16(chunk, signedBitOffset);
3902  const __m128i offLimitMask = _mm_cmpgt_epi16(signedChunk, thresholdMask);
3903 
3904 # ifdef __SSE4_1__
3905  // replace the non-Latin 1 characters in the chunk with question marks
3906  chunk = _mm_blendv_epi8(chunk, questionMark, offLimitMask);
3907 # else
3908  // offLimitQuestionMark contains '?' for each 16 bits that was off-limit
3909  // the 16 bits that were correct contains zeros
3910  const __m128i offLimitQuestionMark = _mm_and_si128(offLimitMask, questionMark);
3911 
3912  // correctBytes contains the bytes that were in limit
3913  // the 16 bits that were off limits contains zeros
3914  const __m128i correctBytes = _mm_andnot_si128(offLimitMask, chunk);
3915 
3916  // merge offLimitQuestionMark and correctBytes to have the result
3917  chunk = _mm_or_si128(correctBytes, offLimitQuestionMark);
3918 # endif
3919 # endif
3920  return chunk;
3921 }
3922 #endif
3923 
3925 {
3926  QByteArray ba;
3927  if (length) {
3928  ba.resize(length);
3929  const ushort *src = reinterpret_cast<const ushort *>(data);
3930  uchar *dst = (uchar*) ba.data();
3931 #if defined(QT_ALWAYS_HAVE_SSE2)
3932  if (length >= 16) {
3933  const int chunkCount = length >> 4; // divided by 16
3934 
3935  for (int i = 0; i < chunkCount; ++i) {
3936  __m128i chunk1 = _mm_loadu_si128((__m128i*)src); // load
3937  chunk1 = mergeQuestionMarks(chunk1);
3938  src += 8;
3939 
3940  __m128i chunk2 = _mm_loadu_si128((__m128i*)src); // load
3941  chunk2 = mergeQuestionMarks(chunk2);
3942  src += 8;
3943 
3944  // pack the two vector to 16 x 8bits elements
3945  const __m128i result = _mm_packus_epi16(chunk1, chunk2);
3946 
3947  _mm_storeu_si128((__m128i*)dst, result); // store
3948  dst += 16;
3949  }
3950  length = length % 16;
3951  }
3952 #elif defined(QT_ALWAYS_HAVE_NEON)
3953  // Refer to the documentation of the SSE2 implementation
3954  // this use eactly the same method as for SSE except:
3955  // 1) neon has unsigned comparison
3956  // 2) packing is done to 64 bits (8 x 8bits component).
3957  if (length >= 16) {
3958  const int chunkCount = length >> 3; // divided by 8
3959  const uint16x8_t questionMark = vdupq_n_u16('?'); // set
3960  const uint16x8_t thresholdMask = vdupq_n_u16(0xff); // set
3961  for (int i = 0; i < chunkCount; ++i) {
3962  uint16x8_t chunk = vld1q_u16((uint16_t *)src); // load
3963  src += 8;
3964 
3965  const uint16x8_t offLimitMask = vcgtq_u16(chunk, thresholdMask); // chunk > thresholdMask
3966  const uint16x8_t offLimitQuestionMark = vandq_u16(offLimitMask, questionMark); // offLimitMask & questionMark
3967  const uint16x8_t correctBytes = vbicq_u16(chunk, offLimitMask); // !offLimitMask & chunk
3968  chunk = vorrq_u16(correctBytes, offLimitQuestionMark); // correctBytes | offLimitQuestionMark
3969  const uint8x8_t result = vmovn_u16(chunk); // narrowing move->packing
3970  vst1_u8(dst, result); // store
3971  dst += 8;
3972  }
3973  length = length % 8;
3974  }
3975 #endif
3976  while (length--) {
3977  *dst++ = (*src>0xff) ? '?' : (uchar) *src;
3978  ++src;
3979  }
3980  }
3981  return ba;
3982 }
3983 
3994 {
3995  return toLatin1_helper(unicode(), length());
3996 }
3997 
3998 // ### Qt 5: Change the return type of at least toAscii(),
3999 // toLatin1() and unicode() such that the use of Q_COMPILER_MANGLES_RETURN_TYPE
4000 // isn't necessary in the header. See task 177402.
4001 
4015 {
4016 #ifndef QT_NO_TEXTCODEC
4017  if (codecForCStrings)
4018  return codecForCStrings->fromUnicode(*this);
4019 #endif // QT_NO_TEXTCODEC
4020  return toLatin1();
4021 }
4022 
4023 #if !defined(Q_WS_MAC) && defined(Q_OS_UNIX)
4024 static QByteArray toLocal8Bit_helper(const QChar *data, int length)
4025 {
4026 #ifndef QT_NO_TEXTCODEC
4028  return QTextCodec::codecForLocale()->fromUnicode(data, length);
4029 #endif // QT_NO_TEXTCODEC
4030  return toLatin1_helper(data, length);
4031 }
4032 #endif
4033 
4050 {
4051 #ifndef QT_NO_TEXTCODEC
4053  return QTextCodec::codecForLocale()->fromUnicode(*this);
4054 #endif // QT_NO_TEXTCODEC
4055  return toLatin1();
4056 }
4057 
4075 {
4076  if (isNull())
4077  return QByteArray();
4078 
4079  return QUtf8::convertFromUnicode(constData(), length(), 0);
4080 }
4081 
4096 {
4097  QVector<uint> v(length());
4098  uint *a = v.data();
4099  int len = toUcs4_helper<uint>(utf16(), length(), a);
4100  v.resize(len);
4101  return v;
4102 }
4103 
4105 {
4106  Data *d;
4107  if (!str) {
4108  d = &shared_null;
4109  d->ref.ref();
4110  } else if (size == 0 || (!*str && size < 0)) {
4111  d = &shared_empty;
4112  d->ref.ref();
4113  } else {
4114  if (size < 0)
4115  size = qstrlen(str);
4116  d = static_cast<Data *>(qMalloc(sizeof(Data) + size * sizeof(QChar)));
4117  Q_CHECK_PTR(d);
4118  d->ref = 1;
4119  d->alloc = d->size = size;
4120  d->clean = d->asciiCache = d->simpletext = d->righttoleft = d->capacity = 0;
4121  d->data = d->array;
4122  d->array[size] = '\0';
4123  ushort *dst = d->data;
4124  /* SIMD:
4125  * Unpacking with SSE has been shown to improve performance on recent CPUs
4126  * The same method gives no improvement with NEON.
4127  */
4128 #if defined(QT_ALWAYS_HAVE_SSE2)
4129  if (size >= 16) {
4130  int chunkCount = size >> 4; // divided by 16
4131  const __m128i nullMask = _mm_set1_epi32(0);
4132  for (int i = 0; i < chunkCount; ++i) {
4133  const __m128i chunk = _mm_loadu_si128((__m128i*)str); // load
4134  str += 16;
4135 
4136  // unpack the first 8 bytes, padding with zeros
4137  const __m128i firstHalf = _mm_unpacklo_epi8(chunk, nullMask);
4138  _mm_storeu_si128((__m128i*)dst, firstHalf); // store
4139  dst += 8;
4140 
4141  // unpack the last 8 bytes, padding with zeros
4142  const __m128i secondHalf = _mm_unpackhi_epi8 (chunk, nullMask);
4143  _mm_storeu_si128((__m128i*)dst, secondHalf); // store
4144  dst += 8;
4145  }
4146  size = size % 16;
4147  }
4148 #endif
4149  while (size--)
4150  *dst++ = (uchar)*str++;
4151  }
4152  return d;
4153 }
4154 
4156 {
4157 #ifndef QT_NO_TEXTCODEC
4158  if (codecForCStrings) {
4159  Data *d;
4160  if (!str) {
4161  d = &shared_null;
4162  d->ref.ref();
4163  } else if (size == 0 || (!*str && size < 0)) {
4164  d = &shared_empty;
4165  d->ref.ref();
4166  } else {
4167  if (size < 0)
4168  size = qstrlen(str);
4169  QString s = codecForCStrings->toUnicode(str, size);
4170  d = s.d;
4171  d->ref.ref();
4172  }
4173  return d;
4174  }
4175 #endif
4176  return fromLatin1_helper(str, size);
4177 }
4178 
4188 QString QString::fromLatin1(const char *str, int size)
4189 {
4190  return QString(fromLatin1_helper(str, size), 0);
4191 }
4192 
4193 
4194 #ifdef QT3_SUPPORT
4195 
4199 const char *QString::ascii_helper() const
4200 {
4201  QMutexLocker locker(asciiCacheMutex());
4202  if (!asciiCache)
4203  asciiCache = new QHash<void *, QByteArray>();
4204 
4205  d->asciiCache = true;
4206  QByteArray ascii = toAscii();
4207  QByteArray old = asciiCache->value(d);
4208  if (old == ascii)
4209  return old.constData();
4210  asciiCache->insert(d, ascii);
4211  return ascii.constData();
4212 }
4213 
4217 const char *QString::latin1_helper() const
4218 {
4219  QMutexLocker locker(asciiCacheMutex());
4220  if (!asciiCache)
4221  asciiCache = new QHash<void *, QByteArray>();
4222 
4223  d->asciiCache = true;
4224  QByteArray ascii = toLatin1();
4225  QByteArray old = asciiCache->value(d);
4226  if (old == ascii)
4227  return old.constData();
4228  asciiCache->insert(d, ascii);
4229  return ascii.constData();
4230 }
4231 
4232 #endif
4233 
4245 QString QString::fromLocal8Bit(const char *str, int size)
4246 {
4247  if (!str)
4248  return QString();
4249  if (size == 0 || (!*str && size < 0))
4250  return QLatin1String("");
4251 #if !defined(QT_NO_TEXTCODEC)
4252  if (size < 0)
4253  size = qstrlen(str);
4255  if (codec)
4256  return codec->toUnicode(str, size);
4257 #endif // !QT_NO_TEXTCODEC
4258  return fromLatin1(str, size);
4259 }
4260 
4276 QString QString::fromAscii(const char *str, int size)
4277 {
4278  return QString(fromAscii_helper(str, size), 0);
4279 }
4280 
4302 QString QString::fromUtf8(const char *str, int size)
4303 {
4304  if (!str)
4305  return QString();
4306  if (size < 0)
4307  size = qstrlen(str);
4308 
4309  return QUtf8::convertToUnicode(str, size, 0);
4310 }
4311 
4330 {
4331  if (!unicode)
4332  return QString();
4333  if (size < 0) {
4334  size = 0;
4335  while (unicode[size] != 0)
4336  ++size;
4337  }
4338  return QUtf16::convertToUnicode((const char *)unicode, size*2, 0);
4339 }
4340 
4341 
4357 {
4358  if (!unicode)
4359  return QString();
4360  if (size < 0) {
4361  size = 0;
4362  while (unicode[size] != 0)
4363  ++size;
4364  }
4365  return QUtf32::convertToUnicode((const char *)unicode, size*4, 0);
4366 }
4367 
4378 {
4379  resize(size);
4380  if (unicode && size)
4381  memcpy(d->data, unicode, size * sizeof(QChar));
4382  return *this;
4383 }
4384 
4416 {
4417  if (d->size == 0)
4418  return *this;
4419 
4420  const QChar * const start = reinterpret_cast<QChar *>(d->data);
4421  const QChar *from = start;
4422  const QChar *fromEnd = start + d->size;
4423  forever {
4424  QChar ch = *from;
4425  if (!ch.isSpace())
4426  break;
4427  if (++from == fromEnd) {
4428  // All-whitespace string
4429  shared_empty.ref.ref();
4430  return QString(&shared_empty, 0);
4431  }
4432  }
4433  // This loop needs no underflow check, as we already determined that
4434  // the string contains non-whitespace. If the string has exactly one
4435  // non-whitespace, it will be checked twice - we can live with that.
4436  while (fromEnd[-1].isSpace())
4437  fromEnd--;
4438  // The rest of the function depends on the fact that we already know
4439  // that the last character in the source is no whitespace.
4440  const QChar *copyFrom = from;
4441  int copyCount;
4442  forever {
4443  if (++from == fromEnd) {
4444  // Only leading and/or trailing whitespace, if any at all
4445  return mid(copyFrom - start, from - copyFrom);
4446  }
4447  QChar ch = *from;
4448  if (!ch.isSpace())
4449  continue;
4450  if (ch != QLatin1Char(' ')) {
4451  copyCount = from - copyFrom;
4452  break;
4453  }
4454  ch = *++from;
4455  if (ch.isSpace()) {
4456  copyCount = from - copyFrom - 1;
4457  break;
4458  }
4459  }
4460  // 'from' now points at the non-trailing whitespace which made the
4461  // string not simplified in the first place. 'copyCount' is the number
4462  // of already simplified characters - at least one, obviously -
4463  // without a trailing space.
4464  QString result((fromEnd - from) + copyCount, Qt::Uninitialized);
4465  QChar *to = reinterpret_cast<QChar *>(result.d->data);
4466  ::memcpy(to, copyFrom, copyCount * 2);
4467  to += copyCount;
4468  fromEnd--;
4469  QChar ch;
4470  forever {
4471  *to++ = QLatin1Char(' ');
4472  do {
4473  ch = *++from;
4474  } while (ch.isSpace());
4475  if (from == fromEnd)
4476  break;
4477  do {
4478  *to++ = ch;
4479  ch = *++from;
4480  if (from == fromEnd)
4481  goto done;
4482  } while (!ch.isSpace());
4483  }
4484  done:
4485  *to++ = ch;
4486  result.truncate(to - reinterpret_cast<QChar *>(result.d->data));
4487  return result;
4488 }
4489 
4507 {
4508  if (d->size == 0)
4509  return *this;
4510  const QChar *s = (const QChar*)d->data;
4511  if (!s->isSpace() && !s[d->size-1].isSpace())
4512  return *this;
4513  int start = 0;
4514  int end = d->size - 1;
4515  while (start<=end && s[start].isSpace()) // skip white space from start
4516  start++;
4517  if (start <= end) { // only white space
4518  while (end && s[end].isSpace()) // skip white space from end
4519  end--;
4520  }
4521  int l = end - start + 1;
4522  if (l <= 0) {
4523  shared_empty.ref.ref();
4524  return QString(&shared_empty, 0);
4525  }
4526  return QString(s + start, l);
4527 }
4528 
4603 void QString::truncate(int pos)
4604 {
4605  if (pos < d->size)
4606  resize(pos);
4607 }
4608 
4609 
4623 void QString::chop(int n)
4624 {
4625  if (n > 0)
4626  resize(d->size - n);
4627 }
4628 
4642 {
4643  resize(size < 0 ? d->size : size);
4644  if (d->size) {
4645  QChar *i = (QChar*)d->data + d->size;
4646  QChar *b = (QChar*)d->data;
4647  while (i != b)
4648  *--i = ch;
4649  }
4650  return *this;
4651 }
4652 
5037 int QString::compare(const QString &other) const
5038 {
5039  return ucstrcmp(constData(), length(), other.constData(), other.length());
5040 }
5041 
5048 int QString::compare(const QString &other, Qt::CaseSensitivity cs) const
5049 {
5050  if (cs == Qt::CaseSensitive)
5051  return ucstrcmp(constData(), length(), other.constData(), other.length());
5052  return ucstricmp(d->data, d->data + d->size, other.d->data, other.d->data + other.d->size);
5053 }
5054 
5059 int QString::compare_helper(const QChar *data1, int length1, const QChar *data2, int length2,
5061 {
5062  if (cs == Qt::CaseSensitive)
5063  return ucstrcmp(data1, length1, data2, length2);
5064  register const ushort *s1 = reinterpret_cast<const ushort *>(data1);
5065  register const ushort *s2 = reinterpret_cast<const ushort *>(data2);
5066  return ucstricmp(s1, s1 + length1, s2, s2 + length2);
5067 }
5068 
5076 {
5077  return compare_helper(unicode(), length(), other, cs);
5078 }
5079 
5101 int QString::compare_helper(const QChar *data1, int length1, QLatin1String s2,
5103 {
5104  const ushort *uc = reinterpret_cast<const ushort *>(data1);
5105  const ushort *e = uc + length1;
5106  const uchar *c = (uchar *)s2.latin1();
5107 
5108  if (!c)
5109  return length1;
5110 
5111  if (cs == Qt::CaseSensitive) {
5112  while (uc < e && *c && *uc == *c)
5113  uc++, c++;
5114 
5115  if (uc == e)
5116  return -*c;
5117 
5118  return *uc - *c;
5119  } else {
5120  return ucstricmp(uc, e, c);
5121  }
5122 }
5123 
5178 #if !defined(CSTR_LESS_THAN)
5179 #define CSTR_LESS_THAN 1
5180 #define CSTR_EQUAL 2
5181 #define CSTR_GREATER_THAN 3
5182 #endif
5183 
5197 int QString::localeAwareCompare(const QString &other) const
5198 {
5199  return localeAwareCompare_helper(constData(), length(), other.constData(), other.length());
5200 }
5201 
5202 #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
5204 #include "qt_windows.h"
5206 #endif
5207 
5212 int QString::localeAwareCompare_helper(const QChar *data1, int length1,
5213  const QChar *data2, int length2)
5214 {
5215  // do the right thing for null and empty
5216  if (length1 == 0 || length2 == 0)
5217  return ucstrcmp(data1, length1, data2, length2);
5218 
5219 #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
5220  int res = CompareString(GetUserDefaultLCID(), 0, (wchar_t*)data1, length1, (wchar_t*)data2, length2);
5221 
5222  switch (res) {
5223  case CSTR_LESS_THAN:
5224  return -1;
5225  case CSTR_GREATER_THAN:
5226  return 1;
5227  default:
5228  return 0;
5229  }
5230 #elif defined (Q_OS_MAC)
5231  // Use CFStringCompare for comparing strings on Mac. This makes Qt order
5232  // strings the same way as native applications do, and also respects
5233  // the "Order for sorted lists" setting in the International preferences
5234  // panel.
5235  const CFStringRef thisString =
5236  CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault,
5237  reinterpret_cast<const UniChar *>(data1), length1, kCFAllocatorNull);
5238  const CFStringRef otherString =
5239  CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault,
5240  reinterpret_cast<const UniChar *>(data2), length2, kCFAllocatorNull);
5241 
5242  const int result = CFStringCompare(thisString, otherString, kCFCompareLocalized);
5243  CFRelease(thisString);
5244  CFRelease(otherString);
5245  return result;
5246 #elif defined(Q_OS_SYMBIAN)
5247  TPtrC p1 = TPtrC16(reinterpret_cast<const TUint16 *>(data1), length1);
5248  TPtrC p2 = TPtrC16(reinterpret_cast<const TUint16 *>(data2), length2);
5249  return p1.CompareC(p2);
5250 #elif defined(Q_OS_UNIX)
5251 # if defined(QT_USE_ICU)
5252  int res;
5253  if (qt_ucol_strcoll(data1, length1, data2, length2, &res)) {
5254  if (res == 0)
5255  res = ucstrcmp(data1, length1, data2, length2);
5256  return res;
5257  } // else fall through
5258 # endif
5259  // declared in <string.h>
5260  int delta = strcoll(toLocal8Bit_helper(data1, length1), toLocal8Bit_helper(data2, length2));
5261  if (delta == 0)
5262  delta = ucstrcmp(data1, length1, data2, length2);
5263  return delta;
5264 #else
5265  return ucstrcmp(data1, length1, data2, length2);
5266 #endif
5267 }
5268 
5269 
5290 const ushort *QString::utf16() const
5291 {
5292  if (d->data != d->array) {
5293  QString *that = const_cast<QString*>(this);
5294  that->realloc(); // ensure '\\0'-termination for ::fromRawData strings
5295  return that->d->data;
5296  }
5297  return d->array;
5298 }
5299 
5319 {
5320  QString result;
5321  int len = length();
5322  int padlen = width - len;
5323  if (padlen > 0) {
5324  result.resize(len+padlen);
5325  if (len)
5326  memcpy(result.d->data, d->data, sizeof(QChar)*len);
5327  QChar *uc = (QChar*)result.d->data + len;
5328  while (padlen--)
5329  * uc++ = fill;
5330  } else {
5331  if (truncate)
5332  result = left(width);
5333  else
5334  result = *this;
5335  }
5336  return result;
5337 }
5338 
5358 {
5359  QString result;
5360  int len = length();
5361  int padlen = width - len;
5362  if (padlen > 0) {
5363  result.resize(len+padlen);
5364  QChar *uc = (QChar*)result.d->data;
5365  while (padlen--)
5366  * uc++ = fill;
5367  if (len)
5368  memcpy(uc, d->data, sizeof(QChar)*len);
5369  } else {
5370  if (truncate)
5371  result = left(width);
5372  else
5373  result = *this;
5374  }
5375  return result;
5376 }
5377 
5390 {
5391  const ushort *p = d->data;
5392  if (!p)
5393  return *this;
5394  if (!d->size)
5395  return *this;
5396 
5397  const ushort *e = d->data + d->size;
5398 
5399  // this avoids one out of bounds check in the loop
5400  if (QChar(*p).isLowSurrogate())
5401  ++p;
5402 
5403  while (p != e) {
5404  uint c = *p;
5405  if (QChar(c).isLowSurrogate() && QChar(*(p - 1)).isHighSurrogate())
5406  c = QChar::surrogateToUcs4(*(p - 1), c);
5407  const QUnicodeTables::Properties *prop = qGetProp(c);
5408  if (prop->lowerCaseDiff || prop->lowerCaseSpecial) {
5410  memcpy(s.d->data, d->data, (p - d->data)*sizeof(ushort));
5411  ushort *pp = s.d->data + (p - d->data);
5412  while (p < e) {
5413  uint c = *p;
5414  if (QChar(c).isLowSurrogate() && QChar(*(p - 1)).isHighSurrogate())
5415  c = QChar::surrogateToUcs4(*(p - 1), c);
5416  prop = qGetProp(c);
5417  if (prop->lowerCaseSpecial) {
5418  int pos = pp - s.d->data;
5420  pp = s.d->data + pos;
5421  const ushort *specialCase = specialCaseMap + prop->lowerCaseDiff;
5422  while (*specialCase)
5423  *pp++ = *specialCase++;
5424  } else {
5425  *pp++ = *p + prop->lowerCaseDiff;
5426  }
5427  ++p;
5428  }
5429  s.truncate(pp - s.d->data);
5430  return s;
5431  }
5432  ++p;
5433  }
5434  return *this;
5435 }
5436 
5442 {
5443  if (!d->size)
5444  return *this;
5445 
5446  const ushort *p = d->data;
5447  if (!p)
5448  return *this;
5449 
5450  const ushort *e = d->data + d->size;
5451 
5452  uint last = 0;
5453  while (p < e) {
5454  ushort folded = foldCase(*p, last);
5455  if (folded != *p) {
5456  QString s(*this);
5457  s.detach();
5458  ushort *pp = s.d->data + (p - d->data);
5459  const ushort *ppe = s.d->data + s.d->size;
5460  last = pp > s.d->data ? *(pp - 1) : 0;
5461  while (pp < ppe) {
5462  *pp = foldCase(*pp, last);
5463  ++pp;
5464  }
5465  return s;
5466  }
5467  p++;
5468  }
5469  return *this;
5470 }
5471 
5484 {
5485  const ushort *p = d->data;
5486  if (!p)
5487  return *this;
5488  if (!d->size)
5489  return *this;
5490 
5491  const ushort *e = d->data + d->size;
5492 
5493  // this avoids one out of bounds check in the loop
5494  if (QChar(*p).isLowSurrogate())
5495  ++p;
5496 
5497  while (p != e) {
5498  uint c = *p;
5499  if (QChar(c).isLowSurrogate() && QChar(*(p - 1)).isHighSurrogate())
5500  c = QChar::surrogateToUcs4(*(p - 1), c);
5501  const QUnicodeTables::Properties *prop = qGetProp(c);
5502  if (prop->upperCaseDiff || prop->upperCaseSpecial) {
5504  memcpy(s.d->data, d->data, (p - d->data)*sizeof(ushort));
5505  ushort *pp = s.d->data + (p - d->data);
5506  while (p < e) {
5507  uint c = *p;
5508  if (QChar(c).isLowSurrogate() && QChar(*(p - 1)).isHighSurrogate())
5509  c = QChar::surrogateToUcs4(*(p - 1), c);
5510  prop = qGetProp(c);
5511  if (prop->upperCaseSpecial) {
5512  int pos = pp - s.d->data;
5514  pp = s.d->data + pos;
5515  const ushort *specialCase = specialCaseMap + prop->upperCaseDiff;
5516  while (*specialCase)
5517  *pp++ = *specialCase++;
5518  } else {
5519  *pp++ = *p + prop->upperCaseDiff;
5520  }
5521  ++p;
5522  }
5523  s.truncate(pp - s.d->data);
5524  return s;
5525  }
5526  ++p;
5527  }
5528  return *this;
5529 }
5530 
5531 // ### Qt 5: Consider whether this function shouldn't be removed See task 202871.
5567 QString &QString::sprintf(const char *cformat, ...)
5568 {
5569  va_list ap;
5570  va_start(ap, cformat);
5571  QString &s = vsprintf(cformat, ap);
5572  va_end(ap);
5573  return s;
5574 }
5575 
5587 QString &QString::vsprintf(const char* cformat, va_list ap)
5588 {
5589  QLocale locale(QLocale::C);
5590 
5591  if (!cformat || !*cformat) {
5592  // Qt 1.x compat
5593  *this = fromLatin1("");
5594  return *this;
5595  }
5596 
5597  // Parse cformat
5598 
5599  QString result;
5600  const char *c = cformat;
5601  for (;;) {
5602  // Copy non-escape chars to result
5603 #ifndef QT_NO_TEXTCODEC
5604  int i = 0;
5605  while (*(c + i) != '\0' && *(c + i) != '%')
5606  ++i;
5607  if (codecForCStrings)
5608  result.append(codecForCStrings->toUnicode(c, i));
5609  else
5610  result.append(fromLatin1(c, i));
5611  c += i;
5612 #else
5613  while (*c != '\0' && *c != '%')
5614  result.append(QLatin1Char(*c++));
5615 #endif
5616 
5617  if (*c == '\0')
5618  break;
5619 
5620  // Found '%'
5621  const char *escape_start = c;
5622  ++c;
5623 
5624  if (*c == '\0') {
5625  result.append(QLatin1Char('%')); // a % at the end of the string - treat as non-escape text
5626  break;
5627  }
5628  if (*c == '%') {
5629  result.append(QLatin1Char('%')); // %%
5630  ++c;
5631  continue;
5632  }
5633 
5634  // Parse flag characters
5635  uint flags = 0;
5636  bool no_more_flags = false;
5637  do {
5638  switch (*c) {
5639  case '#': flags |= QLocalePrivate::Alternate; break;
5640  case '0': flags |= QLocalePrivate::ZeroPadded; break;
5641  case '-': flags |= QLocalePrivate::LeftAdjusted; break;
5642  case ' ': flags |= QLocalePrivate::BlankBeforePositive; break;
5643  case '+': flags |= QLocalePrivate::AlwaysShowSign; break;
5644  case '\'': flags |= QLocalePrivate::ThousandsGroup; break;
5645  default: no_more_flags = true; break;
5646  }
5647 
5648  if (!no_more_flags)
5649  ++c;
5650  } while (!no_more_flags);
5651 
5652  if (*c == '\0') {
5653  result.append(QLatin1String(escape_start)); // incomplete escape, treat as non-escape text
5654  break;
5655  }
5656 
5657  // Parse field width
5658  int width = -1; // -1 means unspecified
5659  if (qIsDigit(*c)) {
5660  QString width_str;
5661  while (*c != '\0' && qIsDigit(*c))
5662  width_str.append(QLatin1Char(*c++));
5663 
5664  // can't be negative - started with a digit
5665  // contains at least one digit
5666  width = width_str.toInt();
5667  }
5668  else if (*c == '*') {
5669  width = va_arg(ap, int);
5670  if (width < 0)
5671  width = -1; // treat all negative numbers as unspecified
5672  ++c;
5673  }
5674 
5675  if (*c == '\0') {
5676  result.append(QLatin1String(escape_start)); // incomplete escape, treat as non-escape text
5677  break;
5678  }
5679 
5680  // Parse precision
5681  int precision = -1; // -1 means unspecified
5682  if (*c == '.') {
5683  ++c;
5684  if (qIsDigit(*c)) {
5685  QString precision_str;
5686  while (*c != '\0' && qIsDigit(*c))
5687  precision_str.append(QLatin1Char(*c++));
5688 
5689  // can't be negative - started with a digit
5690  // contains at least one digit
5691  precision = precision_str.toInt();
5692  }
5693  else if (*c == '*') {
5694  precision = va_arg(ap, int);
5695  if (precision < 0)
5696  precision = -1; // treat all negative numbers as unspecified
5697  ++c;
5698  }
5699  }
5700 
5701  if (*c == '\0') {
5702  result.append(QLatin1String(escape_start)); // incomplete escape, treat as non-escape text
5703  break;
5704  }
5705 
5706  // Parse the length modifier
5707  enum LengthMod { lm_none, lm_hh, lm_h, lm_l, lm_ll, lm_L, lm_j, lm_z, lm_t };
5708  LengthMod length_mod = lm_none;
5709  switch (*c) {
5710  case 'h':
5711  ++c;
5712  if (*c == 'h') {
5713  length_mod = lm_hh;
5714  ++c;
5715  }
5716  else
5717  length_mod = lm_h;
5718  break;
5719 
5720  case 'l':
5721  ++c;
5722  if (*c == 'l') {
5723  length_mod = lm_ll;
5724  ++c;
5725  }
5726  else
5727  length_mod = lm_l;
5728  break;
5729 
5730  case 'L':
5731  ++c;
5732  length_mod = lm_L;
5733  break;
5734 
5735  case 'j':
5736  ++c;
5737  length_mod = lm_j;
5738  break;
5739 
5740  case 'z':
5741  case 'Z':
5742  ++c;
5743  length_mod = lm_z;
5744  break;
5745 
5746  case 't':
5747  ++c;
5748  length_mod = lm_t;
5749  break;
5750 
5751  default: break;
5752  }
5753 
5754  if (*c == '\0') {
5755  result.append(QLatin1String(escape_start)); // incomplete escape, treat as non-escape text
5756  break;
5757  }
5758 
5759  // Parse the conversion specifier and do the conversion
5760  QString subst;
5761  switch (*c) {
5762  case 'd':
5763  case 'i': {
5764  qint64 i;
5765  switch (length_mod) {
5766  case lm_none: i = va_arg(ap, int); break;
5767  case lm_hh: i = va_arg(ap, int); break;
5768  case lm_h: i = va_arg(ap, int); break;
5769  case lm_l: i = va_arg(ap, long int); break;
5770  case lm_ll: i = va_arg(ap, qint64); break;
5771  case lm_j: i = va_arg(ap, long int); break;
5772  case lm_z: i = va_arg(ap, size_t); break;
5773  case lm_t: i = va_arg(ap, int); break;
5774  default: i = 0; break;
5775  }
5776  subst = locale.d()->longLongToString(i, precision, 10, width, flags);
5777  ++c;
5778  break;
5779  }
5780  case 'o':
5781  case 'u':
5782  case 'x':
5783  case 'X': {
5784  quint64 u;
5785  switch (length_mod) {
5786  case lm_none: u = va_arg(ap, uint); break;
5787  case lm_hh: u = va_arg(ap, uint); break;
5788  case lm_h: u = va_arg(ap, uint); break;
5789  case lm_l: u = va_arg(ap, ulong); break;
5790  case lm_ll: u = va_arg(ap, quint64); break;
5791  case lm_z: u = va_arg(ap, size_t); break;
5792  default: u = 0; break;
5793  }
5794 
5795  if (qIsUpper(*c))
5796  flags |= QLocalePrivate::CapitalEorX;
5797 
5798  int base = 10;
5799  switch (qToLower(*c)) {
5800  case 'o':
5801  base = 8; break;
5802  case 'u':
5803  base = 10; break;
5804  case 'x':
5805  base = 16; break;
5806  default: break;
5807  }
5808  subst = locale.d()->unsLongLongToString(u, precision, base, width, flags);
5809  ++c;
5810  break;
5811  }
5812  case 'E':
5813  case 'e':
5814  case 'F':
5815  case 'f':
5816  case 'G':
5817  case 'g':
5818  case 'A':
5819  case 'a': {
5820  double d;
5821  if (length_mod == lm_L)
5822  d = va_arg(ap, long double); // not supported - converted to a double
5823  else
5824  d = va_arg(ap, double);
5825 
5826  if (qIsUpper(*c))
5827  flags |= QLocalePrivate::CapitalEorX;
5828 
5830  switch (qToLower(*c)) {
5831  case 'e': form = QLocalePrivate::DFExponent; break;
5832  case 'a': // not supported - decimal form used instead
5833  case 'f': form = QLocalePrivate::DFDecimal; break;
5834  case 'g': form = QLocalePrivate::DFSignificantDigits; break;
5835  default: break;
5836  }
5837  subst = locale.d()->doubleToString(d, precision, form, width, flags);
5838  ++c;
5839  break;
5840  }
5841  case 'c': {
5842  if (length_mod == lm_l)
5843  subst = QChar((ushort) va_arg(ap, int));
5844  else
5845  subst = QLatin1Char((uchar) va_arg(ap, int));
5846  ++c;
5847  break;
5848  }
5849  case 's': {
5850  if (length_mod == lm_l) {
5851  const ushort *buff = va_arg(ap, const ushort*);
5852  const ushort *ch = buff;
5853  while (*ch != 0)
5854  ++ch;
5855  subst.setUtf16(buff, ch - buff);
5856  } else
5857  subst = QString::fromUtf8(va_arg(ap, const char*));
5858  if (precision != -1)
5859  subst.truncate(precision);
5860  ++c;
5861  break;
5862  }
5863  case 'p': {
5864  void *arg = va_arg(ap, void*);
5865 #ifdef Q_OS_WIN64
5866  quint64 i = reinterpret_cast<quint64>(arg);
5867 #else
5868  quint64 i = reinterpret_cast<unsigned long>(arg);
5869 #endif
5870  flags |= QLocalePrivate::Alternate;
5871  subst = locale.d()->unsLongLongToString(i, precision, 16, width, flags);
5872  ++c;
5873  break;
5874  }
5875  case 'n':
5876  switch (length_mod) {
5877  case lm_hh: {
5878  signed char *n = va_arg(ap, signed char*);
5879  *n = result.length();
5880  break;
5881  }
5882  case lm_h: {
5883  short int *n = va_arg(ap, short int*);
5884  *n = result.length();
5885  break;
5886  }
5887  case lm_l: {
5888  long int *n = va_arg(ap, long int*);
5889  *n = result.length();
5890  break;
5891  }
5892  case lm_ll: {
5893  qint64 *n = va_arg(ap, qint64*);
5894  volatile uint tmp = result.length(); // egcs-2.91.66 gets internal
5895  *n = tmp; // compiler error without volatile
5896  break;
5897  }
5898  default: {
5899  int *n = va_arg(ap, int*);
5900  *n = result.length();
5901  break;
5902  }
5903  }
5904  ++c;
5905  break;
5906 
5907  default: // bad escape, treat as non-escape text
5908  for (const char *cc = escape_start; cc != c; ++cc)
5909  result.append(QLatin1Char(*cc));
5910  continue;
5911  }
5912 
5913  if (flags & QLocalePrivate::LeftAdjusted)
5914  result.append(subst.leftJustified(width));
5915  else
5916  result.append(subst.rightJustified(width));
5917  }
5918 
5919  *this = result;
5920 
5921  return *this;
5922 }
5923 
5943 qint64 QString::toLongLong(bool *ok, int base) const
5944 {
5945 #if defined(QT_CHECK_RANGE)
5946  if (base != 0 && (base < 2 || base > 36)) {
5947  qWarning("QString::toLongLong: Invalid base (%d)", base);
5948  base = 10;
5949  }
5950 #endif
5951 
5952  bool my_ok;
5953  QLocale def_locale;
5954  qint64 result = def_locale.d()->stringToLongLong(*this, base, &my_ok, QLocalePrivate::FailOnGroupSeparators);
5955  if (my_ok) {
5956  if (ok != 0)
5957  *ok = true;
5958  return result;
5959  }
5960 
5961  QLocale c_locale(QLocale::C);
5962  return c_locale.d()->stringToLongLong(*this, base, ok, QLocalePrivate::FailOnGroupSeparators);
5963 }
5964 
5984 quint64 QString::toULongLong(bool *ok, int base) const
5985 {
5986 #if defined(QT_CHECK_RANGE)
5987  if (base != 0 && (base < 2 || base > 36)) {
5988  qWarning("QString::toULongLong: Invalid base (%d)", base);
5989  base = 10;
5990  }
5991 #endif
5992 
5993  bool my_ok;
5994  QLocale def_locale;
5995  quint64 result = def_locale.d()->stringToUnsLongLong(*this, base, &my_ok, QLocalePrivate::FailOnGroupSeparators);
5996  if (my_ok) {
5997  if (ok != 0)
5998  *ok = true;
5999  return result;
6000  }
6001 
6002  QLocale c_locale(QLocale::C);
6003  return c_locale.d()->stringToUnsLongLong(*this, base, ok, QLocalePrivate::FailOnGroupSeparators);
6004 }
6005 
6027 long QString::toLong(bool *ok, int base) const
6028 {
6029  qint64 v = toLongLong(ok, base);
6030  if (v < LONG_MIN || v > LONG_MAX) {
6031  if (ok)
6032  *ok = false;
6033  v = 0;
6034  }
6035  return (long)v;
6036 }
6037 
6059 ulong QString::toULong(bool *ok, int base) const
6060 {
6061  quint64 v = toULongLong(ok, base);
6062  if (v > ULONG_MAX) {
6063  if (ok)
6064  *ok = false;
6065  v = 0;
6066  }
6067  return (ulong)v;
6068 }
6069 
6070 
6090 int QString::toInt(bool *ok, int base) const
6091 {
6092  qint64 v = toLongLong(ok, base);
6093  if (v < INT_MIN || v > INT_MAX) {
6094  if (ok)
6095  *ok = false;
6096  v = 0;
6097  }
6098  return v;
6099 }
6100 
6120 uint QString::toUInt(bool *ok, int base) const
6121 {
6122  quint64 v = toULongLong(ok, base);
6123  if (v > UINT_MAX) {
6124  if (ok)
6125  *ok = false;
6126  v = 0;
6127  }
6128  return (uint)v;
6129 }
6130 
6150 short QString::toShort(bool *ok, int base) const
6151 {
6152  long v = toLongLong(ok, base);
6153  if (v < SHRT_MIN || v > SHRT_MAX) {
6154  if (ok)
6155  *ok = false;
6156  v = 0;
6157  }
6158  return (short)v;
6159 }
6160 
6180 ushort QString::toUShort(bool *ok, int base) const
6181 {
6182  ulong v = toULongLong(ok, base);
6183  if (v > USHRT_MAX) {
6184  if (ok)
6185  *ok = false;
6186  v = 0;
6187  }
6188  return (ushort)v;
6189 }
6190 
6191 
6227 double QString::toDouble(bool *ok) const
6228 {
6229  bool my_ok;
6230  QLocale def_locale;
6231  double result = def_locale.d()->stringToDouble(*this, &my_ok, QLocalePrivate::FailOnGroupSeparators);
6232  if (my_ok) {
6233  if (ok != 0)
6234  *ok = true;
6235  return result;
6236  }
6237 
6238  QLocale c_locale(QLocale::C);
6239  return c_locale.d()->stringToDouble(*this, ok, QLocalePrivate::FailOnGroupSeparators);
6240 }
6241 
6255 #define QT_MAX_FLOAT 3.4028234663852886e+38
6256 
6257 float QString::toFloat(bool *ok) const
6258 {
6259  bool myOk;
6260  double d = toDouble(&myOk);
6261  if (!myOk || d > QT_MAX_FLOAT || d < -QT_MAX_FLOAT) {
6262  if (ok != 0)
6263  *ok = false;
6264  return 0.0;
6265  }
6266  if (ok != 0)
6267  *ok = true;
6268  return (float) d;
6269 }
6270 
6308 {
6309 #if defined(QT_CHECK_RANGE)
6310  if (base < 2 || base > 36) {
6311  qWarning("QString::setNum: Invalid base (%d)", base);
6312  base = 10;
6313  }
6314 #endif
6315  QLocale locale(QLocale::C);
6316  *this = locale.d()->longLongToString(n, -1, base);
6317  return *this;
6318 }
6319 
6324 {
6325 #if defined(QT_CHECK_RANGE)
6326  if (base < 2 || base > 36) {
6327  qWarning("QString::setNum: Invalid base (%d)", base);
6328  base = 10;
6329  }
6330 #endif
6331  QLocale locale(QLocale::C);
6332  *this = locale.d()->unsLongLongToString(n, -1, base);
6333  return *this;
6334 }
6335 
6364 QString &QString::setNum(double n, char f, int prec)
6365 {
6367  uint flags = 0;
6368 
6369  if (qIsUpper(f))
6371  f = qToLower(f);
6372 
6373  switch (f) {
6374  case 'f':
6376  break;
6377  case 'e':
6379  break;
6380  case 'g':
6382  break;
6383  default:
6384 #if defined(QT_CHECK_RANGE)
6385  qWarning("QString::setNum: Invalid format char '%c'", f);
6386 #endif
6387  break;
6388  }
6389 
6390  QLocale locale(QLocale::C);
6391  *this = locale.d()->doubleToString(n, prec, form, -1, flags);
6392  return *this;
6393 }
6394 
6427 {
6428  QString s;
6429  s.setNum(n, base);
6430  return s;
6431 }
6432 
6439 {
6440  QString s;
6441  s.setNum(n, base);
6442  return s;
6443 }
6444 
6449 {
6450  QString s;
6451  s.setNum(n, base);
6452  return s;
6453 }
6454 
6459 {
6460  QString s;
6461  s.setNum(n, base);
6462  return s;
6463 }
6464 
6469 {
6470  QString s;
6471  s.setNum(n, base);
6472  return s;
6473 }
6474 
6479 {
6480  QString s;
6481  s.setNum(n, base);
6482  return s;
6483 }
6484 
6485 
6501 QString QString::number(double n, char f, int prec)
6502 {
6503  QString s;
6504  s.setNum(n, f, prec);
6505  return s;
6506 }
6507 
6527 {
6528  QStringList list;
6529  int start = 0;
6530  int extra = 0;
6531  int end;
6532  while ((end = indexOf(sep, start + extra, cs)) != -1) {
6533  if (start != end || behavior == KeepEmptyParts)
6534  list.append(mid(start, end - start));
6535  start = end + sep.size();
6536  extra = (sep.size() == 0 ? 1 : 0);
6537  }
6538  if (start != size() || behavior == KeepEmptyParts)
6539  list.append(mid(start));
6540  return list;
6541 }
6542 
6547 {
6548  QStringList list;
6549  int start = 0;
6550  int end;
6551  while ((end = indexOf(sep, start, cs)) != -1) {
6552  if (start != end || behavior == KeepEmptyParts)
6553  list.append(mid(start, end - start));
6554  start = end + 1;
6555  }
6556  if (start != size() || behavior == KeepEmptyParts)
6557  list.append(mid(start));
6558  return list;
6559 }
6560 
6561 #ifndef QT_NO_REGEXP
6562 
6592 {
6593  QRegExp rx2(rx);
6594  QStringList list;
6595  int start = 0;
6596  int extra = 0;
6597  int end;
6598  while ((end = rx2.indexIn(*this, start + extra)) != -1) {
6599  int matchedLen = rx2.matchedLength();
6600  if (start != end || behavior == KeepEmptyParts)
6601  list.append(mid(start, end - start));
6602  start = end + matchedLen;
6603  extra = (matchedLen == 0) ? 1 : 0;
6604  }
6605  if (start != size() || behavior == KeepEmptyParts)
6606  list.append(mid(start));
6607  return list;
6608 }
6609 #endif
6610 
6636 {
6637  return normalized(mode, UNICODE_DATA_VERSION);
6638 }
6639 
6657 QString QString::repeated(int times) const
6658 {
6659  if (d->size == 0)
6660  return *this;
6661 
6662  if (times <= 1) {
6663  if (times == 1)
6664  return *this;
6665  return QString();
6666  }
6667 
6668  const int resultSize = times * d->size;
6669 
6670  QString result;
6671  result.reserve(resultSize);
6672  if (result.d->alloc != resultSize)
6673  return QString(); // not enough memory
6674 
6675  memcpy(result.d->data, d->data, d->size * sizeof(ushort));
6676 
6677  int sizeSoFar = d->size;
6678  ushort *end = result.d->data + sizeSoFar;
6679 
6680  const int halfResultSize = resultSize >> 1;
6681  while (sizeSoFar <= halfResultSize) {
6682  memcpy(end, result.d->data, sizeSoFar * sizeof(ushort));
6683  end += sizeSoFar;
6684  sizeSoFar <<= 1;
6685  }
6686  memcpy(end, result.d->data, (resultSize - sizeSoFar) * sizeof(ushort));
6687  result.d->data[resultSize] = '\0';
6688  result.d->size = resultSize;
6689  return result;
6690 }
6691 
6704 {
6705  QString copy = *this;
6706  qt_string_normalize(&copy, mode, version, 0);
6707  return copy;
6708 }
6709 
6711 {
6712  bool simple = true;
6713  const QChar *p = data->constData();
6714  int len = data->length();
6715  for (int i = from; i < len; ++i) {
6716  if (p[i].unicode() >= 0x80) {
6717  simple = false;
6718  break;
6719  }
6720  }
6721  if (simple)
6722  return;
6723 
6724  if (version == QChar::Unicode_Unassigned) {
6725  version = UNICODE_DATA_VERSION;
6726  } else if (version != UNICODE_DATA_VERSION) {
6727  const QString &s = *data;
6728  QChar *d = 0;
6729  for (int i = 0; i < NumNormalizationCorrections; ++i) {
6731  if (n.version > version) {
6732  int pos = from;
6734  ushort ucs4High = QChar::highSurrogate(n.ucs4);
6735  ushort ucs4Low = QChar::lowSurrogate(n.ucs4);
6738  while (pos < s.length() - 1) {
6739  if (s.at(pos).unicode() == ucs4High && s.at(pos + 1).unicode() == ucs4Low) {
6740  if (!d)
6741  d = data->data();
6742  d[pos] = QChar(oldHigh);
6743  d[++pos] = QChar(oldLow);
6744  }
6745  ++pos;
6746  }
6747  } else {
6748  while (pos < s.length()) {
6749  if (s.at(pos).unicode() == n.ucs4) {
6750  if (!d)
6751  d = data->data();
6752  d[pos] = QChar(n.old_mapping);
6753  }
6754  ++pos;
6755  }
6756  }
6757  }
6758  }
6759  }
6760  decomposeHelper(data, mode < QString::NormalizationForm_KD, version, from);
6761 
6762  canonicalOrderHelper(data, version, from);
6763 
6765  return;
6766 
6767  composeHelper(data, version, from);
6768 }
6769 
6770 
6772 {
6773  int min_escape; // lowest escape sequence number
6774  int occurrences; // number of occurrences of the lowest escape sequence number
6775  int locale_occurrences; // number of occurrences of the lowest escape sequence number that
6776  // contain 'L'
6777  int escape_len; // total length of escape sequences which will be replaced
6778 };
6779 
6781 {
6782  const QChar *uc_begin = s.unicode();
6783  const QChar *uc_end = uc_begin + s.length();
6784 
6785  ArgEscapeData d;
6786 
6787  d.min_escape = INT_MAX;
6788  d.occurrences = 0;
6789  d.escape_len = 0;
6790  d.locale_occurrences = 0;
6791 
6792  const QChar *c = uc_begin;
6793  while (c != uc_end) {
6794  while (c != uc_end && c->unicode() != '%')
6795  ++c;
6796 
6797  if (c == uc_end)
6798  break;
6799  const QChar *escape_start = c;
6800  if (++c == uc_end)
6801  break;
6802 
6803  bool locale_arg = false;
6804  if (c->unicode() == 'L') {
6805  locale_arg = true;
6806  if (++c == uc_end)
6807  break;
6808  }
6809 
6810  if (c->digitValue() == -1)
6811  continue;
6812 
6813  int escape = c->digitValue();
6814  ++c;
6815 
6816  if (c != uc_end && c->digitValue() != -1) {
6817  escape = (10 * escape) + c->digitValue();
6818  ++c;
6819  }
6820 
6821  if (escape > d.min_escape)
6822  continue;
6823 
6824  if (escape < d.min_escape) {
6825  d.min_escape = escape;
6826  d.occurrences = 0;
6827  d.escape_len = 0;
6828  d.locale_occurrences = 0;
6829  }
6830 
6831  ++d.occurrences;
6832  if (locale_arg)
6833  ++d.locale_occurrences;
6834  d.escape_len += c - escape_start;
6835  }
6836  return d;
6837 }
6838 
6839 static QString replaceArgEscapes(const QString &s, const ArgEscapeData &d, int field_width,
6840  const QString &arg, const QString &larg, const QChar &fillChar = QLatin1Char(' '))
6841 {
6842  const QChar *uc_begin = s.unicode();
6843  const QChar *uc_end = uc_begin + s.length();
6844 
6845  int abs_field_width = qAbs(field_width);
6846  int result_len = s.length()
6847  - d.escape_len
6849  *qMax(abs_field_width, arg.length())
6850  + d.locale_occurrences
6851  *qMax(abs_field_width, larg.length());
6852 
6853  QString result(result_len, Qt::Uninitialized);
6854  QChar *result_buff = (QChar*) result.unicode();
6855 
6856  QChar *rc = result_buff;
6857  const QChar *c = uc_begin;
6858  int repl_cnt = 0;
6859  while (c != uc_end) {
6860  /* We don't have to check if we run off the end of the string with c,
6861  because as long as d.occurrences > 0 we KNOW there are valid escape
6862  sequences. */
6863 
6864  const QChar *text_start = c;
6865 
6866  while (c->unicode() != '%')
6867  ++c;
6868 
6869  const QChar *escape_start = c++;
6870 
6871  bool locale_arg = false;
6872  if (c->unicode() == 'L') {
6873  locale_arg = true;
6874  ++c;
6875  }
6876 
6877  int escape = c->digitValue();
6878  if (escape != -1) {
6879  if (c + 1 != uc_end && (c + 1)->digitValue() != -1) {
6880  escape = (10 * escape) + (c + 1)->digitValue();
6881  ++c;
6882  }
6883  }
6884 
6885  if (escape != d.min_escape) {
6886  memcpy(rc, text_start, (c - text_start)*sizeof(QChar));
6887  rc += c - text_start;
6888  }
6889  else {
6890  ++c;
6891 
6892  memcpy(rc, text_start, (escape_start - text_start)*sizeof(QChar));
6893  rc += escape_start - text_start;
6894 
6895  uint pad_chars;
6896  if (locale_arg)
6897  pad_chars = qMax(abs_field_width, larg.length()) - larg.length();
6898  else
6899  pad_chars = qMax(abs_field_width, arg.length()) - arg.length();
6900 
6901  if (field_width > 0) { // left padded
6902  for (uint i = 0; i < pad_chars; ++i)
6903  (rc++)->unicode() = fillChar.unicode();
6904  }
6905 
6906  if (locale_arg) {
6907  memcpy(rc, larg.unicode(), larg.length()*sizeof(QChar));
6908  rc += larg.length();
6909  }
6910  else {
6911  memcpy(rc, arg.unicode(), arg.length()*sizeof(QChar));
6912  rc += arg.length();
6913  }
6914 
6915  if (field_width < 0) { // right padded
6916  for (uint i = 0; i < pad_chars; ++i)
6917  (rc++)->unicode() = fillChar.unicode();
6918  }
6919 
6920  if (++repl_cnt == d.occurrences) {
6921  memcpy(rc, c, (uc_end - c)*sizeof(QChar));
6922  rc += uc_end - c;
6923  Q_ASSERT(rc - result_buff == result_len);
6924  c = uc_end;
6925  }
6926  }
6927  }
6928  Q_ASSERT(rc == result_buff + result_len);
6929 
6930  return result;
6931 }
6932 
6962 QString QString::arg(const QString &a, int fieldWidth, const QChar &fillChar) const
6963 {
6964  ArgEscapeData d = findArgEscapes(*this);
6965 
6966  if (d.occurrences == 0) {
6967  qWarning("QString::arg: Argument missing: %s, %s", toLocal8Bit().data(),
6968  a.toLocal8Bit().data());
6969  return *this;
6970  }
6971  return replaceArgEscapes(*this, d, fieldWidth, a, a, fillChar);
6972 }
6973 
7186 QString QString::arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
7187 {
7188  ArgEscapeData d = findArgEscapes(*this);
7189 
7190  if (d.occurrences == 0) {
7191  qWarning() << "QString::arg: Argument missing:" << *this << ',' << a;
7192  return *this;
7193  }
7194 
7195  unsigned flags = QLocalePrivate::NoFlags;
7196  if (fillChar == QLatin1Char('0'))
7198 
7199  QString arg;
7200  if (d.occurrences > d.locale_occurrences)
7201  arg = QLocale::c().d()->longLongToString(a, -1, base, fieldWidth, flags);
7202 
7203  QString locale_arg;
7204  if (d.locale_occurrences > 0) {
7205  QLocale locale;
7208  locale_arg = locale.d()->longLongToString(a, -1, base, fieldWidth, flags);
7209  }
7210 
7211  return replaceArgEscapes(*this, d, fieldWidth, arg, locale_arg, fillChar);
7212 }
7213 
7233 QString QString::arg(qulonglong a, int fieldWidth, int base, const QChar &fillChar) const
7234 {
7235  ArgEscapeData d = findArgEscapes(*this);
7236 
7237  if (d.occurrences == 0) {
7238  qWarning() << "QString::arg: Argument missing:" << *this << ',' << a;
7239  return *this;
7240  }
7241 
7242  unsigned flags = QLocalePrivate::NoFlags;
7243  if (fillChar == QLatin1Char('0'))
7245 
7246  QString arg;
7247  if (d.occurrences > d.locale_occurrences)
7248  arg = QLocale::c().d()->unsLongLongToString(a, -1, base, fieldWidth, flags);
7249 
7250  QString locale_arg;
7251  if (d.locale_occurrences > 0) {
7252  QLocale locale;
7255  locale_arg = locale.d()->unsLongLongToString(a, -1, base, fieldWidth, flags);
7256  }
7257 
7258  return replaceArgEscapes(*this, d, fieldWidth, arg, locale_arg, fillChar);
7259 }
7260 
7307 QString QString::arg(QChar a, int fieldWidth, const QChar &fillChar) const
7308 {
7309  QString c;
7310  c += a;
7311  return arg(c, fieldWidth, fillChar);
7312 }
7313 
7322 QString QString::arg(char a, int fieldWidth, const QChar &fillChar) const
7323 {
7324  QString c;
7325  c += QLatin1Char(a);
7326  return arg(c, fieldWidth, fillChar);
7327 }
7328 
7357 QString QString::arg(double a, int fieldWidth, char fmt, int prec, const QChar &fillChar) const
7358 {
7359  ArgEscapeData d = findArgEscapes(*this);
7360 
7361  if (d.occurrences == 0) {
7362  qWarning("QString::arg: Argument missing: %s, %g", toLocal8Bit().data(), a);
7363  return *this;
7364  }
7365 
7366  unsigned flags = QLocalePrivate::NoFlags;
7367  if (fillChar == QLatin1Char('0'))
7369 
7370  if (qIsUpper(fmt))
7371  flags |= QLocalePrivate::CapitalEorX;
7372  fmt = qToLower(fmt);
7373 
7375  switch (fmt) {
7376  case 'f':
7378  break;
7379  case 'e':
7381  break;
7382  case 'g':
7384  break;
7385  default:
7386 #if defined(QT_CHECK_RANGE)
7387  qWarning("QString::arg: Invalid format char '%c'", fmt);
7388 #endif
7389  break;
7390  }
7391 
7392  QString arg;
7393  if (d.occurrences > d.locale_occurrences)
7394  arg = QLocale::c().d()->doubleToString(a, prec, form, fieldWidth, flags);
7395 
7396  QString locale_arg;
7397  if (d.locale_occurrences > 0) {
7398  QLocale locale;
7399 
7402  locale_arg = locale.d()->doubleToString(a, prec, form, fieldWidth, flags);
7403  }
7404 
7405  return replaceArgEscapes(*this, d, fieldWidth, arg, locale_arg, fillChar);
7406 }
7407 
7408 static int getEscape(const QChar *uc, int *pos, int len, int maxNumber = 999)
7409 {
7410  int i = *pos;
7411  ++i;
7412  if (i < len && uc[i] == QLatin1Char('L'))
7413  ++i;
7414  if (i < len) {
7415  int escape = uc[i].unicode() - '0';
7416  if (uint(escape) >= 10U)
7417  return -1;
7418  ++i;
7419  while (i < len) {
7420  int digit = uc[i].unicode() - '0';
7421  if (uint(digit) >= 10U)
7422  break;
7423  escape = (escape * 10) + digit;
7424  ++i;
7425  }
7426  if (escape <= maxNumber) {
7427  *pos = i;
7428  return escape;
7429  }
7430  }
7431  return -1;
7432 }
7433 
7434 QString QString::multiArg(int numArgs, const QString **args) const
7435 {
7436  QString result;
7437  QMap<int, int> numbersUsed;
7438  const QChar *uc = (const QChar *) d->data;
7439  const int len = d->size;
7440  const int end = len - 1;
7441  int lastNumber = -1;
7442  int i = 0;
7443 
7444  // populate the numbersUsed map with the %n's that actually occur in the string
7445  while (i < end) {
7446  if (uc[i] == QLatin1Char('%')) {
7447  int number = getEscape(uc, &i, len);
7448  if (number != -1) {
7449  numbersUsed.insert(number, -1);
7450  continue;
7451  }
7452  }
7453  ++i;
7454  }
7455 
7456  // assign an argument number to each of the %n's
7457  QMap<int, int>::iterator j = numbersUsed.begin();
7458  QMap<int, int>::iterator jend = numbersUsed.end();
7459  int arg = 0;
7460  while (j != jend && arg < numArgs) {
7461  *j = arg++;
7462  lastNumber = j.key();
7463  ++j;
7464  }
7465 
7466  // sanity
7467  if (numArgs > arg) {
7468  qWarning("QString::arg: %d argument(s) missing in %s", numArgs - arg, toLocal8Bit().data());
7469  numArgs = arg;
7470  }
7471 
7472  i = 0;
7473  while (i < len) {
7474  if (uc[i] == QLatin1Char('%') && i != end) {
7475  int number = getEscape(uc, &i, len, lastNumber);
7476  int arg = numbersUsed[number];
7477  if (number != -1 && arg != -1) {
7478  result += *args[arg];
7479  continue;
7480  }
7481  }
7482  result += uc[i++];
7483  }
7484  return result;
7485 }
7486 
7487 static bool isStringRightToLeft(const ushort *p, const ushort *end)
7488 {
7489  bool righttoleft = false;
7490  while (p < end) {
7491  switch(QChar::direction(*p))
7492  {
7493  case QChar::DirL:
7494  goto end;
7495  case QChar::DirR:
7496  case QChar::DirAL:
7497  righttoleft = true;
7498  goto end;
7499  default:
7500  break;
7501  }
7502  ++p;
7503  }
7504  end:
7505  return righttoleft;
7506 }
7507 
7511 {
7512  ushort *p = d->data;
7513  ushort *end = p + d->size;
7514  d->simpletext = true;
7515  while (p < end) {
7516  ushort uc = *p;
7517  // sort out regions of complex text formatting
7518  if (uc > 0x058f && (uc < 0x1100 || uc > 0xfb0f)) {
7519  d->simpletext = false;
7520  }
7521  p++;
7522  }
7523 
7524  d->righttoleft = isStringRightToLeft(d->data, d->data + d->size);
7525  d->clean = true;
7526 }
7527 
7529 {
7530  return isStringRightToLeft(d->data, d->data + d->size);
7531 }
7532 
7674 {
7675  Data *x = static_cast<Data *>(qMalloc(sizeof(Data)));
7676  Q_CHECK_PTR(x);
7677  if (unicode) {
7678  x->data = (ushort *)unicode;
7679  } else {
7680  x->data = x->array;
7681  size = 0;
7682  }
7683  x->ref = 1;
7684  x->alloc = x->size = size;
7685  *x->array = '\0';
7686  x->clean = x->asciiCache = x->simpletext = x->righttoleft = x->capacity = 0;
7687  return QString(x, 0);
7688 }
7689 
7708 {
7709  if (d->ref != 1 || (d->data == d->array && d->alloc)) {
7710  *this = fromRawData(unicode, size);
7711  } else {
7712 #ifdef QT3_SUPPORT
7713  if (d->asciiCache) {
7714  QMutexLocker locker(asciiCacheMutex());
7715  Q_ASSERT(asciiCache);
7716  asciiCache->remove(d);
7717  }
7718 #endif
7719  if (unicode) {
7720  d->data = (ushort *)unicode;
7721  } else {
7722  d->data = d->array;
7723  size = 0;
7724  }
7725  d->alloc = d->size = size;
7726  *d->array = '\0';
7727  d->clean = d->asciiCache = d->simpletext = d->righttoleft = d->capacity = 0;
7728  }
7729  return *this;
7730 }
7731 
7983 /* \fn bool operator==(const QLatin1String &s1, const QLatin1String &s2)
7984  \relates QLatin1String
7985 
7986  Returns true if string \a s1 is lexically equal to string \a s2; otherwise
7987  returns false.
7988 */
7989 /* \fn bool operator!=(const QLatin1String &s1, const QLatin1String &s2)
7990  \relates QLatin1String
7991 
7992  Returns true if string \a s1 is lexically unequal to string \a s2; otherwise
7993  returns false.
7994 */
7995 /* \fn bool operator<(const QLatin1String &s1, const QLatin1String &s2)
7996  \relates QLatin1String
7997 
7998  Returns true if string \a s1 is lexically smaller than string \a s2; otherwise
7999  returns false.
8000 */
8001 /* \fn bool operator<=(const QLatin1String &s1, const QLatin1String &s2)
8002  \relates QLatin1String
8003 
8004  Returns true if string \a s1 is lexically smaller than or equal to string \a s2; otherwise
8005  returns false.
8006 */
8007 /* \fn bool operator>(const QLatin1String &s1, const QLatin1String &s2)
8008  \relates QLatin1String
8009 
8010  Returns true if string \a s1 is lexically greater than string \a s2; otherwise
8011  returns false.
8012 */
8013 /* \fn bool operator>=(const QLatin1String &s1, const QLatin1String &s2)
8014  \relates QLatin1String
8015 
8016  Returns true if string \a s1 is lexically greater than or equal to
8017  string \a s2; otherwise returns false.
8018 */
8019 
8020 
8021 #if !defined(QT_NO_DATASTREAM) || (defined(QT_BOOTSTRAPPED) && !defined(QT_BUILD_QMAKE))
8022 
8035 {
8036  if (out.version() == 1) {
8037  out << str.toLatin1();
8038  } else {
8039  if (!str.isNull() || out.version() < 3) {
8040  if ((out.byteOrder() == QDataStream::BigEndian) == (QSysInfo::ByteOrder == QSysInfo::BigEndian)) {
8041  out.writeBytes(reinterpret_cast<const char *>(str.unicode()), sizeof(QChar) * str.length());
8042  } else {
8043  QVarLengthArray<ushort> buffer(str.length());
8044  const ushort *data = reinterpret_cast<const ushort *>(str.constData());
8045  for (int i = 0; i < str.length(); i++) {
8046  buffer[i] = qbswap(*data);
8047  ++data;
8048  }
8049  out.writeBytes(reinterpret_cast<const char *>(buffer.data()), sizeof(ushort) * buffer.size());
8050  }
8051  } else {
8052  // write null marker
8053  out << (quint32)0xffffffff;
8054  }
8055  }
8056  return out;
8057 }
8058 
8072 {
8073 #ifdef QT_QSTRING_UCS_4
8074 #if defined(Q_CC_GNU)
8075 #warning "operator>> not working properly"
8076 #endif
8077 #endif
8078 
8079  if (in.version() == 1) {
8080  QByteArray l;
8081  in >> l;
8082  str = QString::fromLatin1(l);
8083  } else {
8084  quint32 bytes = 0;
8085  in >> bytes; // read size of string
8086  if (bytes == 0xffffffff) { // null string
8087  str.clear();
8088  } else if (bytes > 0) { // not empty
8089  if (bytes & 0x1) {
8090  str.clear();
8092  return in;
8093  }
8094 
8095  const quint32 Step = 1024 * 1024;
8096  quint32 len = bytes / 2;
8097  quint32 allocated = 0;
8098 
8099  while (allocated < len) {
8100  int blockSize = qMin(Step, len - allocated);
8101  str.resize(allocated + blockSize);
8102  if (in.readRawData(reinterpret_cast<char *>(str.data()) + allocated * 2,
8103  blockSize * 2) != blockSize * 2) {
8104  str.clear();
8106  return in;
8107  }
8108  allocated += blockSize;
8109  }
8110 
8111  if ((in.byteOrder() == QDataStream::BigEndian)
8112  != (QSysInfo::ByteOrder == QSysInfo::BigEndian)) {
8113  ushort *data = reinterpret_cast<ushort *>(str.data());
8114  while (len--) {
8115  *data = qbswap(*data);
8116  ++data;
8117  }
8118  }
8119  } else {
8120  str = QLatin1String("");
8121  }
8122  }
8123  return in;
8124 }
8125 #endif // QT_NO_DATASTREAM
8126 
8654  if (!m_string)
8655  return QString();
8656  if (m_size && m_position == 0 && m_size == m_string->size())
8657  return *m_string;
8658  return QString(m_string->unicode() + m_position, m_size);
8659 }
8660 
8661 
8670 bool operator==(const QStringRef &s1,const QStringRef &s2)
8671 { return (s1.size() == s2.size() &&
8672  qMemEquals((const ushort *)s1.unicode(), (const ushort *)s2.unicode(), s1.size()));
8673 }
8674 
8683 bool operator==(const QString &s1,const QStringRef &s2)
8684 { return (s1.size() == s2.size() &&
8685  qMemEquals((const ushort *)s1.unicode(), (const ushort *)s2.unicode(), s1.size()));
8686 }
8687 
8696 bool operator==(const QLatin1String &s1, const QStringRef &s2)
8697 {
8698  const ushort *uc = reinterpret_cast<const ushort *>(s2.unicode());
8699  const ushort *e = uc + s2.size();
8700  const uchar *c = reinterpret_cast<const uchar *>(s1.latin1());
8701  if (!c)
8702  return s2.isEmpty();
8703 
8704  while (*c) {
8705  if (uc == e || *uc != *c)
8706  return false;
8707  ++uc;
8708  ++c;
8709  }
8710  return (uc == e);
8711 }
8712 
8727 bool operator<(const QStringRef &s1,const QStringRef &s2)
8728 {
8729  return ucstrcmp(s1.constData(), s1.length(), s2.constData(), s2.length()) < 0;
8730 }
8731 
8829 {
8830  if (!string)
8831  return QStringRef();
8832  int pos = string->size();
8833  string->insert(pos, unicode(), size());
8834  return QStringRef(string, pos, size());
8835 }
8836 
9018 {
9019  if (str.string() == this) {
9020  str.appendTo(this);
9021  } else if (str.string()) {
9022  int oldSize = size();
9023  resize(oldSize + str.size());
9024  memcpy(data() + oldSize, str.unicode(), str.size() * sizeof(QChar));
9025  }
9026  return *this;
9027 }
9028 
9046 {
9047  if (n >= d->size || n < 0)
9048  n = d->size;
9049  return QStringRef(this, 0, n);
9050 }
9051 
9069 {
9070  if (n >= d->size || n < 0)
9071  n = d->size;
9072  return QStringRef(this, d->size - n, n);
9073 }
9074 
9100 {
9101  if (d == &shared_null || position >= d->size)
9102  return QStringRef();
9103  if (n < 0)
9104  n = d->size - position;
9105  if (position < 0) {
9106  n += position;
9107  position = 0;
9108  }
9109  if (n + position > d->size)
9110  n = d->size - position;
9111  return QStringRef(this, position, n);
9112 }
9113 
9132 int QStringRef::indexOf(const QString &str, int from, Qt::CaseSensitivity cs) const
9133 {
9134  return qFindString(unicode(), length(), from, str.unicode(), str.length(), cs);
9135 }
9136 
9150 int QStringRef::indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
9151 {
9152  return findChar(unicode(), length(), ch, from, cs);
9153 }
9154 
9174 {
9175  return qt_find_latin1_string(unicode(), size(), str, from, cs);
9176 }
9177 
9195 int QStringRef::indexOf(const QStringRef &str, int from, Qt::CaseSensitivity cs) const
9196 {
9197  return qFindString(unicode(), size(), from, str.unicode(), str.size(), cs);
9198 }
9199 
9217 int QStringRef::lastIndexOf(const QString &str, int from, Qt::CaseSensitivity cs) const
9218 {
9219  const int sl = str.size();
9220  if (sl == 1)
9221  return lastIndexOf(str.at(0), from, cs);
9222 
9223  const int l = size();;
9224  if (from < 0)
9225  from += l;
9226  int delta = l - sl;
9227  if (from == l && sl == 0)
9228  return from;
9229  if (from < 0 || from >= l || delta < 0)
9230  return -1;
9231  if (from > delta)
9232  from = delta;
9233 
9234  return lastIndexOfHelper(reinterpret_cast<const ushort*>(unicode()), from,
9235  reinterpret_cast<const ushort*>(str.unicode()), str.size(), cs);
9236 }
9237 
9251 {
9252  return qt_last_index_of(unicode(), size(), ch, from, cs);
9253 }
9254 
9274 {
9275  const int sl = qstrlen(str.latin1());
9276  if (sl == 1)
9277  return lastIndexOf(QLatin1Char(str.latin1()[0]), from, cs);
9278 
9279  const int l = size();
9280  if (from < 0)
9281  from += l;
9282  int delta = l - sl;
9283  if (from == l && sl == 0)
9284  return from;
9285  if (from < 0 || from >= l || delta < 0)
9286  return -1;
9287  if (from > delta)
9288  from = delta;
9289 
9291  for (int i = 0; i < sl; ++i)
9292  s[i] = str.latin1()[i];
9293 
9294  return lastIndexOfHelper(reinterpret_cast<const ushort*>(unicode()), from, s.data(), sl, cs);
9295 }
9296 
9315 int QStringRef::lastIndexOf(const QStringRef &str, int from, Qt::CaseSensitivity cs) const
9316 {
9317  const int sl = str.size();
9318  if (sl == 1)
9319  return lastIndexOf(str.at(0), from, cs);
9320 
9321  const int l = size();
9322  if (from < 0)
9323  from += l;
9324  int delta = l - sl;
9325  if (from == l && sl == 0)
9326  return from;
9327  if (from < 0 || from >= l || delta < 0)
9328  return -1;
9329  if (from > delta)
9330  from = delta;
9331 
9332  return lastIndexOfHelper(reinterpret_cast<const ushort*>(unicode()), from,
9333  reinterpret_cast<const ushort*>(str.unicode()),
9334  str.size(), cs);
9335 }
9336 
9351 {
9352  return qt_string_count(unicode(), size(), str.unicode(), str.size(), cs);
9353 }
9354 
9371 {
9372  return qt_string_count(unicode(), size(), ch, cs);
9373 }
9374 
9391 {
9392  return qt_string_count(unicode(), size(), str.unicode(), str.size(), cs);
9393 }
9394 
9410 {
9411  return qt_starts_with(isNull() ? 0 : unicode(), size(),
9412  str.isNull() ? 0 : str.unicode(), str.size(), cs);
9413 }
9414 
9421 {
9422  return qt_starts_with(isNull() ? 0 : unicode(), size(), str, cs);
9423 }
9424 
9431 {
9432  return qt_starts_with(isNull() ? 0 : unicode(), size(),
9433  str.isNull() ? 0 : str.unicode(), str.size(), cs);
9434 }
9435 
9452 {
9453  if (!isEmpty()) {
9454  const ushort *data = reinterpret_cast<const ushort*>(unicode());
9455  return (cs == Qt::CaseSensitive
9456  ? data[0] == ch
9457  : foldCase(data[0]) == foldCase(ch.unicode()));
9458  } else {
9459  return false;
9460  }
9461 }
9462 
9477 {
9478  return qt_ends_with(isNull() ? 0 : unicode(), size(),
9479  str.isNull() ? 0 : str.unicode(), str.size(), cs);
9480 }
9481 
9498 {
9499  if (!isEmpty()) {
9500  const ushort *data = reinterpret_cast<const ushort*>(unicode());
9501  const int size = length();
9502  return (cs == Qt::CaseSensitive
9503  ? data[size - 1] == ch
9504  : foldCase(data[size - 1]) == foldCase(ch.unicode()));
9505  } else {
9506  return false;
9507  }
9508 }
9509 
9516 {
9517  return qt_ends_with(isNull() ? 0 : unicode(), size(), str, cs);
9518 }
9519 
9526 {
9527  return qt_ends_with(isNull() ? 0 : unicode(), size(),
9528  str.isNull() ? 0 : str.unicode(), str.size(), cs);
9529 }
9530 
9531 
9595 static inline int qt_last_index_of(const QChar *haystack, int haystackLen, const QChar &needle,
9596  int from, Qt::CaseSensitivity cs)
9597 {
9598  ushort c = needle.unicode();
9599  if (from < 0)
9600  from += haystackLen;
9601  if (from < 0 || from >= haystackLen)
9602  return -1;
9603  if (from >= 0) {
9604  const ushort *b = reinterpret_cast<const ushort*>(haystack);
9605  const ushort *n = b + from;
9606  if (cs == Qt::CaseSensitive) {
9607  for (; n >= b; --n)
9608  if (*n == c)
9609  return n - b;
9610  } else {
9611  c = foldCase(c);
9612  for (; n >= b; --n)
9613  if (foldCase(*n) == c)
9614  return n - b;
9615  }
9616  }
9617  return -1;
9618 
9619 
9620 }
9621 
9622 static inline int qt_string_count(const QChar *haystack, int haystackLen,
9623  const QChar *needle, int needleLen,
9625 {
9626  int num = 0;
9627  int i = -1;
9628  if (haystackLen > 500 && needleLen > 5) {
9629  QStringMatcher matcher(needle, needleLen, cs);
9630  while ((i = matcher.indexIn(haystack, haystackLen, i + 1)) != -1)
9631  ++num;
9632  } else {
9633  while ((i = qFindString(haystack, haystackLen, i + 1, needle, needleLen, cs)) != -1)
9634  ++num;
9635  }
9636  return num;
9637 }
9638 
9639 static inline int qt_string_count(const QChar *unicode, int size, const QChar &ch,
9641 {
9642  ushort c = ch.unicode();
9643  int num = 0;
9644  const ushort *b = reinterpret_cast<const ushort*>(unicode);
9645  const ushort *i = b + size;
9646  if (cs == Qt::CaseSensitive) {
9647  while (i != b)
9648  if (*--i == c)
9649  ++num;
9650  } else {
9651  c = foldCase(c);
9652  while (i != b)
9653  if (foldCase(*(--i)) == c)
9654  ++num;
9655  }
9656  return num;
9657 }
9658 
9659 static inline int qt_find_latin1_string(const QChar *haystack, int size,
9660  const QLatin1String &needle,
9661  int from, Qt::CaseSensitivity cs)
9662 {
9663  const char *latin1 = needle.latin1();
9664  int len = qstrlen(latin1);
9665  QVarLengthArray<ushort> s(len);
9666  for (int i = 0; i < len; ++i)
9667  s[i] = latin1[i];
9668 
9669  return qFindString(haystack, size, from,
9670  reinterpret_cast<const QChar*>(s.constData()), len, cs);
9671 }
9672 
9673 static inline bool qt_starts_with(const QChar *haystack, int haystackLen,
9674  const QChar *needle, int needleLen, Qt::CaseSensitivity cs)
9675 {
9676  if (!haystack)
9677  return !needle;
9678  if (haystackLen == 0)
9679  return needleLen == 0;
9680  if (needleLen > haystackLen)
9681  return false;
9682 
9683  const ushort *h = reinterpret_cast<const ushort*>(haystack);
9684  const ushort *n = reinterpret_cast<const ushort*>(needle);
9685 
9686  if (cs == Qt::CaseSensitive) {
9687  return qMemEquals(h, n, needleLen);
9688  } else {
9689  uint last = 0;
9690  uint olast = 0;
9691  for (int i = 0; i < needleLen; ++i)
9692  if (foldCase(h[i], last) != foldCase(n[i], olast))
9693  return false;
9694  }
9695  return true;
9696 }
9697 
9698 static inline bool qt_starts_with(const QChar *haystack, int haystackLen,
9699  const QLatin1String &needle, Qt::CaseSensitivity cs)
9700 {
9701  if (!haystack)
9702  return !needle.latin1();
9703  if (haystackLen == 0)
9704  return !needle.latin1() || *needle.latin1() == 0;
9705  const int slen = qstrlen(needle.latin1());
9706  if (slen > haystackLen)
9707  return false;
9708  const ushort *data = reinterpret_cast<const ushort*>(haystack);
9709  const uchar *latin = reinterpret_cast<const uchar*>(needle.latin1());
9710  if (cs == Qt::CaseSensitive) {
9711  for (int i = 0; i < slen; ++i)
9712  if (data[i] != latin[i])
9713  return false;
9714  } else {
9715  for (int i = 0; i < slen; ++i)
9716  if (foldCase(data[i]) != foldCase((ushort)latin[i]))
9717  return false;
9718  }
9719  return true;
9720 }
9721 
9722 static inline bool qt_ends_with(const QChar *haystack, int haystackLen,
9723  const QChar *needle, int needleLen, Qt::CaseSensitivity cs)
9724 {
9725  if (!haystack)
9726  return !needle;
9727  if (haystackLen == 0)
9728  return needleLen == 0;
9729  const int pos = haystackLen - needleLen;
9730  if (pos < 0)
9731  return false;
9732 
9733  const ushort *h = reinterpret_cast<const ushort*>(haystack);
9734  const ushort *n = reinterpret_cast<const ushort*>(needle);
9735 
9736  if (cs == Qt::CaseSensitive) {
9737  return qMemEquals(h + pos, n, needleLen);
9738  } else {
9739  uint last = 0;
9740  uint olast = 0;
9741  for (int i = 0; i < needleLen; i++)
9742  if (foldCase(h[pos+i], last) != foldCase(n[i], olast))
9743  return false;
9744  }
9745  return true;
9746 }
9747 
9748 
9749 static inline bool qt_ends_with(const QChar *haystack, int haystackLen,
9750  const QLatin1String &needle, Qt::CaseSensitivity cs)
9751 {
9752  if (!haystack)
9753  return !needle.latin1();
9754  if (haystackLen == 0)
9755  return !needle.latin1() || *needle.latin1() == 0;
9756  const int slen = qstrlen(needle.latin1());
9757  int pos = haystackLen - slen;
9758  if (pos < 0)
9759  return false;
9760  const uchar *latin = reinterpret_cast<const uchar*>(needle.latin1());
9761  const ushort *data = reinterpret_cast<const ushort*>(haystack);
9762  if (cs == Qt::CaseSensitive) {
9763  for (int i = 0; i < slen; i++)
9764  if (data[pos+i] != latin[i])
9765  return false;
9766  } else {
9767  for (int i = 0; i < slen; i++)
9768  if (foldCase(data[pos+i]) != foldCase((ushort)latin[i]))
9769  return false;
9770  }
9771  return true;
9772 }
9773 
9789 {
9790  return toLatin1_helper(unicode(), length());
9791 }
9792 
9811 {
9812 #ifndef QT_NO_TEXTCODEC
9815 #endif // QT_NO_TEXTCODEC
9816  return toLatin1();
9817 }
9818 
9840 {
9841 #ifndef QT_NO_TEXTCODEC
9844 #endif // QT_NO_TEXTCODEC
9845  return toLatin1();
9846 }
9847 
9870 {
9871  if (isNull())
9872  return QByteArray();
9873 
9874  return QUtf8::convertFromUnicode(constData(), length(), 0);
9875 }
9876 
9891 {
9892  QVector<uint> v(length());
9893  uint *a = v.data();
9894  int len = toUcs4_helper<uint>(reinterpret_cast<const unsigned short *>(unicode()), length(), a);
9895  v.resize(len);
9896  return v;
9897 }
9898 
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qstring.cpp:6448
static QString fromWCharArray(const wchar_t *, int size=-1)
Returns a copy of the string, where the encoding of string depends on the size of wchar...
Definition: qstring.cpp:1019
static QTextCodec * codecForLocale()
Returns a pointer to the codec most suitable for this locale.
double d
Definition: qnumeric_p.h:62
const int blockSize
#define UNICODE_DATA_VERSION
int qFindString(const QChar *haystack, int haystackLen, int from, const QChar *needle, int needleLen, Qt::CaseSensitivity cs)
Definition: qstring.cpp:2753
QString toString() const
Returns a copy of the string reference as a QString object.
Definition: qstring.cpp:8653
QString section(QChar sep, int start, int end=-1, SectionFlags flags=SectionDefault) const
This function returns a section of the string.
Definition: qstring.h:781
const T * constData() const
iterator end()
Returns an STL-style iterator pointing to the imaginary character after the last character in the str...
Definition: qstring.h:894
const struct __CFString * CFStringRef
static QString convertToUnicode(const char *, int, QTextCodec::ConverterState *, DataEndianness=DetectEndianness)
Definition: qutfcodec.cpp:444
qlonglong toLongLong(bool *ok=0, int base=10) const
Returns the string converted to a long long using base base, which is 10 by default and must be betwe...
Definition: qstring.cpp:5943
float toFloat(bool *ok=0) const
Definition: qstring.cpp:6257
QString & sprintf(const char *format,...)
Safely builds a formatted string from the format string cformat and an arbitrary list of arguments...
Definition: qstring.cpp:5567
bool operator==(const QStringRef &s1, const QStringRef &s2)
Returns true if string reference s1 is lexically equal to string reference s2; otherwise returns fals...
Definition: qstring.cpp:8670
static QString fromLocal8Bit(const char *, int size=-1)
Returns a QString initialized with the first size characters of the 8-bit string str.
Definition: qstring.cpp:4245
static int qt_string_count(const QChar *haystack, int haystackLen, const QChar *needle, int needleLen, Qt::CaseSensitivity cs)
Definition: qstring.cpp:9622
void realloc()
Definition: qstring.cpp:1472
static int ucstrnicmp(const ushort *a, const ushort *b, int l)
Definition: qstring.cpp:221
QStringRef appendTo(QString *string) const
Appends the string reference to string, and returns a new reference to the combined string data...
Definition: qstring.cpp:8828
QIntegerForSizeof< void * >::Unsigned quintptr
Definition: qglobal.h:986
unsigned char c[8]
Definition: qnumeric_p.h:62
qint64 stringToLongLong(const QString &num, int base, bool *ok, GroupSeparatorMode group_sep_mode) const
Definition: qlocale.cpp:3105
static int localeAwareCompare_helper(const QChar *data1, int length1, const QChar *data2, int length2)
Definition: qstring.cpp:5212
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string reference starts with str; otherwise returns false.
Definition: qstring.cpp:9409
QString cap(int nth=0) const
Returns the text captured by the nth subexpression.
Definition: qregexp.cpp:4310
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
const Key key(const T &value) const
Returns the first key with value value.
Definition: qmap.h:844
The QMutex class provides access serialization between threads.
Definition: qmutex.h:60
int lastIndexIn(const QString &str, int offset=-1, CaretMode caretMode=CaretAtZero) const
Attempts to find a match backwards in str from position offset.
Definition: qregexp.cpp:4167
QString & operator=(QChar c)
Definition: qstring.cpp:1582
static QString fromAscii(const char *, int size=-1)
Returns a QString initialized with the first size characters from the string str. ...
Definition: qstring.cpp:4276
NormalizationForm
This enum describes the various normalized forms of Unicode text.
Definition: qstring.h:309
char * data()
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:429
qulonglong toULongLong(bool *ok=0, int base=10) const
Returns the string converted to an unsigned long long using base base, which is 10 by default and mus...
Definition: qstring.cpp:5984
int length() const
Returns the number of characters referred to by the string reference.
Definition: qstring.h:1116
int digitValue() const
Returns the numeric value of the digit, or -1 if the character is not a digit.
Definition: qchar.cpp:817
const QChar at(int i) const
Returns the character at the given index position in the string.
Definition: qstring.h:698
The QRegExp class provides pattern matching using regular expressions.
Definition: qregexp.h:61
void qbswap(const T src, uchar *dest)
Definition: qendian.h:74
int toInt(bool *ok=0, int base=10) const
Returns the string converted to an int using base base, which is 10 by default and must be between 2 ...
Definition: qstring.cpp:6090
ushort unicode() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qchar.h:251
ushort toUShort(bool *ok=0, int base=10) const
Returns the string converted to an unsigned short using base base, which is 10 by default and must be...
Definition: qstring.cpp:6180
QByteArray toAscii() const Q_REQUIRED_RESULT
Returns an 8-bit representation of the string as a QByteArray.
Definition: qstring.cpp:9810
#define QT_MAX_FLOAT
Returns the string converted to a float value.
Definition: qstring.cpp:6255
QByteArray toUtf8() const Q_REQUIRED_RESULT
Returns a UTF-8 representation of the string as a QByteArray.
Definition: qstring.cpp:4074
ByteOrder byteOrder() const
Returns the current byte order setting – either BigEndian or LittleEndian.
Definition: qdatastream.h:209
static bool qMemEquals(const quint16 *a, const quint16 *b, int length)
Definition: qstring.cpp:273
Q_CORE_EXPORT void qFree(void *ptr)
Definition: qmalloc.cpp:58
QString & replace(int i, int len, QChar after)
Definition: qstring.cpp:2005
void updateProperties() const
Definition: qstring.cpp:7510
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
ushort capacity
Definition: qstring.h:611
QString leftJustified(int width, QChar fill=QLatin1Char(' '), bool trunc=false) const Q_REQUIRED_RESULT
Returns a string of size width that contains this string padded by the fill character.
Definition: qstring.cpp:5318
void chop(int n)
Removes n characters from the end of the string.
Definition: qstring.cpp:4623
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
QString & prepend(QChar c)
Definition: qstring.h:261
QString toUpper() const Q_REQUIRED_RESULT
Returns an uppercase copy of the string.
Definition: qstring.cpp:5483
int toWCharArray(wchar_t *array) const
Fills the array with the data contained in this QString object.
Definition: qstring.cpp:1086
static qreal position(QGraphicsObject *item, QDeclarativeAnchorLine::AnchorLine anchorLine)
qt_section_chunk(int l, QString s)
Definition: qstring.cpp:3576
QByteArray toUtf8() const Q_REQUIRED_RESULT
Returns a UTF-8 representation of the string as a QByteArray.
Definition: qstring.cpp:9869
ushort clean
Definition: qstring.h:607
bool isLowSurrogate() const
Returns true if the QChar is the low part of a utf16 surrogate (ie.
Definition: qchar.h:279
int matchedLength() const
Returns the length of the last matched string, or -1 if there was no match.
Definition: qregexp.cpp:4193
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
Definition: qstring.cpp:3734
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
quint16 u
long ASN1_INTEGER_get ASN1_INTEGER * a
void setStatus(Status status)
Sets the status of the data stream to the status given.
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
Q_CORE_EXPORT void * qMalloc(size_t size)
Definition: qmalloc.cpp:53
Q_CORE_EXPORT void * qRealloc(void *ptr, size_t size)
Definition: qmalloc.cpp:63
The QString class provides a Unicode character string.
Definition: qstring.h:83
QString normalized(NormalizationForm mode) const Q_REQUIRED_RESULT
Returns the string in the given Unicode normalization mode.
Definition: qstring.cpp:6635
The QHash class is a template class that provides a hash-table-based dictionary.
Definition: qdatastream.h:66
QString & vsprintf(const char *format, va_list ap)
Equivalent method to sprintf(), but takes a va_list ap instead a list of variable arguments...
Definition: qstring.cpp:5587
QString multiArg(int numArgs, const QString **args) const
Definition: qstring.cpp:7434
static QByteArray toLatin1_helper(const QChar *data, int length)
Definition: qstring.cpp:3924
bool isHighSurrogate() const
Returns true if the QChar is the high part of a utf16 surrogate (ie.
Definition: qchar.h:276
Q_DECL_CONSTEXPR T qAbs(const T &t)
Definition: qglobal.h:1201
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
#define Q_BASIC_ATOMIC_INITIALIZER(a)
Definition: qbasicatomic.h:218
bool qIsDigit(char ch)
Definition: qstring.cpp:367
QChar toCaseFolded() const
Returns the case folded equivalent of the character.
Definition: qchar.cpp:1406
static bool isStringRightToLeft(const ushort *p, const ushort *end)
Definition: qstring.cpp:7487
static const uint base
Definition: qurl.cpp:268
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
QChar * data()
Returns a pointer to the data stored in the QString.
Definition: qstring.h:710
static int qt_find_latin1_string(const QChar *hay, int size, const QLatin1String &needle, int from, Qt::CaseSensitivity cs)
Definition: qstring.cpp:9659
static QString fromRawData(const QChar *, int size)
Constructs a QString that uses the first size Unicode characters in the array unicode.
Definition: qstring.cpp:7673
static QByteArray convertFromUnicode(const QChar *, int, QTextCodec::ConverterState *)
Definition: qutfcodec.cpp:64
The QStringMatcher class holds a sequence of characters that can be quickly matched in a Unicode stri...
QBasicAtomicInt ref
Definition: qstring.h:604
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
NumberOptions numberOptions() const
Returns the options related to number conversions for this QLocale instance.
Definition: qlocale.cpp:802
bool isSpace() const
Returns true if the character is a separator character (Separator_* categories); otherwise returns fa...
Definition: qchar.cpp:609
QString repeated(int times) const
Returns a copy of this string repeated the specified number of times.
Definition: qstring.cpp:6657
bool isEmpty() const
Returns true if the list contains no items; otherwise returns false.
Definition: qlist.h:152
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string reference ends with str; otherwise returns false.
Definition: qstring.cpp:9476
void resize(int size)
Sets the size of the vector to size.
Definition: qvector.h:342
static ushort highSurrogate(uint ucs4)
Returns the high surrogate value of a ucs4 code point.
Definition: qchar.h:303
QString & setRawData(const QChar *unicode, int size)
Resets the QString to use the first size Unicode characters in the array unicode. ...
Definition: qstring.cpp:7707
static QString doubleToString(const QChar zero, const QChar plus, const QChar minus, const QChar exponent, const QChar group, const QChar decimal, double d, int precision, DoubleForm form, int width, unsigned flags)
Definition: qlocale.cpp:2613
QStringRef leftRef(int n) const Q_REQUIRED_RESULT
Returns a substring reference to the n leftmost characters of the string.
Definition: qstring.cpp:9045
static ushort lowSurrogate(uint ucs4)
Returns the low surrogate value of a ucs4 code point.
Definition: qchar.h:306
const QChar * constData() const
Same as unicode().
Definition: qstring.h:1159
static void free(Data *)
Definition: qstring.cpp:1311
QByteArray toLocal8Bit() const Q_REQUIRED_RESULT
Returns the local 8-bit representation of the string as a QByteArray.
Definition: qstring.cpp:9839
static void decomposeHelper(QString *str, bool canonical, QChar::UnicodeVersion version, int from)
Definition: qchar.cpp:1698
void reserve(int size)
Attempts to allocate memory for at least size characters.
Definition: qstring.h:881
static const NormalizationCorrection uc_normalization_corrections[]
static Data shared_null
Definition: qstring.h:616
#define QT_RETHROW
Definition: qglobal.h:1539
unsigned char uchar
Definition: qglobal.h:994
static const ushort specialCaseMap[]
QString rightJustified(int width, QChar fill=QLatin1Char(' '), bool trunc=false) const Q_REQUIRED_RESULT
Returns a string of size() width that contains the fill character followed by the string...
Definition: qstring.cpp:5357
static QString unsLongLongToString(const QChar zero, const QChar group, const QChar plus, quint64 l, int precision, int base, int width, unsigned flags)
Definition: qlocale.cpp:2870
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
bool operator==(const QString &s) const
Returns true if string other is equal to this string; otherwise returns false.
Definition: qstring.cpp:2368
static int compare_helper(const QChar *data1, int length1, const QChar *data2, int length2, Qt::CaseSensitivity cs=Qt::CaseSensitive)
Definition: qstring.cpp:5059
static QString longLongToString(const QChar zero, const QChar group, const QChar plus, const QChar minus, qint64 l, int precision, int base, int width, unsigned flags)
Definition: qlocale.cpp:2775
int size() const
Returns the number of characters referred to by the string reference.
Definition: qstring.h:1114
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
static bool requiresSurrogates(uint ucs4)
Returns true if the UCS-4-encoded character specified by ucs4 can be split into the high and low part...
Definition: qchar.h:294
const char * latin1() const
Returns the Latin-1 string stored in this object.
Definition: qstring.h:661
quint64 stringToUnsLongLong(const QString &num, int base, bool *ok, GroupSeparatorMode group_sep_mode) const
Definition: qlocale.cpp:3119
QByteArray fromUnicode(const QString &uc) const
Converts str from Unicode to the encoding of this codec, and returns the result in a QByteArray...
int qAllocMore(int alloc, int extra)
Definition: qbytearray.cpp:70
void truncate(int pos)
Truncates the string at the given position index.
Definition: qstring.cpp:4603
int indexIn(const QString &str, int offset=0, CaretMode caretMode=CaretAtZero) const
Attempts to find a match in str from position offset (0 by default).
Definition: qregexp.cpp:4136
int readRawData(char *, int len)
Reads at most len bytes from the stream into s and returns the number of bytes read.
unsigned __int64 quint64
Definition: qglobal.h:943
QString left(int n) const Q_REQUIRED_RESULT
Returns a substring that contains the n leftmost characters of the string.
Definition: qstring.cpp:3664
bool operator<(const QStringRef &s1, const QStringRef &s2)
Returns true if string reference s1 is lexically less than string reference s2; otherwise returns fal...
Definition: qstring.cpp:8727
static int qt_last_index_of(const QChar *haystack, int haystackLen, const QChar &needle, int from, Qt::CaseSensitivity cs)
Definition: qstring.cpp:9595
QStringRef rightRef(int n) const Q_REQUIRED_RESULT
Returns a substring reference to the n rightmost characters of the string.
Definition: qstring.cpp:9068
double stringToDouble(const QString &num, bool *ok, GroupSeparatorMode group_sep_mode) const
Definition: qlocale.cpp:3092
QString trimmed() const Q_REQUIRED_RESULT
Returns a string that has whitespace removed from the start and the end.
Definition: qstring.cpp:4506
int size() const
Returns the number of characters in this string.
Definition: qstring.h:102
const QChar * unicode() const
Returns a &#39;\0&#39;-terminated Unicode representation of the string.
Definition: qstring.h:706
QString & setNum(short, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qstring.h:729
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
QDataStream & writeBytes(const char *, uint len)
Writes the length specifier len and the buffer s to the stream and returns a reference to the stream...
bool isRightToLeft() const
Returns true if the string is read right to left.
Definition: qstring.cpp:7528
static QString convertToUnicode(const char *, int, QTextCodec::ConverterState *)
Definition: qutfcodec.cpp:156
static int ucstrncmp(const QChar *a, const QChar *b, int l)
Definition: qstring.cpp:201
void replace_helper(uint *indices, int nIndices, int blen, const QChar *after, int alen)
Definition: qstring.cpp:2039
#define Q_GLOBAL_STATIC(TYPE, NAME)
Declares a global static variable with the given type and name.
Definition: qglobal.h:1968
void expand(int i)
Definition: qstring.cpp:1477
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
static int ucstricmp(const ushort *a, const ushort *ae, const ushort *b, const ushort *be)
Definition: qstring.cpp:141
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
static QString fromUtf8(const char *, int size=-1)
Returns a QString initialized with the first size bytes of the UTF-8 string str.
Definition: qstring.cpp:4302
static const QUnicodeTables::Properties * qGetProp(uint ucs4)
bool qt_ucol_strcoll(const QChar *source, int sourceLength, const QChar *target, int targetLength, int *result)
unsigned short quint16
Definition: qglobal.h:936
Q_CORE_EXPORT void qWarning(const char *,...)
bool isEmpty() const
Returns true if the string reference has no characters; otherwise returns false.
Definition: qstring.h:1169
QString toCaseFolded() const Q_REQUIRED_RESULT
Returns the case folded equivalent of the string.
Definition: qstring.cpp:5441
int count() const
Returns the number of characters referred to by the string reference.
Definition: qstring.h:1115
unsigned int uint
Definition: qglobal.h:996
int indexOf(const QString &str, int from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns the index position of the first occurrence of the string str in this string reference...
Definition: qstring.cpp:9132
int indexOf(QChar c, int from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.cpp:2838
static QString replaceArgEscapes(const QString &s, const ArgEscapeData &d, int field_width, const QString &arg, const QString &larg, const QChar &fillChar=QLatin1Char(' '))
Definition: qstring.cpp:6839
static Bigint * diff(Bigint *a, Bigint *b)
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal...
Definition: qstring.h:654
static QTextCodec * codec(MYSQL *mysql)
Definition: qsql_mysql.cpp:220
int toUcs4_helper(const unsigned short *uc, int length, T *out)
Definition: qstring.cpp:1047
static int getEscape(const QChar *uc, int *pos, int len, int maxNumber=999)
Definition: qstring.cpp:7408
const QChar * unicode() const
Returns a Unicode representation of the string reference.
Definition: qstring.h:1153
QString right(int n) const Q_REQUIRED_RESULT
Returns a substring that contains the n rightmost characters of the string.
Definition: qstring.cpp:3682
QByteArray toLatin1() const Q_REQUIRED_RESULT
Returns a Latin-1 representation of the string as a QByteArray.
Definition: qstring.cpp:3993
__int64 qint64
Definition: qglobal.h:942
static int cmp(const ushort *s1, const ushort *s2, size_t len)
unsigned long ulong
Definition: qglobal.h:997
void detach()
Definition: qstring.h:714
#define QT_CATCH(A)
Definition: qglobal.h:1537
QByteArray toLocal8Bit() const Q_REQUIRED_RESULT
Returns the local 8-bit representation of the string as a QByteArray.
Definition: qstring.cpp:4049
bool operator>(const QString &s) const
Returns true if this string is lexically greater than string other; otherwise returns false...
Definition: qstring.h:405
int locale_occurrences
Definition: qstring.cpp:6775
UnicodeVersion
Specifies which version of the [Unicode standard](http://www.
Definition: qchar.h:212
int count() const
Definition: qstring.h:103
int localeAwareCompare(const QString &s) const
Definition: qstring.cpp:5197
The QStringRef class provides a thin wrapper around QString substrings.
Definition: qstring.h:1099
QDataStream & operator<<(QDataStream &stream, const QString &string)
Writes the given string to the specified stream.
Definition: qstring.cpp:8034
static Data * fromAscii_helper(const char *str, int size=-1)
Definition: qstring.cpp:4155
Q_GUI_EXPORT QString escape(const QString &plain)
Converts the plain text string plain to a HTML string with HTML metacharacters <, >...
Data * d
Definition: qstring.h:618
int lastIndexOf(const QString &str, int from=-1, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns the index position of the last occurrence of the string str in this string reference...
Definition: qstring.cpp:9217
iterator begin()
Returns an STL-style iterator pointing to the first item in the map.
Definition: qmap.h:372
int version() const
Returns the version number of the data serialization format.
Definition: qdatastream.h:212
void resize(int size)
Sets the size of the string to size characters.
Definition: qstring.cpp:1353
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
static uint foldCase(const ushort *ch, const ushort *start)
Definition: qchar.cpp:1380
bool isNull() const
Returns true if this string is null; otherwise returns false.
Definition: qstring.h:505
QString toUnicode(const QByteArray &) const
Converts a from the encoding of this codec to Unicode, and returns the result in a QString...
static int findChar(const QChar *str, int len, QChar ch, int from, Qt::CaseSensitivity cs)
Returns the index position of the first occurrence of the character ch in the string given by str and...
Definition: qstring.cpp:333
ushort * data
Definition: qstring.h:606
QStringRef midRef(int position, int n=-1) const Q_REQUIRED_RESULT
Returns a substring reference to n characters of this string, starting at the specified position...
Definition: qstring.cpp:9099
QString mid(int position, int n=-1) const Q_REQUIRED_RESULT
Returns a string that contains n characters of this string, starting at the specified position index...
Definition: qstring.cpp:3706
CaseSensitivity
Definition: qnamespace.h:1451
int qFindStringBoyerMoore(const QChar *haystack, int haystackLen, int from, const QChar *needle, int needleLen, Qt::CaseSensitivity cs)
uint qstrlen(const char *str)
Definition: qbytearray.h:79
#define Q_CHECK_PTR(p)
Definition: qglobal.h:1853
#define REHASH(a)
Definition: qstring.cpp:357
const QLocalePrivate * d() const
Definition: qlocale.cpp:761
The QMutexLocker class is a convenience class that simplifies locking and unlocking mutexes...
Definition: qmutex.h:101
QString arg(qlonglong a, int fieldwidth=0, int base=10, const QChar &fillChar=QLatin1Char(' ')) const Q_REQUIRED_RESULT
Definition: qstring.cpp:7186
static QLocale c()
Returns a QLocale object initialized to the "C" locale.
Definition: qlocale.h:773
QString & append(QChar c)
Definition: qstring.cpp:1777
int compare(const QString &s) const
Definition: qstring.cpp:5037
const QString * string() const
Returns a pointer to the string referred to by the string reference, or 0 if it does not reference a ...
Definition: qstring.h:1112
static ArgEscapeData findArgEscapes(const QString &s)
Definition: qstring.cpp:6780
QString simplified() const Q_REQUIRED_RESULT
Returns a string that has whitespace removed from the start and the end, and that has each sequence o...
Definition: qstring.cpp:4415
QDataStream & operator>>(QDataStream &stream, QString &string)
Reads a string from the specified stream into the given string.
Definition: qstring.cpp:8071
void clear()
Clears the contents of the string and makes it empty.
Definition: qstring.h:723
int captureCount() const
Returns the number of captures contained in the regular expression.
Definition: qregexp.cpp:4223
unsigned short ushort
Definition: qglobal.h:995
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the map...
Definition: qmap.h:375
bool operator==(const QString &s1, const QStringRef &s2)
Returns true if string s1 is lexically equal to string reference s2; otherwise returns false...
Definition: qstring.cpp:8683
int lastIndexOf(QChar c, int from=-1, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.cpp:3000
static QString fromLatin1(const char *, int size=-1)
Returns a QString initialized with the first size characters of the Latin-1 string str...
Definition: qstring.cpp:4188
iterator insert(const Key &key, const T &value)
Inserts a new item with the key key and a value of value.
Definition: qmap.h:559
#define SPECIAL_CASE_MAX_LEN
bool operator==(const QLatin1String &s1, const QStringRef &s2)
Returns true if string s1 is lexically equal to string reference s2; otherwise returns false...
Definition: qstring.cpp:8696
QVector< uint > toUcs4() const Q_REQUIRED_RESULT
Returns a UCS-4/UTF-32 representation of the string as a QVector<uint>.
Definition: qstring.cpp:9890
QString toLower() const Q_REQUIRED_RESULT
Returns a lowercase copy of the string.
Definition: qstring.cpp:5389
void resize(int size)
Sets the size of the byte array to size bytes.
unsigned int quint32
Definition: qglobal.h:938
double toDouble(bool *ok=0) const
Returns the string converted to a double value.
Definition: qstring.cpp:6227
int size() const
Returns the number of items in the list.
Definition: qlist.h:137
static QTextCodec * codecForCStrings
Definition: qstring.h:621
QByteArray toAscii() const Q_REQUIRED_RESULT
Returns an 8-bit representation of the string as a QByteArray.
Definition: qstring.cpp:4014
QString & fill(QChar c, int size=-1)
Sets every character in the string to character ch.
Definition: qstring.cpp:4641
uint toUInt(bool *ok=0, int base=10) const
Returns the string converted to an unsigned int using base base, which is 10 by default and must be b...
Definition: qstring.cpp:6120
static QString convertToUnicode(const char *, int, QTextCodec::ConverterState *, DataEndianness=DetectEndianness)
Definition: qutfcodec.cpp:313
ushort array[1]
Definition: qstring.h:614
if(void) toggleToolbarShown
static int lastIndexOfHelper(const ushort *haystack, int from, const ushort *needle, int sl, Qt::CaseSensitivity cs)
Definition: qstring.cpp:2863
QFactoryLoader * l
friend class QStringRef
Definition: qstring.h:644
static uint surrogateToUcs4(ushort high, ushort low)
Converts a UTF16 surrogate pair with the given high and low values to its UCS-4 code point...
Definition: qchar.h:297
int indexIn(const QString &str, int from=0) const
Searches the string str from character position from (default 0, i.e.
quint16 index
ushort righttoleft
Definition: qstring.h:609
static bool qt_starts_with(const QChar *haystack, int haystackLen, const QChar *needle, int needleLen, Qt::CaseSensitivity cs)
Definition: qstring.cpp:9673
short toShort(bool *ok=0, int base=10) const
Returns the string converted to a short using base base, which is 10 by default and must be between 2...
Definition: qstring.cpp:6150
static void composeHelper(QString *str, QChar::UnicodeVersion version, int from)
Definition: qchar.cpp:1776
#define CSTR_GREATER_THAN
Definition: qstring.cpp:5181
bool qIsUpper(char ch)
Definition: qstring.cpp:362
Initialization
Definition: qnamespace.h:1729
CaretMode
The CaretMode enum defines the different meanings of the caret (^) in a regular expression.
Definition: qregexp.h:71
T * data()
Returns a pointer to the data stored in the vector.
Definition: qvector.h:152
void setCaseSensitivity(Qt::CaseSensitivity cs)
Sets case sensitive matching to cs.
Definition: qregexp.cpp:3998
QString & setUtf16(const ushort *utf16, int size)
Resizes the string to size characters and copies unicode into the string.
Definition: qstring.h:882
QStringList split(const QString &sep, SplitBehavior behavior=KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const Q_REQUIRED_RESULT
Splits the string into substrings wherever sep occurs, and returns the list of those strings...
Definition: qstring.cpp:6526
QByteArray toLatin1() const Q_REQUIRED_RESULT
Returns a Latin-1 representation of the string as a QByteArray.
Definition: qstring.cpp:9788
The QDataStream class provides serialization of binary data to a QIODevice.
Definition: qdatastream.h:71
quint64 qulonglong
Definition: qglobal.h:952
static const Null null
Definition: qstring.h:502
static int ucstrcmp(const QChar *a, int alen, const QChar *b, int blen)
Definition: qstring.cpp:211
bool isNull() const
Returns true if string() returns a null pointer or a pointer to a null string; otherwise returns true...
Definition: qstring.h:1170
Direction direction() const
Returns the character&#39;s direction.
Definition: qchar.cpp:889
static Data * fromLatin1_helper(const char *str, int size=-1)
Definition: qstring.cpp:4104
QString & remove(int i, int len)
Removes n characters from the string, starting at the given position index, and returns a reference t...
Definition: qstring.cpp:1867
The QTextCodec class provides conversions between text encodings.
Definition: qtextcodec.h:62
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string ends with s; otherwise returns false.
Definition: qstring.cpp:3796
static void canonicalOrderHelper(QString *str, QChar::UnicodeVersion version, int from)
Definition: qchar.cpp:1821
ushort simpletext
Definition: qstring.h:608
qint64 qlonglong
Definition: qglobal.h:951
QVector< uint > toUcs4() const Q_REQUIRED_RESULT
Returns a UCS-4/UTF-32 representation of the string as a QVector<uint>.
Definition: qstring.cpp:4095
static int grow(int)
Definition: qstring.cpp:822
ushort asciiCache
Definition: qstring.h:610
QString & insert(int i, QChar c)
Definition: qstring.cpp:1671
ulong toULong(bool *ok=0, int base=10) const
Returns the string converted to an unsigned long using base base, which is 10 by default and must be ...
Definition: qstring.cpp:6059
#define QT_TRY
Definition: qglobal.h:1536
SplitBehavior
This enum specifies how the split() function should behave with respect to empty strings.
Definition: qstring.h:299
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
QString & setUnicode(const QChar *unicode, int size)
Resizes the string to size characters and copies unicode into the string.
Definition: qstring.cpp:4377
#define CSTR_LESS_THAN
Definition: qstring.cpp:5179
#define INT_MAX
const QChar * constData() const
Returns a pointer to the data stored in the QString.
Definition: qstring.h:712
const QChar at(int i) const
Returns the character at the given index position in the string reference.
Definition: qstring.h:1174
char qToLower(char ch)
Definition: qstring.cpp:372
void qt_string_normalize(QString *data, QString::NormalizationForm mode, QChar::UnicodeVersion version, int from)
Definition: qstring.cpp:6710
static QString fromUtf16(const ushort *, int size=-1)
Returns a QString initialized with the first size characters of the Unicode string unicode (ISO-10646...
Definition: qstring.cpp:4329
bool operator<(const QString &s) const
Returns true if this string is lexically less than string other; otherwise returns false...
Definition: qstring.cpp:2436
QString()
Constructs a null string.
Definition: qstring.h:879
long toLong(bool *ok=0, int base=10) const
Returns the string converted to a long using base base, which is 10 by default and must be between 2 ...
Definition: qstring.cpp:6027
The QList class is a template class that provides lists.
Definition: qdatastream.h:62
static Data shared_empty
Definition: qstring.h:617
const ushort * utf16() const
Returns the QString as a &#39;\0\&#39;-terminated array of unsigned shorts.
Definition: qstring.cpp:5290
static bool qt_ends_with(const QChar *haystack, int haystackLen, const QChar *needle, int needleLen, Qt::CaseSensitivity cs)
Definition: qstring.cpp:9722
static QString fromUcs4(const uint *, int size=-1)
Returns a QString initialized with the first size characters of the Unicode string unicode (ISO-10646...
Definition: qstring.cpp:4356
#define forever
This macro is provided for convenience for writing infinite loops.
Definition: qglobal.h:2452