1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25 
26 #pragma once
27 
28 #include "sqliteglobal.h"
29 
30 #include <QByteArray>
31 #include <QDataStream>
32 #include <QHashFunctions>
33 #include <QMetaType>
34 #include <QString>
35 
36 #include <cstring>
37 #include <iosfwd>
38 
39 class Utf8StringVector;
40 class Utf8String;
41 
42 class Utf8String
43 {
44     friend class Utf8StringVector;
45 
46 public:
47     Utf8String() = default;
48 
Utf8String(const char * utf8Text)49     explicit Utf8String(const char *utf8Text)
50         : byteArray(utf8Text, utf8Text ? static_cast<int>(std::strlen(utf8Text)) : -1)
51     {}
52 
Utf8String(const char * utf8Text,int size)53     explicit Utf8String(const char *utf8Text, int size)
54         : byteArray(utf8Text, size)
55     {}
56 
Utf8String(const QString & text)57     Utf8String(const QString &text)
58         : byteArray(text.toUtf8())
59     {
60     }
61 
constData()62     const char *constData() const
63     {
64         return byteArray.constData();
65     }
66 
byteSize()67     int byteSize() const
68     {
69         return byteArray.size();
70     }
71 
fromUtf8(const char * utf8Text)72     static Utf8String fromUtf8(const char *utf8Text)
73     {
74         return Utf8String(utf8Text, -1);
75     }
76 
fromByteArray(const QByteArray & utf8ByteArray)77     static Utf8String fromByteArray(const QByteArray &utf8ByteArray)
78     {
79         return Utf8String(utf8ByteArray);
80     }
toByteArray()81     const QByteArray &toByteArray() const
82     {
83         return byteArray;
84     }
85 
fromString(const QString & text)86     static Utf8String fromString(const QString &text)
87     {
88         return Utf8String::fromByteArray(text.toUtf8());
89     }
90 
toString()91     QString toString() const
92     {
93         return QString::fromUtf8(byteArray, byteArray.size());
94     }
95 
96     Utf8String mid(int position, int length = -1) const
97     {
98         return Utf8String(byteArray.mid(position, length));
99     }
100 
replace(const Utf8String & before,const Utf8String & after)101     void replace(const Utf8String &before, const Utf8String &after)
102     {
103         byteArray.replace(before.byteArray, after.byteArray);
104     }
105 
replace(int position,int length,const Utf8String & after)106     void replace(int position, int length, const Utf8String &after)
107     {
108         byteArray.replace(position, length, after.byteArray);
109     }
110 
111     SQLITE_EXPORT Utf8StringVector split(char separator) const;
112 
clear()113     void clear()
114     {
115         byteArray.clear();
116     }
117 
append(const Utf8String & textToAppend)118     void append(const Utf8String &textToAppend)
119     {
120         byteArray.append(textToAppend.byteArray);
121     }
122 
chop(int n)123     void chop(int n)
124     {
125         byteArray.chop(n);
126     }
127 
indexOf(const Utf8String & text)128     int indexOf(const Utf8String &text) const
129     {
130         return byteArray.indexOf(text.byteArray);
131     }
132 
indexOf(const char * text)133     int indexOf(const char *text) const
134     {
135         return byteArray.indexOf(text);
136     }
137 
lastIndexOf(const Utf8String & text)138     int lastIndexOf(const Utf8String &text) const
139     {
140         return byteArray.lastIndexOf(text.byteArray);
141     }
142 
lastIndexOf(const char * text)143     int lastIndexOf(const char *text) const
144     {
145         return byteArray.lastIndexOf(text);
146     }
147 
indexOf(char character)148     int indexOf(char character) const
149     {
150         return byteArray.indexOf(character);
151     }
152 
contains(const Utf8String & text)153     bool contains(const Utf8String &text) const
154     {
155         return byteArray.contains(text.byteArray);
156     }
157 
contains(const char * text)158     bool contains(const char *text) const
159     {
160         return byteArray.contains(text);
161     }
162 
contains(char character)163     bool contains(char character) const
164     {
165         return byteArray.contains(character);
166     }
167 
startsWith(const Utf8String & text)168     bool startsWith(const Utf8String &text) const
169     {
170         return byteArray.startsWith(text.byteArray);
171     }
172 
startsWith(const char * text)173     bool startsWith(const char *text) const
174     {
175         return byteArray.startsWith(text);
176     }
177 
startsWith(char character)178     bool startsWith(char character) const
179     {
180         return byteArray.startsWith(character);
181     }
182 
endsWith(const Utf8String & text)183     bool endsWith(const Utf8String &text) const
184     {
185         return byteArray.endsWith(text.byteArray);
186     }
187 
endsWith(const char * text)188     bool endsWith(const char *text) const
189     {
190         return byteArray.endsWith(text);
191     }
192 
endsWith(char character)193     bool endsWith(char character) const
194     {
195         return byteArray.endsWith(character);
196     }
197 
isNull()198     bool isNull() const
199     {
200         return byteArray.isNull();
201     }
202 
isEmpty()203     bool isEmpty() const
204     {
205         return byteArray.isEmpty();
206     }
207 
hasContent()208     bool hasContent() const
209     {
210         return !isEmpty();
211     }
212 
reserve(int reserveSize)213     void reserve(int reserveSize)
214     {
215         byteArray.reserve(reserveSize);
216     }
217 
218     template<typename T>
219     static Utf8String number(T number, int base = 10)
220     {
221         return Utf8String::fromByteArray(QByteArray::number(number, base));
222     }
223 
224     const Utf8String &operator+=(const Utf8String &text)
225     {
226         byteArray += text.byteArray;
227 
228         return *this;
229     }
230 
registerType()231     static void registerType()
232     {
233         qRegisterMetaType<Utf8String>("Utf8String");
234     }
235 
QString()236     operator QString() const
237     {
238         return toString();
239     }
240 
241     operator const QByteArray &() const
242     {
243         return byteArray;
244     }
245 
246     friend const Utf8String operator+(const Utf8String &first, const Utf8String &second)
247     {
248         return Utf8String(first.byteArray + second.byteArray);
249     }
250 
251     friend bool operator!=(const Utf8String &first, const Utf8String &second)
252     {
253         return first.byteArray != second.byteArray;
254     }
255 
256     friend bool operator==(const Utf8String &first, const Utf8String &second)
257     {
258         return first.byteArray == second.byteArray;
259     }
260 
261     friend bool operator==(const Utf8String &first, const char *second)
262     {
263         return first.byteArray == second;
264     }
265 
266     friend bool operator==(const char *first, const Utf8String &second)
267     {
268         return second == first;
269     }
270 
271     friend bool operator!=(const Utf8String &first, const char *second)
272     {
273         return first.byteArray != second;
274     }
275 
276     friend bool operator!=(const char *first, const Utf8String &second) { return second != first; }
277 
278     friend bool operator==(const Utf8String &first, const QString &second)
279     {
280         return first.byteArray == second.toUtf8();
281     }
282 
283     friend bool operator<(const Utf8String &first, const Utf8String &second)
284     {
285         if (first.byteSize() == second.byteSize())
286             return first.byteArray < second.byteArray;
287 
288         return first.byteSize() < second.byteSize();
289     }
290 
291     friend  QDataStream &operator<<(QDataStream &datastream, const Utf8String &text)
292     {
293         datastream << text.byteArray;
294 
295         return datastream;
296     }
297 
298     friend QDataStream &operator>>(QDataStream &datastream, Utf8String &text)
299     {
300         datastream >> text.byteArray;
301 
302         return datastream;
303     }
304 
qHash(const Utf8String & utf8String)305     friend auto qHash(const Utf8String &utf8String)
306     {
307         return qHash(utf8String.byteArray);
308     }
309 
310 protected:
Utf8String(const QByteArray & utf8ByteArray)311     explicit Utf8String(const QByteArray &utf8ByteArray)
312         : byteArray(utf8ByteArray)
313     {
314     }
315 
316 private:
317     QByteArray byteArray;
318 };
319 
320 SQLITE_EXPORT QDebug operator<<(QDebug debug, const Utf8String &text);
321 SQLITE_EXPORT std::ostream& operator<<(std::ostream &os, const Utf8String &utf8String);
322 
323 #define Utf8StringLiteral(str) Utf8String::fromByteArray(QByteArrayLiteral(str))
324