1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
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 The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#include <QtTest/QtTest>
30
31#define LITERAL "some literal"
32#define LITERAL_LEN (sizeof(LITERAL)-1)
33#define LITERAL_EXTRA "some literal" "EXTRA"
34
35// "some literal", but replacing all vowels by their umlauted UTF-8 string :)
36#define UTF8_LITERAL "s\xc3\xb6m\xc3\xab l\xc3\xaft\xc3\xabr\xc3\xa4l"
37#define UTF8_LITERAL_LEN (sizeof(UTF8_LITERAL)-1)
38#define UTF8_LITERAL_EXTRA "s\xc3\xb6m\xc3\xab l\xc3\xaft\xc3\xabr\xc3\xa4l" "EXTRA"
39
40#ifdef Q_COMPILER_UNICODE_STRINGS
41// "some literal", but replacing all vocals by their umlauted UTF-8 string :)
42#define UNICODE_LITERAL u"s\u00f6m\u00eb l\u00eft\u00ebr\u00e4l"
43#define UNICODE_LITERAL_LEN ((sizeof(UNICODE_LITERAL) - 1) / 2)
44#define UNICODE_LITERAL_EXTRA u"s\u00f6m\u00eb l\u00eft\u00ebr\u00e4l" "EXTRA"
45#endif
46
47#ifndef P
48# error You need to define P
49# define P +
50#endif
51
52//fix for gcc4.0: if the operator+ does not exist without QT_USE_FAST_OPERATOR_PLUS
53#ifndef QT_USE_FAST_CONCATENATION
54#define Q %
55#else
56#define Q P
57#endif
58
59template <typename T> QString toQString(const T &t);
60
61template <> QString toQString(const QString &s) { return s; }
62template <> QString toQString(const QStringRef &r) { return r.toString(); }
63template <> QString toQString(const QStringView &v) { return v.toString(); }
64template <> QString toQString(const QLatin1String &l) { return l; }
65template <> QString toQString(const QLatin1Char &l) { return QChar(l); }
66template <> QString toQString(const QChar &c) { return c; }
67template <> QString toQString(const QChar::SpecialCharacter &c) { return QChar(c); }
68#ifdef Q_COMPILER_UNICODE_STRINGS
69template <> QString toQString(char16_t * const &p) { return QStringView(p).toString(); }
70template <size_t N> QString toQString(const char16_t (&a)[N]) { return QStringView(a).toString(); }
71template <> QString toQString(const char16_t &c) { return QChar(c); }
72#endif
73
74template <typename T> QByteArray toQByteArray(const T &t);
75
76template <> QByteArray toQByteArray(const QByteArray &b) { return b; }
77template <> QByteArray toQByteArray(char * const &p) { return p; }
78template <size_t N> QByteArray toQByteArray(const char (&a)[N]) { return a; }
79template <> QByteArray toQByteArray(const char &c) { return QByteArray(&c, 1); }
80
81void runScenario()
82{
83 // this code is latin1. TODO: replace it with the utf8 block below, once
84 // strings default to utf8.
85 QLatin1String l1string(LITERAL);
86 QString string(l1string);
87 QStringRef stringref(&string, 2, 10);
88 QStringView stringview(stringref);
89 QLatin1Char lchar('c');
90 QChar qchar(lchar);
91 QChar::SpecialCharacter special(QChar::Nbsp);
92#ifdef Q_COMPILER_UNICODE_STRINGS
93 char16_t u16char = UNICODE_LITERAL[0];
94 char16_t u16chararray[] = { u's', 0xF6, u'm', 0xEB, u' ', u'l', 0xEF, u't', 0xEB, u'r', 0xE4, u'l', 0x00 };
95 QCOMPARE(QStringView(u16chararray), QStringView(UNICODE_LITERAL));
96 char16_t *u16charstar = u16chararray;
97#endif
98
99#define CHECK(QorP, a1, a2) \
100 do { \
101 DO(QorP, a1, a2); \
102 DO(QorP, a2, a1); \
103 } while (0)
104
105#define DO(QorP, a1, a2) \
106 QCOMPARE(QString(a1 QorP a2), \
107 toQString(a1).append(toQString(a2))) \
108 /* end */
109
110 CHECK(P, l1string, l1string);
111 CHECK(P, l1string, string);
112 CHECK(P, l1string, stringref);
113 CHECK(Q, l1string, stringview);
114 CHECK(P, l1string, lchar);
115 CHECK(P, l1string, qchar);
116 CHECK(P, l1string, special);
117 CHECK(P, l1string, QStringLiteral(LITERAL));
118 CHECK(Q, l1string, u16char);
119 CHECK(Q, l1string, u16chararray);
120 CHECK(Q, l1string, u16charstar);
121
122 CHECK(P, string, string);
123 CHECK(P, string, stringref);
124 CHECK(Q, string, stringview);
125 CHECK(P, string, lchar);
126 CHECK(P, string, qchar);
127 CHECK(P, string, special);
128 CHECK(P, string, QStringLiteral(LITERAL));
129 CHECK(Q, string, u16char);
130 CHECK(Q, string, u16chararray);
131 CHECK(Q, string, u16charstar);
132
133 CHECK(P, stringref, stringref);
134 CHECK(Q, stringref, stringview);
135 CHECK(P, stringref, lchar);
136 CHECK(P, stringref, qchar);
137 CHECK(P, stringref, special);
138 CHECK(P, stringref, QStringLiteral(LITERAL));
139 CHECK(Q, stringref, u16char);
140 CHECK(Q, stringref, u16chararray);
141 CHECK(Q, stringref, u16charstar);
142
143 CHECK(Q, stringview, stringview);
144 CHECK(Q, stringview, lchar);
145 CHECK(Q, stringview, qchar);
146 CHECK(Q, stringview, special);
147 CHECK(P, stringview, QStringLiteral(LITERAL));
148 CHECK(Q, stringview, u16char);
149 CHECK(Q, stringview, u16chararray);
150 CHECK(Q, stringview, u16charstar);
151
152 CHECK(P, lchar, lchar);
153 CHECK(P, lchar, qchar);
154 CHECK(P, lchar, special);
155 CHECK(P, lchar, QStringLiteral(LITERAL));
156 CHECK(Q, lchar, u16char);
157 CHECK(Q, lchar, u16chararray);
158 CHECK(Q, lchar, u16charstar);
159
160 CHECK(P, qchar, qchar);
161 CHECK(P, qchar, special);
162 CHECK(P, qchar, QStringLiteral(LITERAL));
163 CHECK(Q, qchar, u16char);
164 CHECK(Q, qchar, u16chararray);
165 CHECK(Q, qchar, u16charstar);
166
167 CHECK(P, special, special);
168 CHECK(P, special, QStringLiteral(LITERAL));
169 CHECK(Q, special, u16char);
170 CHECK(Q, special, u16chararray);
171 CHECK(Q, special, u16charstar);
172
173 CHECK(P, QStringLiteral(LITERAL), QStringLiteral(LITERAL));
174 CHECK(Q, QStringLiteral(LITERAL), u16char);
175 CHECK(Q, QStringLiteral(LITERAL), u16chararray);
176 CHECK(Q, QStringLiteral(LITERAL), u16charstar);
177
178 // CHECK(Q, u16char, u16char); // BUILTIN <-> BUILTIN cat't be overloaded
179 // CHECK(Q, u16char, u16chararray);
180 // CHECK(Q, u16char, u16charstar);
181
182 // CHECK(Q, u16chararray, u16chararray); // BUILTIN <-> BUILTIN cat't be overloaded
183 // CHECK(Q, u16chararray, u16charstar);
184
185 // CHECK(Q, u16charstar, u16charstar); // BUILTIN <-> BUILTIN cat't be overloaded
186
187#undef DO
188
189#define DO(QorP, a1, a2) \
190 QCOMPARE(QByteArray(a1 QorP a2), \
191 toQByteArray(a1).append(toQByteArray(a2))) \
192 /* end */
193
194 QByteArray bytearray = stringref.toUtf8();
195 char *charstar = bytearray.data();
196 char chararray[3] = { 'H', 'i', '\0' };
197 const char constchararray[3] = { 'H', 'i', '\0' };
198 char achar = 'a';
199
200 CHECK(P, bytearray, bytearray);
201 CHECK(P, bytearray, charstar);
202#ifndef Q_CC_MSVC // see QTBUG-65359
203 CHECK(P, bytearray, chararray);
204#else
205 Q_UNUSED(chararray);
206#endif
207 CHECK(P, bytearray, constchararray);
208 CHECK(P, bytearray, achar);
209
210 //CHECK(Q, charstar, charstar); // BUILTIN <-> BUILTIN cat't be overloaded
211 //CHECK(Q, charstar, chararray);
212 //CHECK(Q, charstar, achar);
213
214 //CHECK(Q, chararray, chararray); // BUILTIN <-> BUILTIN cat't be overloaded
215 //CHECK(Q, chararray, achar);
216
217 //CHECK(Q, achar, achar); // BUILTIN <-> BUILTIN cat't be overloaded
218
219#undef DO
220#undef CHECK
221
222 QString r2(QLatin1String(LITERAL LITERAL));
223 QString r3 = QString::fromUtf8(UTF8_LITERAL UTF8_LITERAL);
224 QString r;
225
226 // self-assignment:
227 r = stringref.toString();
228 r = lchar + r;
229 QCOMPARE(r, QString(lchar P stringref));
230
231#ifdef Q_COMPILER_UNICODE_STRINGS
232 r = QStringLiteral(UNICODE_LITERAL);
233 r = r Q QStringLiteral(UNICODE_LITERAL);
234 QCOMPARE(r, r3);
235#endif
236
237#ifndef QT_NO_CAST_FROM_ASCII
238 r = string P LITERAL;
239 QCOMPARE(r, r2);
240 r = LITERAL P string;
241 QCOMPARE(r, r2);
242
243 QByteArray ba = QByteArray(LITERAL);
244 r = ba P string;
245 QCOMPARE(r, r2);
246 r = string P ba;
247 QCOMPARE(r, r2);
248
249 r = string P QByteArrayLiteral(LITERAL);
250 QCOMPARE(r, r2);
251 r = QByteArrayLiteral(LITERAL) P string;
252 QCOMPARE(r, r2);
253
254 static const char badata[] = LITERAL_EXTRA;
255 ba = QByteArray::fromRawData(badata, LITERAL_LEN);
256 r = ba P string;
257 QCOMPARE(r, r2);
258 r = string P ba;
259 QCOMPARE(r, r2);
260
261 string = QString::fromUtf8(UTF8_LITERAL);
262 ba = UTF8_LITERAL;
263
264 r = string P UTF8_LITERAL;
265 QCOMPARE(r.size(), r3.size());
266 QCOMPARE(r, r3);
267 r = UTF8_LITERAL P string;
268 QCOMPARE(r, r3);
269 r = ba P string;
270 QCOMPARE(r, r3);
271 r = string P ba;
272 QCOMPARE(r, r3);
273
274 ba = QByteArray::fromRawData(UTF8_LITERAL_EXTRA, UTF8_LITERAL_LEN);
275 r = ba P string;
276 QCOMPARE(r, r3);
277 r = string P ba;
278 QCOMPARE(r, r3);
279
280 ba = QByteArray(); // empty
281 r = ba P string;
282 QCOMPARE(r, string);
283 r = string P ba;
284 QCOMPARE(r, string);
285
286 const char *zero = 0;
287 r = string P zero;
288 QCOMPARE(r, string);
289 r = zero P string;
290 QCOMPARE(r, string);
291#endif
292
293 string = QString::fromLatin1(LITERAL);
294 QCOMPARE(QByteArray(qPrintable(string P string)), QByteArray(string.toLatin1() + string.toLatin1()));
295
296
297
298 //QByteArray
299 {
300 QByteArray ba = LITERAL;
301 QByteArray superba = ba P ba P LITERAL;
302 QCOMPARE(superba, QByteArray(LITERAL LITERAL LITERAL));
303
304 ba = QByteArrayLiteral(LITERAL);
305 QCOMPARE(ba, QByteArray(LITERAL));
306 superba = ba P QByteArrayLiteral(LITERAL) P LITERAL;
307 QCOMPARE(superba, QByteArray(LITERAL LITERAL LITERAL));
308
309 QByteArray testWith0 = ba P "test\0with\0zero" P ba;
310 QCOMPARE(testWith0, QByteArray(LITERAL "test" LITERAL));
311
312 QByteArray ba2 = ba P '\0' + LITERAL;
313 QCOMPARE(ba2, QByteArray(LITERAL "\0" LITERAL, ba.size()*2+1));
314
315 const char *mmh = "test\0foo";
316 QCOMPARE(QByteArray(ba P mmh P ba), testWith0);
317
318 QByteArray raw = QByteArray::fromRawData(UTF8_LITERAL_EXTRA, UTF8_LITERAL_LEN);
319 QByteArray r = "hello" P raw;
320 QByteArray r2 = "hello" UTF8_LITERAL;
321 QCOMPARE(r, r2);
322 r2 = QByteArray("hello\0") P UTF8_LITERAL;
323 QCOMPARE(r, r2);
324
325 const char *zero = 0;
326 r = ba P zero;
327 QCOMPARE(r, ba);
328 r = zero P ba;
329 QCOMPARE(r, ba);
330 }
331
332 //operator QString +=
333 {
334 QString str = QString::fromUtf8(UTF8_LITERAL);
335 str += QLatin1String(LITERAL) P str;
336 QCOMPARE(str, QString::fromUtf8(UTF8_LITERAL LITERAL UTF8_LITERAL));
337#ifndef QT_NO_CAST_FROM_ASCII
338 str = (QString::fromUtf8(UTF8_LITERAL) += QLatin1String(LITERAL) P UTF8_LITERAL);
339 QCOMPARE(str, QString::fromUtf8(UTF8_LITERAL LITERAL UTF8_LITERAL));
340#endif
341
342 QString str2 = QString::fromUtf8(UTF8_LITERAL);
343 QString str2_e = QString::fromUtf8(UTF8_LITERAL);
344 const char * nullData = 0;
345 str2 += QLatin1String(nullData) P str2;
346 str2_e += QLatin1String("") P str2_e;
347 QCOMPARE(str2, str2_e);
348 }
349
350 //operator QByteArray +=
351 {
352 QByteArray ba = UTF8_LITERAL;
353 ba += QByteArray(LITERAL) P UTF8_LITERAL;
354 QCOMPARE(ba, QByteArray(UTF8_LITERAL LITERAL UTF8_LITERAL));
355 ba += LITERAL P QByteArray::fromRawData(UTF8_LITERAL_EXTRA, UTF8_LITERAL_LEN);
356 QCOMPARE(ba, QByteArray(UTF8_LITERAL LITERAL UTF8_LITERAL LITERAL UTF8_LITERAL));
357 QByteArray withZero = QByteArray(LITERAL "\0" LITERAL, LITERAL_LEN*2+1);
358 QByteArray ba2 = withZero;
359 ba2 += ba2 P withZero;
360 QCOMPARE(ba2, QByteArray(withZero + withZero + withZero));
361#if !defined(QT_NO_CAST_TO_ASCII) && QT_DEPRECATED_SINCE(5, 15)
362QT_WARNING_PUSH
363QT_WARNING_DISABLE_DEPRECATED
364 ba = UTF8_LITERAL;
365 ba2 = (ba += QLatin1String(LITERAL) + QString::fromUtf8(UTF8_LITERAL));
366 QCOMPARE(ba2, ba);
367 QCOMPARE(ba, QByteArray(UTF8_LITERAL LITERAL UTF8_LITERAL));
368QT_WARNING_POP
369#endif
370 }
371
372}
373

source code of qtbase/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/stringbuilder.cpp