1 /****************************************************************************
2 **
3 ** DQt - D bindings for the Qt Toolkit
4 **
5 ** GNU Lesser General Public License Usage
6 ** This file may be used under the terms of the GNU Lesser
7 ** General Public License version 3 as published by the Free Software
8 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
9 ** packaging of this file. Please review the following information to
10 ** ensure the GNU Lesser General Public License version 3 requirements
11 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
12 **
13 ****************************************************************************/
14 module qt.core.bytearray;
15 extern(C++):
16 
17 import core.stdc.config;
18 import core.vararg;
19 import qt.config;
20 import qt.core.arraydata;
21 import qt.core.flags;
22 import qt.core.global;
23 import qt.core.list;
24 import qt.core.metatype;
25 import qt.core.namespace;
26 import qt.core.typeinfo;
27 import qt.helpers;
28 
29 /+ #ifdef truncate
30 #error qbytearray.h must be included before any header file that defines truncate
31 #endif
32 
33 #if defined(Q_OS_DARWIN) || defined(Q_QDOC)
34 Q_FORWARD_DECLARE_CF_TYPE(CFData);
35 Q_FORWARD_DECLARE_OBJC_CLASS(NSData);
36 #endif +/
37 
38 
39 
40 /*****************************************************************************
41   Safe and portable C string functions; extensions to standard string.h
42  *****************************************************************************/
43 
44 /+ Q_CORE_EXPORT +/ char* qstrdup(const(char)* );
45 
46 pragma(inline, true) uint qstrlen(const(char)* str)
47 {
48     import core.stdc.string;
49     return str ? cast(uint)(strlen(str)) : 0;
50 }
51 
52 pragma(inline, true) uint qstrnlen(const(char)* str, uint maxlen)
53 {
54     uint length = 0;
55     if (str) {
56         while (length < maxlen && *str++)
57             length++;
58     }
59     return length;
60 }
61 
62 /+ Q_CORE_EXPORT +/ char* qstrcpy(char* dst, const(char)* src);
63 /+ Q_CORE_EXPORT +/ char* qstrncpy(char* dst, const(char)* src, uint len);
64 
65 /+ Q_CORE_EXPORT +/ int qstrcmp(const(char)* str1, const(char)* str2);
66 /+ Q_CORE_EXPORT +/ int qstrcmp(ref const(QByteArray) str1, ref const(QByteArray) str2);
67 /+ Q_CORE_EXPORT +/ int qstrcmp(ref const(QByteArray) str1, const(char)* str2);
68 pragma(inline, true) int qstrcmp(const(char)* str1, ref const(QByteArray) str2)
69 { return -qstrcmp(str2, str1); }
70 
71 pragma(inline, true) int qstrncmp(const(char)* str1, const(char)* str2, uint len)
72 {
73     import core.stdc.string;
74 
75     return (str1 && str2) ? strncmp(str1, str2, len)
76         : (str1 ? 1 : (str2 ? -1 : 0));
77 }
78 /+ Q_CORE_EXPORT +/ int qstricmp(const(char)* , const(char)* );
79 /+ Q_CORE_EXPORT +/ int qstrnicmp(const(char)* , const(char)* , uint len);
80 /+ Q_CORE_EXPORT +/ int qstrnicmp(const(char)* , qsizetype, const(char)* , qsizetype /+ = -1 +/);
81 
82 // implemented in qvsnprintf.cpp
83 /+ Q_CORE_EXPORT +/ int qvsnprintf(char* str, size_t n, const(char)* fmt, va_list ap);
84 /+ Q_CORE_EXPORT +/ int qsnprintf(char* str, size_t n, const(char)* fmt, ...);
85 
86 // qChecksum: Internet checksum
87 /+ Q_CORE_EXPORT +/ quint16 qChecksum(const(char)* s, uint len);                            // ### Qt 6: Remove
88 /+ Q_CORE_EXPORT +/ quint16 qChecksum(const(char)* s, uint len, /+ Qt:: +/qt.core.namespace.ChecksumType standard); // ### Qt 6: Use Qt::ChecksumType standard = Qt::ChecksumIso3309
89 
90 /+ class QByteRef;
91 class QString;
92 class QDataStream;
93 template <typename T> class QList; +/
94 
95 alias QByteArrayData = QArrayData;
96 
97 struct QStaticByteArrayData(int N)
98 {
99     QByteArrayData ba;
100     char[N + 1] data;
101 
102     QByteArrayData* data_ptr() const
103     {
104         (mixin(Q_ASSERT(q{QStaticByteArrayData.ba.ref_.isStatic()})));
105         return const_cast!(QByteArrayData*)(&ba);
106     }
107 }
108 
109 struct QByteArrayDataPtr
110 {
111     QByteArrayData* ptr;
112 }
113 
114 /+ #define Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(size, offset) \
115     Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(size, offset)
116     /**/
117 
118 #define Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER(size) \
119     Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(size, sizeof(QByteArrayData)) \
120     /**/
121 
122 #  define QByteArrayLiteral(str) \
123     ([]() -> QByteArray { \
124         enum { Size = sizeof(str) - 1 }; \
125         static const QStaticByteArrayData<Size> qbytearray_literal = { \
126             Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER(Size), \
127             str }; \
128         QByteArrayDataPtr holder = { qbytearray_literal.data_ptr() }; \
129         return QByteArray(holder); \
130     }()) \
131     /**/ +/
132 static if(!versionIsSet!("QT_COMPILING_QSTRING_COMPAT_CPP") && defined!"Q_COMPILER_REF_QUALIFIERS")
133 {
134 /+ #    define Q_REQUIRED_RESULT
135 #    define Q_REQUIRED_RESULT_pushed +/
136 }
137 
138 @(QMetaType.Type.QByteArray) @Q_MOVABLE_TYPE extern(C++, class) struct /+ Q_CORE_EXPORT +/ QByteArray
139 {
140     static import qt.core.namespace;
141 private:
142     alias Data = QTypedArrayData!(char);
143 
144 public:
145     enum Base64Option {
146         Base64Encoding = 0,
147         Base64UrlEncoding = 1,
148 
149         KeepTrailingEquals = 0,
150         OmitTrailingEquals = 2,
151 
152         IgnoreBase64DecodingErrors = 0,
153         AbortOnBase64DecodingErrors = 4,
154     }
155     /+ Q_DECLARE_FLAGS(Base64Options, Base64Option) +/
156 alias Base64Options = QFlags!(Base64Option);
157     enum /+ class +/ Base64DecodingStatus {
158         Ok,
159         IllegalInputLength,
160         IllegalCharacter,
161         IllegalPadding,
162     }
163 
164     version(Windows)
165     {
166         @disable this();
167         pragma(inline, true) void rawConstructor()/+ noexcept+/
168         {
169             this.d = Data.sharedNull();
170         }
171         static typeof(this) create()
172         {
173             typeof(this) r = typeof(this).init;
174             r.rawConstructor();
175             return r;
176         }
177     }
178     else
179     {
180         static typeof(this) create()
181         {
182             return typeof(this).init;
183         }
184     }
185 
186     this(const(char)* , int size = -1);
187     this(int size, char c);
188     this(int size, /+ Qt:: +/qt.core.namespace.Initialization);
189     @disable this(this);
190     pragma(inline, true) this(ref const(QByteArray) a)/+ noexcept+/
191     {
192         this.d = cast(Data*)a.d;
193         d.ref_.ref_();
194     }
195     pragma(inline, true) ~this() { if (!d.ref_.deref()) Data.deallocate(d); }
196 
197     /+ref QByteArray operator =(ref const(QByteArray) )/+ noexcept+/;+/
198     /+ref QByteArray operator =(const(char)* str);+/
199     /+ inline QByteArray(QByteArray && other) noexcept : d(other.d) { other.d = Data::sharedNull(); } +/
200     /+ inline QByteArray &operator=(QByteArray &&other) noexcept
201     { qSwap(d, other.d); return *this; } +/
202 
203     /+ inline void swap(QByteArray &other) noexcept
204     { qSwap(d, other.d); } +/
205 
206     pragma(inline, true) int size() const
207     { return d.size; }
208     pragma(inline, true) bool isEmpty() const
209     { return d.size == 0; }
210     void resize(int size);
211 
212     ref QByteArray fill(char c, int size = -1);
213 
214     pragma(inline, true) int capacity() const
215     { return d.alloc ? d.alloc - 1 : 0; }
216     pragma(inline, true) void reserve(int asize)
217     {
218         if (d.ref_.isShared() || uint(asize) + 1u > d.alloc) {
219             reallocData(qMax(uint(size()), uint(asize)) + 1u, d.detachFlags() | Data.AllocationOption.CapacityReserved);
220         } else {
221             // cannot set unconditionally, since d could be the shared_null or
222             // otherwise static
223             d.capacityReserved = true;
224         }
225     }
226     pragma(inline, true) void squeeze()
227     {
228         if (d.ref_.isShared() || uint(d.size) + 1u < d.alloc) {
229             reallocData(uint(d.size) + 1u, d.detachFlags() & ~Data.AllocationOption.CapacityReserved);
230         } else {
231             // cannot set unconditionally, since d could be shared_null or
232             // otherwise static.
233             d.capacityReserved = false;
234         }
235     }
236 
237     version(QT_NO_CAST_FROM_BYTEARRAY){}else
238     {
239         /+pragma(inline, true) auto opCast(T : const(char))() const;+/
240         /+pragma(inline, true) auto opCast(T : const(void))() const;+/
241     }
242     pragma(inline, true) char* data()
243     { detach(); return cast(char*)(d.data()); }
244     pragma(inline, true) const(char)* data() const
245     { return cast(const(char)*)(d.data()); }
246     pragma(inline, true) const(char)* constData() const
247     { return cast(const(char)*)(d.data()); }
248     pragma(inline, true) void detach()
249     { if (d.ref_.isShared() || (d.offset != QByteArrayData.sizeof)) reallocData(uint(d.size) + 1u, d.detachFlags()); }
250     pragma(inline, true) bool isDetached() const
251     { return !d.ref_.isShared(); }
252     pragma(inline, true) bool isSharedWith(ref const(QByteArray) other) const { return d == other.d; }
253     void clear();
254 
255     pragma(inline, true) char at(int i) const
256     { (mixin(Q_ASSERT(q{uint(i) < uint(size())}))); return d.data()[i]; }
257     pragma(inline, true) char opIndex(int i) const
258     { (mixin(Q_ASSERT(q{uint(i) < uint(size())}))); return d.data()[i]; }
259     pragma(inline, true) char opIndex(uint i) const
260     { (mixin(Q_ASSERT(q{i < uint(size())}))); return d.data()[i]; }
261     /+ Q_REQUIRED_RESULT +/ pragma(inline, true) QByteRef opIndex(int i)
262     { (mixin(Q_ASSERT(q{i >= 0}))); detach(); return QByteRef(this, i); }
263     /+ Q_REQUIRED_RESULT +/ pragma(inline, true) QByteRef opIndex(uint i)
264     {  detach(); return QByteRef(this, i); }
265     /+ Q_REQUIRED_RESULT +/ char front() const { return at(0); }
266     /+ Q_REQUIRED_RESULT +/ pragma(inline, true) QByteRef front() { return opIndex(0); }
267     /+ Q_REQUIRED_RESULT +/ char back() const { return at(size() - 1); }
268     /+ Q_REQUIRED_RESULT +/ pragma(inline, true) QByteRef back() { return opIndex(size() - 1); }
269 
270     int indexOf(char c, int from = 0) const;
271     int indexOf(const(char)* c, int from = 0) const;
272     int indexOf(ref const(QByteArray) a, int from = 0) const;
273     int lastIndexOf(char c, int from = -1) const;
274     int lastIndexOf(const(char)* c, int from = -1) const;
275     int lastIndexOf(ref const(QByteArray) a, int from = -1) const;
276 
277     pragma(inline, true) bool contains(char c) const
278     { return indexOf(c) != -1; }
279     pragma(inline, true) bool contains(const(char)* c) const
280     { return indexOf(c) != -1; }
281     pragma(inline, true) bool contains(ref const(QByteArray) a) const
282     { return indexOf(a) != -1; }
283     int count(char c) const;
284     int count(const(char)* a) const;
285     int count(ref const(QByteArray) a) const;
286 
287     pragma(inline, true) int compare(const(char)* c, /+ Qt:: +/qt.core.namespace.CaseSensitivity cs = /+ Qt:: +/qt.core.namespace.CaseSensitivity.CaseSensitive) const/+ noexcept+/
288     {
289         return cs == /+ Qt:: +/qt.core.namespace.CaseSensitivity.CaseSensitive ? qstrcmp(this, c) :
290                                          qstrnicmp(data(), size(), c, -1);
291     }
292     pragma(inline, true) int compare(ref const(QByteArray) a, /+ Qt:: +/qt.core.namespace.CaseSensitivity cs = /+ Qt:: +/qt.core.namespace.CaseSensitivity.CaseSensitive) const/+ noexcept+/
293     {
294         return cs == /+ Qt:: +/qt.core.namespace.CaseSensitivity.CaseSensitive ? qstrcmp(this, a) :
295                                          qstrnicmp(data(), size(), a.data(), a.size());
296     }
297 
298     /+ Q_REQUIRED_RESULT +/ QByteArray left(int len) const;
299     /+ Q_REQUIRED_RESULT +/ QByteArray right(int len) const;
300     /+ Q_REQUIRED_RESULT +/ QByteArray mid(int index, int len = -1) const;
301     /+ Q_REQUIRED_RESULT +/ QByteArray chopped(int len) const
302     { (mixin(Q_ASSERT(q{len >= 0}))); (mixin(Q_ASSERT(q{len <= size()}))); return left(size() - len); }
303 
304     bool startsWith(ref const(QByteArray) a) const;
305     bool startsWith(char c) const;
306     bool startsWith(const(char)* c) const;
307 
308     bool endsWith(ref const(QByteArray) a) const;
309     bool endsWith(char c) const;
310     bool endsWith(const(char)* c) const;
311 
312     bool isUpper() const;
313     bool isLower() const;
314 
315     void truncate(int pos);
316     void chop(int n);
317 
318 /+ #if defined(Q_COMPILER_REF_QUALIFIERS) && !defined(QT_COMPILING_QSTRING_COMPAT_CPP) && !defined(Q_CLANG_QDOC)
319 #  if defined(Q_CC_GNU) && !defined(Q_CC_CLANG) && !defined(Q_CC_INTEL) && !__has_cpp_attribute(nodiscard)
320     // required due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61941
321 #    pragma push_macro("Q_REQUIRED_RESULT")
322 #    undef Q_REQUIRED_RESULT
323 #    define Q_REQUIRED_RESULT
324 #    define Q_REQUIRED_RESULT_pushed
325 #  endif
326     Q_REQUIRED_RESULT +/ 
327     static if((!versionIsSet!("QT_COMPILING_QSTRING_COMPAT_CPP") && defined!"Q_COMPILER_REF_QUALIFIERS"))
328     {
329         QByteArray toLower() const/+ &+/
330         { return toLower_helper(this); }
331         /+ Q_REQUIRED_RESULT +/ QByteArray toLower()/+ &&+/
332         { return toLower_helper(this); }
333         /+ Q_REQUIRED_RESULT +/ QByteArray toUpper() const/+ &+/
334         { return toUpper_helper(this); }
335         /+ Q_REQUIRED_RESULT +/ QByteArray toUpper()/+ &&+/
336         { return toUpper_helper(this); }
337         /+ Q_REQUIRED_RESULT +/ QByteArray trimmed() const/+ &+/
338         { return trimmed_helper(this); }
339         /+ Q_REQUIRED_RESULT +/ QByteArray trimmed()/+ &&+/
340         { return trimmed_helper(this); }
341         /+ Q_REQUIRED_RESULT +/ QByteArray simplified() const/+ &+/
342         { return simplified_helper(this); }
343         /+ Q_REQUIRED_RESULT +/ QByteArray simplified()/+ &&+/
344         { return simplified_helper(this); }
345     }
346     else
347     {
348     /+ #  ifdef Q_REQUIRED_RESULT_pushed
349     #    pragma pop_macro("Q_REQUIRED_RESULT")
350     #  endif
351     #else +/
352         /+ Q_REQUIRED_RESULT +/ QByteArray toLower() const;
353         /+ Q_REQUIRED_RESULT +/ QByteArray toUpper() const;
354         /+ Q_REQUIRED_RESULT +/ QByteArray trimmed() const;
355         /+ Q_REQUIRED_RESULT +/ QByteArray simplified() const;
356     }
357 /+ #endif +/
358 
359     /+ Q_REQUIRED_RESULT +/ QByteArray leftJustified(int width, char fill = ' ', bool truncate = false) const;
360     /+ Q_REQUIRED_RESULT +/ QByteArray rightJustified(int width, char fill = ' ', bool truncate = false) const;
361 
362     ref QByteArray prepend(char c);
363     pragma(inline, true) ref QByteArray prepend(int n, char ch)
364     { return insert(0, n, ch); }
365     ref QByteArray prepend(const(char)* s);
366     ref QByteArray prepend(const(char)* s, int len);
367     ref QByteArray prepend(ref const(QByteArray) a);
368     ref QByteArray append(char c);
369     pragma(inline, true) ref QByteArray append(int n, char ch)
370     { return insert(d.size, n, ch); }
371     ref QByteArray append(const(char)* s);
372     ref QByteArray append(const(char)* s, int len);
373     ref QByteArray append(ref const(QByteArray) a);
374     ref QByteArray insert(int i, char c);
375     ref QByteArray insert(int i, int count, char c);
376     ref QByteArray insert(int i, const(char)* s);
377     ref QByteArray insert(int i, const(char)* s, int len);
378     ref QByteArray insert(int i, ref const(QByteArray) a);
379     ref QByteArray remove(int index, int len);
380     ref QByteArray replace(int index, int len, const(char)* s);
381     ref QByteArray replace(int index, int len, const(char)* s, int alen);
382     ref QByteArray replace(int index, int len, ref const(QByteArray) s);
383     pragma(inline, true) ref QByteArray replace(char before, const(char)* c)
384     { return replace(&before, 1, c, qstrlen(c)); }
385     ref QByteArray replace(char before, ref const(QByteArray) after);
386     pragma(inline, true) ref QByteArray replace(const(char)* before, const(char)* after)
387     { return replace(before, qstrlen(before), after, qstrlen(after)); }
388     ref QByteArray replace(const(char)* before, int bsize, const(char)* after, int asize);
389     ref QByteArray replace(ref const(QByteArray) before, ref const(QByteArray) after);
390     pragma(inline, true) ref QByteArray replace(ref const(QByteArray) before, const(char)* c)
391     { return replace(before.constData(), before.size(), c, qstrlen(c)); }
392     ref QByteArray replace(const(char)* before, ref const(QByteArray) after);
393     ref QByteArray replace(char before, char after);
394     extern(D) pragma(inline, true) ref QByteArray opOpAssign(string op)(char c) if(op == "~")
395     { return append(c); }
396     extern(D) pragma(inline, true) ref QByteArray opOpAssign(string op)(const(char)* s) if(op == "~")
397     { return append(s); }
398     extern(D) pragma(inline, true) ref QByteArray opOpAssign(string op)(ref const(QByteArray) a) if(op == "~")
399     { return append(a); }
400 
401     QList!(QByteArray) split(char sep) const;
402 
403     /+ Q_REQUIRED_RESULT +/ QByteArray repeated(int times) const;
404 
405 /+ #if !defined(QT_NO_CAST_TO_ASCII) && QT_DEPRECATED_SINCE(5, 15)
406     QT_DEPRECATED_VERSION_X_5_15("Use QString's toUtf8(), toLatin1() or toLocal8Bit()")
407     QByteArray &append(const QString &s);
408     QT_DEPRECATED_VERSION_X_5_15("Use QString's toUtf8(), toLatin1() or toLocal8Bit()")
409     QByteArray &insert(int i, const QString &s);
410     QT_DEPRECATED_VERSION_X_5_15("Use QString's toUtf8(), toLatin1() or toLocal8Bit()")
411     QByteArray &replace(const QString &before, const char *after);
412     QT_DEPRECATED_VERSION_X_5_15("Use QString's toUtf8(), toLatin1() or toLocal8Bit()")
413     QByteArray &replace(char c, const QString &after);
414     QT_DEPRECATED_VERSION_X_5_15("Use QString's toUtf8(), toLatin1() or toLocal8Bit()")
415     QByteArray &replace(const QString &before, const QByteArray &after);
416 
417     QT_DEPRECATED_VERSION_X_5_15("Use QString's toUtf8(), toLatin1() or toLocal8Bit()")
418     QByteArray &operator+=(const QString &s);
419     QT_DEPRECATED_VERSION_X_5_15("Use QString's toUtf8(), toLatin1() or toLocal8Bit()")
420     int indexOf(const QString &s, int from = 0) const;
421     QT_DEPRECATED_VERSION_X_5_15("Use QString's toUtf8(), toLatin1() or toLocal8Bit()")
422     int lastIndexOf(const QString &s, int from = -1) const;
423 #endif
424 #if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
425     inline bool operator==(const QString &s2) const;
426     inline bool operator!=(const QString &s2) const;
427     inline bool operator<(const QString &s2) const;
428     inline bool operator>(const QString &s2) const;
429     inline bool operator<=(const QString &s2) const;
430     inline bool operator>=(const QString &s2) const;
431 #endif +/
432 
433     short toShort(bool* ok = null, int base = 10) const;
434     ushort toUShort(bool* ok = null, int base = 10) const;
435     int toInt(bool* ok = null, int base = 10) const;
436     uint toUInt(bool* ok = null, int base = 10) const;
437     cpp_long toLong(bool* ok = null, int base = 10) const;
438     cpp_ulong toULong(bool* ok = null, int base = 10) const;
439     qlonglong toLongLong(bool* ok = null, int base = 10) const;
440     qulonglong toULongLong(bool* ok = null, int base = 10) const;
441     float toFloat(bool* ok = null) const;
442     double toDouble(bool* ok = null) const;
443     QByteArray toBase64(Base64Options options) const;
444     QByteArray toBase64() const; // ### Qt6 merge with previous
445     QByteArray toHex() const;
446     QByteArray toHex(char separator) const; // ### Qt6 merge with previous
447     QByteArray toPercentEncoding(ref const(QByteArray) exclude/* = globalInitVar!QByteArray*/,
448                                      ref const(QByteArray) include/* = globalInitVar!QByteArray*/,
449                                      char percent/* = '%'*/) const;
450 
451     pragma(inline, true) ref QByteArray setNum(short n, int base = 10)
452     { return base == 10 ? setNum(qlonglong(n), base) : setNum(qulonglong(ushort(n)), base); }
453     pragma(inline, true) ref QByteArray setNum(ushort n, int base = 10)
454     { return setNum(qulonglong(n), base); }
455     pragma(inline, true) ref QByteArray setNum(int n, int base = 10)
456     { return base == 10 ? setNum(qlonglong(n), base) : setNum(qulonglong(uint(n)), base); }
457     pragma(inline, true) ref QByteArray setNum(uint n, int base = 10)
458     { return setNum(qulonglong(n), base); }
459     ref QByteArray setNum(qlonglong, int base = 10);
460     ref QByteArray setNum(qulonglong, int base = 10);
461     pragma(inline, true) ref QByteArray setNum(float n, char f = 'g', int prec = 6)
462     { return setNum(double(n),f,prec); }
463     ref QByteArray setNum(double, char f = 'g', int prec = 6);
464     ref QByteArray setRawData(const(char)* a, uint n); // ### Qt 6: use an int
465 
466     /+ Q_REQUIRED_RESULT +/ static QByteArray number(int, int base = 10);
467     /+ Q_REQUIRED_RESULT +/ static QByteArray number(uint, int base = 10);
468     /+ Q_REQUIRED_RESULT +/ static QByteArray number(qlonglong, int base = 10);
469     /+ Q_REQUIRED_RESULT +/ static QByteArray number(qulonglong, int base = 10);
470     /+ Q_REQUIRED_RESULT +/ static QByteArray number(double, char f = 'g', int prec = 6);
471     /+ Q_REQUIRED_RESULT +/ static QByteArray fromRawData(const(char)* , int size);
472 
473     /+
474     extern(C++, class) struct FromBase64Result;
475     +/extern(C++, class) struct FromBase64Result
476     {
477     public:
478         QByteArray decoded;
479         QByteArray.Base64DecodingStatus decodingStatus;
480 
481         /+ void swap(QByteArray::FromBase64Result &other) noexcept
482         {
483             qSwap(decoded, other.decoded);
484             qSwap(decodingStatus, other.decodingStatus);
485         } +/
486 
487         /+/+ explicit +/ auto opCast(T : bool)() const/+ noexcept+/ { return decodingStatus == QByteArray.Base64DecodingStatus.Ok; }+/
488 
489         static if(defined!"Q_COMPILER_REF_QUALIFIERS")
490         {
491             /+ref QByteArray operator *()/+ & noexcept+/ { return decoded; }+/
492             /+ref const(QByteArray) operator *() const/+ & noexcept+/ { return decoded; }+/
493             /+ QByteArray &&operator*() && noexcept { return std::move(decoded); } +/
494         }
495         else
496         {
497             /+ref QByteArray operator *()/+ noexcept+/ { return decoded; }+/
498             /+ref const(QByteArray) operator *() const/+ noexcept+/ { return decoded; }+/
499         }
500     }
501 
502     /+ Q_REQUIRED_RESULT static FromBase64Result fromBase64Encoding(QByteArray &&base64, Base64Options options = Base64Encoding); +/
503     /+ Q_REQUIRED_RESULT +/ static FromBase64Result fromBase64Encoding(ref const(QByteArray) base64, Base64Options options = Base64Option.Base64Encoding);
504     /+ Q_REQUIRED_RESULT +/ static QByteArray fromBase64(ref const(QByteArray) base64, Base64Options options);
505     /+ Q_REQUIRED_RESULT +/ static QByteArray fromBase64(ref const(QByteArray) base64); // ### Qt6 merge with previous
506     /+ Q_REQUIRED_RESULT +/ static QByteArray fromHex(ref const(QByteArray) hexEncoded);
507     /+ Q_REQUIRED_RESULT +/ static QByteArray fromPercentEncoding(ref const(QByteArray) pctEncoded, char percent = '%');
508 
509     static if((versionIsSet!("OSX") || versionIsSet!("iOS") || versionIsSet!("TVOS") || versionIsSet!("WatchOS")))
510     {
511         /+ static QByteArray fromCFData(CFDataRef data); +/
512         /+ static QByteArray fromRawCFData(CFDataRef data); +/
513         /+ CFDataRef toCFData() const Q_DECL_CF_RETURNS_RETAINED; +/
514         /+ CFDataRef toRawCFData() const Q_DECL_CF_RETURNS_RETAINED; +/
515         /+ static QByteArray fromNSData(const NSData *data); +/
516         /+ static QByteArray fromRawNSData(const NSData *data); +/
517         /+ NSData *toNSData() const Q_DECL_NS_RETURNS_AUTORELEASED; +/
518         /+ NSData *toRawNSData() const Q_DECL_NS_RETURNS_AUTORELEASED; +/
519     }
520 
521     alias iterator = char*;
522     alias const_iterator = const(char)*;
523     alias Iterator = iterator;
524     alias ConstIterator = const_iterator;
525     /+ typedef std::reverse_iterator<iterator> reverse_iterator; +/
526     /+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator; +/
527     pragma(inline, true) iterator begin()
528     /+pragma(inline, true) QByteArray.iterator begin()+/
529     { detach(); return cast(iterator)(d.data()); }
530     pragma(inline, true) const_iterator begin() const
531     /+pragma(inline, true) QByteArray.const_iterator begin() const+/
532     { return cast(const_iterator)(d.data()); }
533     pragma(inline, true) const_iterator cbegin() const
534     /+pragma(inline, true) QByteArray.const_iterator cbegin() const+/
535     { return cast(const_iterator)(d.data()); }
536     pragma(inline, true) const_iterator constBegin() const
537     /+pragma(inline, true) QByteArray.const_iterator constBegin() const+/
538     { return cast(const_iterator)(d.data()); }
539     pragma(inline, true) iterator end()
540     /+pragma(inline, true) QByteArray.iterator end()+/
541     { detach(); return cast(iterator)(d.data() + d.size); }
542     pragma(inline, true) const_iterator end() const
543     /+pragma(inline, true) QByteArray.const_iterator end() const+/
544     { return cast(const_iterator)(d.data() + d.size); }
545     pragma(inline, true) const_iterator cend() const
546     /+pragma(inline, true) QByteArray.const_iterator cend() const+/
547     { return cast(const_iterator)(d.data() + d.size); }
548     pragma(inline, true) const_iterator constEnd() const
549     /+pragma(inline, true) QByteArray.const_iterator constEnd() const+/
550     { return cast(const_iterator)(d.data() + d.size); }
551     /+ reverse_iterator rbegin() { return reverse_iterator(end()); } +/
552     /+ reverse_iterator rend() { return reverse_iterator(begin()); } +/
553     /+ const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } +/
554     /+ const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } +/
555     /+ const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); } +/
556     /+ const_reverse_iterator crend() const { return const_reverse_iterator(begin()); } +/
557 
558     // stl compatibility
559     alias size_type = int;
560     alias difference_type = qptrdiff;
561     /+ typedef const char & const_reference; +/
562     /+ typedef char & reference; +/
563     alias pointer = char*;
564     alias const_pointer = const(char)*;
565     alias value_type = char;
566     pragma(inline, true) void push_back(char c)
567     { append(c); }
568     pragma(inline, true) void push_back(const(char)* c)
569     { append(c); }
570     pragma(inline, true) void push_back(ref const(QByteArray) a)
571     { append(a); }
572     pragma(inline, true) void push_front(char c)
573     { prepend(c); }
574     pragma(inline, true) void push_front(const(char)* c)
575     { prepend(c); }
576     pragma(inline, true) void push_front(ref const(QByteArray) a)
577     { prepend(a); }
578     void shrink_to_fit() { squeeze(); }
579 
580     /+ static inline QByteArray fromStdString(const std::string &s); +/
581     /+ inline std::string toStdString() const; +/
582 
583     pragma(inline, true) int count() const { return d.size; }
584     int length() const { return d.size; }
585     bool isNull() const;
586 
587     pragma(inline, true) this(QByteArrayDataPtr dd)
588     {
589         this.d = static_cast!(Data*)(dd.ptr);
590     }
591 
592 private:
593     /+auto opCast(T : QNoImplicitBoolCast)() const;+/
594     version(Windows)
595         Data* d;
596     else
597     {
598         union
599         {
600             const(QArrayData) *d2 = QArrayData.shared_null.ptr;
601             Data* d;
602         }
603     }
604     void reallocData(uint alloc, Data.AllocationOptions options);
605     void expand(int i);
606     QByteArray nulTerminated() const;
607 
608     static QByteArray toLower_helper(ref const(QByteArray) a);
609     static QByteArray toLower_helper(ref QByteArray a);
610     static QByteArray toUpper_helper(ref const(QByteArray) a);
611     static QByteArray toUpper_helper(ref QByteArray a);
612     static QByteArray trimmed_helper(ref const(QByteArray) a);
613     static QByteArray trimmed_helper(ref QByteArray a);
614     static QByteArray simplified_helper(ref const(QByteArray) a);
615     static QByteArray simplified_helper(ref QByteArray a);
616 
617     /+ friend class QByteRef; +/
618     /+ friend class QString; +/
619     /+ friend Q_CORE_EXPORT QByteArray qUncompress(const uchar *data, int nbytes); +/
620 public:
621     alias DataPtr = Data*;
622     pragma(inline, true) ref DataPtr data_ptr() return { return d; }
623 }
624 /+pragma(inline, true) QFlags!(QByteArray.Base64Options.enum_type) operator |(QByteArray.Base64Options.enum_type f1, QByteArray.Base64Options.enum_type f2)/+noexcept+/{return QFlags!(QByteArray.Base64Options.enum_type)(f1)|f2;}+/
625 /+pragma(inline, true) QFlags!(QByteArray.Base64Options.enum_type) operator |(QByteArray.Base64Options.enum_type f1, QFlags!(QByteArray.Base64Options.enum_type) f2)/+noexcept+/{return f2|f1;}+/
626 /+pragma(inline, true) QIncompatibleFlag operator |(QByteArray.Base64Options.enum_type f1, int f2)/+noexcept+/{return QIncompatibleFlag(int(f1)|f2);}+/
627 
628 /+ Q_DECLARE_OPERATORS_FOR_FLAGS(QByteArray::Base64Options)#ifndef QT_NO_CAST_FROM_BYTEARRAY
629 #endif +/
630 
631 extern(C++, "QtPrivate") {
632 extern(C++, "DeprecatedRefClassBehavior") {
633     enum /+ class +/ EmittingClass {
634         QByteRef,
635         QCharRef,
636     }
637 
638     enum /+ class +/ WarningType {
639         OutOfRange,
640         DelayedDetach,
641     }
642 
643     /+ Q_CORE_EXPORT +/ /+ Q_DECL_COLD_FUNCTION +/ void warn(WarningType w, EmittingClass c);
644 } // namespace DeprecatedAssignmentOperatorBehavior
645 } // namespace QtPrivate
646 
647 extern(C++, class) struct
648 /+ #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
649 Q_CORE_EXPORT
650 #endif +/
651 QByteRef {  // ### Qt 7: remove
652 private:
653     QByteArray *a;
654     int i;
655     pragma(inline, true) this(ref QByteArray array, int idx)
656     {
657         this.a = &array;
658         this.i = idx;
659     }
660     /+ friend class QByteArray; +/
661 public:
662     /+ QByteRef(const QByteRef &) = default; +/
663     /+pragma(inline, true) auto opCast(T : char)() const
664     {
665         using namespace /+ QtPrivate:: +/DeprecatedRefClassBehavior;
666         if (/+ Q_LIKELY +/(i < a.d.size))
667             return a.d.data()[i];
668         version(QT_DEBUG)
669         {
670             warn(WarningType.OutOfRange, EmittingClass.QByteRef);
671         }
672         return cast(char)(0);
673     }+/
674     /+pragma(inline, true) ref QByteRef operator =(char c)
675     {
676         using namespace /+ QtPrivate:: +/DeprecatedRefClassBehavior;
677         if (/+ Q_UNLIKELY +/(i >= a.d.size)) {
678             version(QT_DEBUG)
679             {
680                 warn(WarningType.OutOfRange, EmittingClass.QByteRef);
681             }
682             a.expand(i);
683         } else {
684             version(QT_DEBUG)
685             {
686                 if (/+ Q_UNLIKELY +/(!a.isDetached()))
687                     warn(WarningType.DelayedDetach, EmittingClass.QByteRef);
688             }
689             a.detach();
690         }
691         a.d.data()[i] = c;
692         return this;
693     }+/
694     /+pragma(inline, true) ref QByteRef operator =(ref const(QByteRef) c)
695     {
696         return operator=(cast(char)(c));
697     }+/
698     /+pragma(inline, true) bool operator ==(char c) const
699     { return a.d.data()[i] == c; }+/
700     /+pragma(inline, true) bool operator !=(char c) const
701     { return a.d.data()[i] != c; }+/
702     /+pragma(inline, true) bool operator >(char c) const
703     { return a.d.data()[i] > c; }+/
704     /+pragma(inline, true) bool operator >=(char c) const
705     { return a.d.data()[i] >= c; }+/
706     /+pragma(inline, true) bool operator <(char c) const
707     { return a.d.data()[i] < c; }+/
708     /+pragma(inline, true) bool operator <=(char c) const
709     { return a.d.data()[i] <= c; }+/
710 }
711 /+pragma(inline, true) bool operator ==(ref const(QByteArray) a1, ref const(QByteArray) a2)/+ noexcept+/
712 {
713     import core.stdc.string;
714     return (a1.size() == a2.size()) && (memcmp(a1.constData(), a2.constData(), a1.size())==0);
715 }+/
716 /+pragma(inline, true) bool operator ==(ref const(QByteArray) a1, const(char)* a2)/+ noexcept+/
717 { return a2 ? qstrcmp(a1,a2) == 0 : a1.isEmpty(); }+/
718 /+pragma(inline, true) bool operator ==(const(char)* a1, ref const(QByteArray) a2)/+ noexcept+/
719 { return a1 ? qstrcmp(a1,a2) == 0 : a2.isEmpty(); }+/
720 /+pragma(inline, true) bool operator !=(ref const(QByteArray) a1, ref const(QByteArray) a2)/+ noexcept+/
721 { return !(a1==a2); }+/
722 /+pragma(inline, true) bool operator !=(ref const(QByteArray) a1, const(char)* a2)/+ noexcept+/
723 { return a2 ? qstrcmp(a1,a2) != 0 : !a1.isEmpty(); }+/
724 /+pragma(inline, true) bool operator !=(const(char)* a1, ref const(QByteArray) a2)/+ noexcept+/
725 { return a1 ? qstrcmp(a1,a2) != 0 : !a2.isEmpty(); }+/
726 /+pragma(inline, true) bool operator <(ref const(QByteArray) a1, ref const(QByteArray) a2)/+ noexcept+/
727 { return qstrcmp(a1, a2) < 0; }+/
728  /+pragma(inline, true) bool operator <(ref const(QByteArray) a1, const(char)* a2)/+ noexcept+/
729 { return qstrcmp(a1, a2) < 0; }+/
730 /+pragma(inline, true) bool operator <(const(char)* a1, ref const(QByteArray) a2)/+ noexcept+/
731 { return qstrcmp(a1, a2) < 0; }+/
732 /+pragma(inline, true) bool operator <=(ref const(QByteArray) a1, ref const(QByteArray) a2)/+ noexcept+/
733 { return qstrcmp(a1, a2) <= 0; }+/
734 /+pragma(inline, true) bool operator <=(ref const(QByteArray) a1, const(char)* a2)/+ noexcept+/
735 { return qstrcmp(a1, a2) <= 0; }+/
736 /+pragma(inline, true) bool operator <=(const(char)* a1, ref const(QByteArray) a2)/+ noexcept+/
737 { return qstrcmp(a1, a2) <= 0; }+/
738 /+pragma(inline, true) bool operator >(ref const(QByteArray) a1, ref const(QByteArray) a2)/+ noexcept+/
739 { return qstrcmp(a1, a2) > 0; }+/
740 /+pragma(inline, true) bool operator >(ref const(QByteArray) a1, const(char)* a2)/+ noexcept+/
741 { return qstrcmp(a1, a2) > 0; }+/
742 /+pragma(inline, true) bool operator >(const(char)* a1, ref const(QByteArray) a2)/+ noexcept+/
743 { return qstrcmp(a1, a2) > 0; }+/
744 /+pragma(inline, true) bool operator >=(ref const(QByteArray) a1, ref const(QByteArray) a2)/+ noexcept+/
745 { return qstrcmp(a1, a2) >= 0; }+/
746 /+pragma(inline, true) bool operator >=(ref const(QByteArray) a1, const(char)* a2)/+ noexcept+/
747 { return qstrcmp(a1, a2) >= 0; }+/
748 /+pragma(inline, true) bool operator >=(const(char)* a1, ref const(QByteArray) a2)/+ noexcept+/
749 { return qstrcmp(a1, a2) >= 0; }+/
750 version(QT_USE_QSTRINGBUILDER){}else
751 {
752 /+pragma(inline, true) const(QByteArray) operator +(ref const(QByteArray) a1, ref const(QByteArray) a2)
753 { return QByteArray(a1) ~= a2; }+/
754 /+pragma(inline, true) const(QByteArray) operator +(ref const(QByteArray) a1, const(char)* a2)
755 { return QByteArray(a1) ~= a2; }+/
756 /+pragma(inline, true) const(QByteArray) operator +(ref const(QByteArray) a1, char a2)
757 { return QByteArray(a1) ~= a2; }+/
758 /+pragma(inline, true) const(QByteArray) operator +(const(char)* a1, ref const(QByteArray) a2)
759 { return QByteArray(a1) ~= a2; }+/
760 /+pragma(inline, true) const(QByteArray) operator +(char a1, ref const(QByteArray) a2)
761 { return QByteArray(&a1, 1) ~= a2; }+/
762 }
763 
764 /+ inline std::string QByteArray::toStdString() const
765 { return std::string(constData(), length()); }
766 
767 inline QByteArray QByteArray::fromStdString(const std::string &s)
768 { return QByteArray(s.data(), int(s.size())); }
769 
770 #if !defined(QT_NO_DATASTREAM) || (defined(QT_BOOTSTRAPPED) && !defined(QT_BUILD_QMAKE))
771 Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QByteArray &);
772 Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QByteArray &);
773 #endif +/
774 
775 version(QT_NO_COMPRESS){}else
776 {
777 /+ Q_CORE_EXPORT +/ QByteArray qCompress(const(uchar)* data, int nbytes, int compressionLevel = -1);
778 /+ Q_CORE_EXPORT +/ QByteArray qUncompress(const(uchar)* data, int nbytes);
779 /+pragma(inline, true) QByteArray qCompress(ref const(QByteArray) data, int compressionLevel = -1)
780 { return qCompress(reinterpret_cast!(const(uchar)*)(data.constData()), data.size(), compressionLevel); }
781 pragma(inline, true) QByteArray qUncompress(ref const(QByteArray) data)
782 { return qUncompress(reinterpret_cast!(const(uchar)*)(data.constData()), data.size()); }
783 +/
784 }
785 
786 /+ Q_DECLARE_SHARED(QByteArray)
787 
788 Q_DECLARE_SHARED(QByteArray::FromBase64Result) +/
789 
790 /+pragma(inline, true) bool operator ==(ref const(QByteArray.FromBase64Result) lhs, ref const(QByteArray.FromBase64Result) rhs)/+ noexcept+/
791 {
792     if (lhs.decodingStatus != rhs.decodingStatus)
793         return false;
794 
795     if (lhs.decodingStatus == QByteArray.Base64DecodingStatus.Ok && lhs.decoded != rhs.decoded)
796         return false;
797 
798     return true;
799 }+/
800 
801 /+pragma(inline, true) bool operator !=(ref const(QByteArray.FromBase64Result) lhs, ref const(QByteArray.FromBase64Result) rhs)/+ noexcept+/
802 {
803     return !operator==(lhs, rhs);
804 }+/
805 
806 /+ Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QByteArray::FromBase64Result &key, uint seed = 0) noexcept;
807 typedef QArrayData QByteArrayData; +/
808