1 /*
2  * DQt - D bindings for the Qt Toolkit
3  *
4  * GNU Lesser General Public License Usage
5  * This file may be used under the terms of the GNU Lesser
6  * General Public License version 3 as published by the Free Software
7  * Foundation and appearing in the file LICENSE.LGPL3 included in the
8  * packaging of this file. Please review the following information to
9  * ensure the GNU Lesser General Public License version 3 requirements
10  * will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
11  */
12 module qt.core.datastream;
13 extern(C++):
14 
15 import qt.config;
16 import qt.helpers;
17 version(QT_NO_DATASTREAM){}else
18 {
19     import qt.core.bytearray;
20     import qt.core.global;
21     import qt.core.iodevice;
22     import qt.core.iodevicebase;
23     import qt.core.scopedpointer;
24     import qt.core.sysinfo;
25     import qt.core.typeinfo;
26 }
27 
28 
29 /+ #ifdef Status
30 #error qdatastream.h must be included before any header file that defines Status
31 #endif +/
32 
33 
34 
35 version(QT_NO_DATASTREAM){}else
36 {
37 extern(C++, class) struct QDataStreamPrivate;
38 /+ namespace QtPrivate {
39 class StreamStateSaver;
40 } +/
41 /// Binding for C++ class [QDataStream](https://doc.qt.io/qt-6/qdatastream.html).
42 extern(C++, class) struct /+ Q_CORE_EXPORT +/ QDataStream
43 {
44     /*public QIODeviceBase base0;
45     alias base0 this;*/
46     alias OpenModeFlag = QIODeviceBase.OpenModeFlag;
47     alias OpenMode = QIODeviceBase.OpenMode;
48 public:
49     enum Version {
50         Qt_1_0 = 1,
51         Qt_2_0 = 2,
52         Qt_2_1 = 3,
53         Qt_3_0 = 4,
54         Qt_3_1 = 5,
55         Qt_3_3 = 6,
56         Qt_4_0 = 7,
57         Qt_4_1 = Version.Qt_4_0,
58         Qt_4_2 = 8,
59         Qt_4_3 = 9,
60         Qt_4_4 = 10,
61         Qt_4_5 = 11,
62         Qt_4_6 = 12,
63         Qt_4_7 = Version.Qt_4_6,
64         Qt_4_8 = Version.Qt_4_7,
65         Qt_4_9 = Version.Qt_4_8,
66         Qt_5_0 = 13,
67         Qt_5_1 = 14,
68         Qt_5_2 = 15,
69         Qt_5_3 = Version.Qt_5_2,
70         Qt_5_4 = 16,
71         Qt_5_5 = Version.Qt_5_4,
72         Qt_5_6 = 17,
73         Qt_5_7 = Version.Qt_5_6,
74         Qt_5_8 = Version.Qt_5_7,
75         Qt_5_9 = Version.Qt_5_8,
76         Qt_5_10 = Version.Qt_5_9,
77         Qt_5_11 = Version.Qt_5_10,
78         Qt_5_12 = 18,
79         Qt_5_13 = 19,
80         Qt_5_14 = Version.Qt_5_13,
81         Qt_5_15 = Version.Qt_5_14,
82         Qt_6_0 = 20,
83         Qt_6_1 = Version.Qt_6_0,
84         Qt_6_2 = Version.Qt_6_0,
85         Qt_DefaultCompiledVersion = Version.Qt_6_2
86 /+ #if QT_VERSION >= 0x060300
87 #error Add the datastream version for this Qt version and update Qt_DefaultCompiledVersion
88 #endif +/
89     }
90 
91     enum ByteOrder {
92         BigEndian = QSysInfo.Endian.BigEndian,
93         LittleEndian = QSysInfo.Endian.LittleEndian
94     }
95 
96     enum Status {
97         Ok,
98         ReadPastEnd,
99         ReadCorruptData,
100         WriteFailed
101     }
102 
103     enum FloatingPointPrecision {
104         SinglePrecision,
105         DoublePrecision
106     }
107 
108     @disable this();
109     pragma(mangle, defaultConstructorMangling(__traits(identifier, typeof(this))))
110     ref typeof(this) rawConstructor();
111     static typeof(this) create()
112     {
113         typeof(this) r = typeof(this).init;
114         r.rawConstructor();
115         return r;
116     }
117 
118     /+ explicit +/this(QIODevice );
119     this(QByteArray* , OpenMode flags);
120     this(ref const(QByteArray) );
121     ~this();
122 
123     pragma(inline, true) QIODevice device() const
124     { return cast(QIODevice)dev; }
125     void setDevice(QIODevice );
126 
127     bool atEnd() const;
128 
129     Status status() const;
130     void setStatus(Status status);
131     void resetStatus();
132 
133     FloatingPointPrecision floatingPointPrecision() const;
134     void setFloatingPointPrecision(FloatingPointPrecision precision);
135 
136     pragma(inline, true) ByteOrder byteOrder() const
137     { return byteorder; }
138     void setByteOrder(ByteOrder);
139 
140     pragma(inline, true) int version_() const
141     { return ver; }
142     pragma(inline, true) void setVersion(int v)
143     { ver = v; }
144 
145     /+pragma(inline, true) ref QDataStream operator >>(ref char i)
146     { return this >> reinterpret_cast!(ref qint8)(i); }+/
147     /+ref QDataStream operator >>(ref qint8 i);+/
148     /+pragma(inline, true) ref QDataStream operator >>(ref quint8 i)
149     { return this >> reinterpret_cast!(ref qint8)(i); }+/
150     /+ref QDataStream operator >>(ref qint16 i);+/
151     /+pragma(inline, true) ref QDataStream operator >>(ref quint16 i)
152     { return this >> reinterpret_cast!(ref qint16)(i); }+/
153     /+ref QDataStream operator >>(ref qint32 i);+/
154     /+pragma(inline, true) ref QDataStream operator >>(ref quint32 i)
155     { return this >> reinterpret_cast!(ref qint32)(i); }+/
156     /+ref QDataStream operator >>(ref qint64 i);+/
157     /+pragma(inline, true) ref QDataStream operator >>(ref quint64 i)
158     { return this >> reinterpret_cast!(ref qint64)(i); }+/
159     /+ref QDataStream operator >>(ref /+ std:: +/nullptr_t ptr) { ptr = null; return this; }+/
160 
161     /+ref QDataStream operator >>(ref bool i);+/
162     /+ref QDataStream operator >>(ref qfloat16 f);+/
163     /+ref QDataStream operator >>(ref float f);+/
164     /+ref QDataStream operator >>(ref double f);+/
165     /+ref QDataStream operator >>(ref char* str);+/
166     /+ref QDataStream operator >>(ref wchar c);+/
167     /+ref QDataStream operator >>(ref dchar c);+/
168 
169     /+pragma(inline, true) ref QDataStream operator <<(char i)
170     { return this << qint8(i); }+/
171     /+ref QDataStream operator <<(qint8 i);+/
172     /+pragma(inline, true) ref QDataStream operator <<(quint8 i)
173     { return this << qint8(i); }+/
174     /+ref QDataStream operator <<(qint16 i);+/
175     /+pragma(inline, true) ref QDataStream operator <<(quint16 i)
176     { return this << qint16(i); }+/
177     /+ref QDataStream operator <<(qint32 i);+/
178     /+pragma(inline, true) ref QDataStream operator <<(quint32 i)
179     { return this << qint32(i); }+/
180     /+ref QDataStream operator <<(qint64 i);+/
181     /+pragma(inline, true) ref QDataStream operator <<(quint64 i)
182     { return this << qint64(i); }+/
183     /+ref QDataStream operator <<(/+ std:: +/nullptr_t) { return this; }+/
184     /+ref QDataStream operator <<(bool i);+/
185     /+ref QDataStream operator <<(qfloat16 f);+/
186     /+ref QDataStream operator <<(float f);+/
187     /+ref QDataStream operator <<(double f);+/
188     /+ref QDataStream operator <<(const(char)* str);+/
189     /+ref QDataStream operator <<(wchar c);+/
190     /+ref QDataStream operator <<(dchar c);+/
191 
192 
193     ref QDataStream readBytes(ref char* , ref uint len);
194     int readRawData(char* , int len);
195 
196     ref QDataStream writeBytes(const(char)* , uint len);
197     int writeRawData(const(char)* , int len);
198 
199     int skipRawData(int len);
200 
201     void startTransaction();
202     bool commitTransaction();
203     void rollbackTransaction();
204     void abortTransaction();
205 
206     bool isDeviceTransactionStarted() const;
207 private:
208     /+ Q_DISABLE_COPY(QDataStream) +/
209 @disable this(this);
210 /+this(ref const(QDataStream));+//+ref QDataStream operator =(ref const(QDataStream));+/
211     QScopedPointer!(QDataStreamPrivate) d;
212 
213     QIODevice dev;
214     bool owndev;
215     bool noswap;
216     ByteOrder byteorder;
217     int ver;
218     Status q_status;
219 
220     int readBlock(char* data, int len);
221     /+ friend class QtPrivate::StreamStateSaver; +/
222     mixin(CREATE_CONVENIENCE_WRAPPERS);
223 }
224 
225 extern(C++, "QtPrivate") {
226 
227 /+ class StreamStateSaver
228 {
229 public:
230     inline StreamStateSaver(QDataStream *s) : stream(s), oldStatus(s->status())
231     {
232         if (!stream->isDeviceTransactionStarted())
233             stream->resetStatus();
234     }
235     inline ~StreamStateSaver()
236     {
237         if (oldStatus != QDataStream::Ok) {
238             stream->resetStatus();
239             stream->setStatus(oldStatus);
240         }
241     }
242 
243 private:
244     QDataStream *stream;
245     QDataStream::Status oldStatus;
246 };
247 
248 template <typename Container>
249 QDataStream &readArrayBasedContainer(QDataStream &s, Container &c)
250 {
251     StreamStateSaver stateSaver(&s);
252 
253     c.clear();
254     quint32 n;
255     s >> n;
256     c.reserve(n);
257     for (quint32 i = 0; i < n; ++i) {
258         typename Container::value_type t;
259         s >> t;
260         if (s.status() != QDataStream::Ok) {
261             c.clear();
262             break;
263         }
264         c.append(t);
265     }
266 
267     return s;
268 }
269 
270 template <typename Container>
271 QDataStream &readListBasedContainer(QDataStream &s, Container &c)
272 {
273     StreamStateSaver stateSaver(&s);
274 
275     c.clear();
276     quint32 n;
277     s >> n;
278     for (quint32 i = 0; i < n; ++i) {
279         typename Container::value_type t;
280         s >> t;
281         if (s.status() != QDataStream::Ok) {
282             c.clear();
283             break;
284         }
285         c << t;
286     }
287 
288     return s;
289 }
290 
291 template <typename Container>
292 QDataStream &readAssociativeContainer(QDataStream &s, Container &c)
293 {
294     StreamStateSaver stateSaver(&s);
295 
296     c.clear();
297     quint32 n;
298     s >> n;
299     for (quint32 i = 0; i < n; ++i) {
300         typename Container::key_type k;
301         typename Container::mapped_type t;
302         s >> k >> t;
303         if (s.status() != QDataStream::Ok) {
304             c.clear();
305             break;
306         }
307         c.insert(k, t);
308     }
309 
310     return s;
311 }
312 
313 template <typename Container>
314 QDataStream &writeSequentialContainer(QDataStream &s, const Container &c)
315 {
316     s << quint32(c.size());
317     for (const typename Container::value_type &t : c)
318         s << t;
319 
320     return s;
321 }
322 
323 template <typename Container>
324 QDataStream &writeAssociativeContainer(QDataStream &s, const Container &c)
325 {
326     s << quint32(c.size());
327     auto it = c.constBegin();
328     auto end = c.constEnd();
329     while (it != end) {
330         s << it.key() << it.value();
331         ++it;
332     }
333 
334     return s;
335 } +/
336 
337 /+ref QDataStream writeAssociativeMultiContainer(Container)(ref QDataStream s, ref const(Container) c)
338 {
339     s << quint32(c.size());
340     auto it = c.constBegin();
341     auto end = c.constEnd();
342     while (it != end) {
343         const rangeStart = it++;
344         while (it != end && rangeStart.key() == it.key())
345             ++it;
346         const(qint64) last = /+ std:: +/distance(rangeStart, it) - 1;
347         for (qint64 i = last; i >= 0; --i) {
348             auto next = /+ std:: +/next(rangeStart, i);
349             s << next.key() << next.value();
350         }
351     }
352 
353     return s;
354 }+/
355 
356 } // QtPrivate namespace
357 
358 /+ alias QDataStreamIfHasOStreamOperators(T) =
359     /+ std:: +/enable_if_t!(bool, ref QDataStream);
360 alias QDataStreamIfHasOStreamOperatorsContainer(Container, T) =
361     /+ std:: +/enable_if_t!(bool, ref QDataStream);
362 
363 alias QDataStreamIfHasIStreamOperators(T) =
364     /+ std:: +/enable_if_t!(bool, ref QDataStream);
365 alias QDataStreamIfHasIStreamOperatorsContainer(Container, T) =
366     /+ std:: +/enable_if_t!(bool, ref QDataStream); +/
367 
368 /*****************************************************************************
369   QDataStream inline functions
370  *****************************************************************************/
371 
372 /+ template <typename Enum>
373 inline QDataStream &operator<<(QDataStream &s, QFlags<Enum> e)
374 { return s << typename QFlags<Enum>::Int(e); }
375 
376 template <typename Enum>
377 inline QDataStream &operator>>(QDataStream &s, QFlags<Enum> &e)
378 {
379     typename QFlags<Enum>::Int i;
380     s >> i;
381     e = QFlag(i);
382     return s;
383 }
384 
385 template <typename T>
386 typename std::enable_if_t<std::is_enum<T>::value, QDataStream &>
387 operator<<(QDataStream &s, const T &t)
388 { return s << static_cast<typename std::underlying_type<T>::type>(t); }
389 
390 template <typename T>
391 typename std::enable_if_t<std::is_enum<T>::value, QDataStream &>
392 operator>>(QDataStream &s, T &t)
393 { return s >> reinterpret_cast<typename std::underlying_type<T>::type &>(t); }
394 
395 #ifndef Q_CLANG_QDOC
396 
397 template<typename T>
398 inline QDataStreamIfHasIStreamOperatorsContainer<QList<T>, T> operator>>(QDataStream &s, QList<T> &v)
399 {
400     return QtPrivate::readArrayBasedContainer(s, v);
401 }
402 
403 template<typename T>
404 inline QDataStreamIfHasOStreamOperatorsContainer<QList<T>, T> operator<<(QDataStream &s, const QList<T> &v)
405 {
406     return QtPrivate::writeSequentialContainer(s, v);
407 }
408 
409 template <typename T>
410 inline QDataStreamIfHasIStreamOperatorsContainer<QSet<T>, T> operator>>(QDataStream &s, QSet<T> &set)
411 {
412     return QtPrivate::readListBasedContainer(s, set);
413 }
414 
415 template <typename T>
416 inline QDataStreamIfHasOStreamOperatorsContainer<QSet<T>, T> operator<<(QDataStream &s, const QSet<T> &set)
417 {
418     return QtPrivate::writeSequentialContainer(s, set);
419 }
420 
421 template <class Key, class T>
422 inline QDataStreamIfHasIStreamOperatorsContainer<QHash<Key, T>, Key, T> operator>>(QDataStream &s, QHash<Key, T> &hash)
423 {
424     return QtPrivate::readAssociativeContainer(s, hash);
425 }
426 
427 template <class Key, class T>
428 
429 inline QDataStreamIfHasOStreamOperatorsContainer<QHash<Key, T>, Key, T> operator<<(QDataStream &s, const QHash<Key, T> &hash)
430 {
431     return QtPrivate::writeAssociativeContainer(s, hash);
432 }
433 
434 template <class Key, class T>
435 inline QDataStreamIfHasIStreamOperatorsContainer<QMultiHash<Key, T>, Key, T> operator>>(QDataStream &s, QMultiHash<Key, T> &hash)
436 {
437     return QtPrivate::readAssociativeContainer(s, hash);
438 }
439 
440 template <class Key, class T>
441 inline QDataStreamIfHasOStreamOperatorsContainer<QMultiHash<Key, T>, Key, T> operator<<(QDataStream &s, const QMultiHash<Key, T> &hash)
442 {
443     return QtPrivate::writeAssociativeMultiContainer(s, hash);
444 }
445 
446 template <class Key, class T>
447 inline QDataStreamIfHasIStreamOperatorsContainer<QMap<Key, T>, Key, T> operator>>(QDataStream &s, QMap<Key, T> &map)
448 {
449     return QtPrivate::readAssociativeContainer(s, map);
450 }
451 
452 template <class Key, class T>
453 inline QDataStreamIfHasOStreamOperatorsContainer<QMap<Key, T>, Key, T> operator<<(QDataStream &s, const QMap<Key, T> &map)
454 {
455     return QtPrivate::writeAssociativeContainer(s, map);
456 }
457 
458 template <class Key, class T>
459 inline QDataStreamIfHasIStreamOperatorsContainer<QMultiMap<Key, T>, Key, T> operator>>(QDataStream &s, QMultiMap<Key, T> &map)
460 {
461     return QtPrivate::readAssociativeContainer(s, map);
462 }
463 
464 template <class Key, class T>
465 inline QDataStreamIfHasOStreamOperatorsContainer<QMultiMap<Key, T>, Key, T> operator<<(QDataStream &s, const QMultiMap<Key, T> &map)
466 {
467     return QtPrivate::writeAssociativeMultiContainer(s, map);
468 }
469 
470 #ifndef QT_NO_DATASTREAM
471 template <class T1, class T2>
472 inline QDataStreamIfHasIStreamOperators<T1, T2> operator>>(QDataStream& s, std::pair<T1, T2> &p)
473 {
474     s >> p.first >> p.second;
475     return s;
476 }
477 
478 template <class T1, class T2>
479 inline QDataStreamIfHasOStreamOperators<T1, T2> operator<<(QDataStream& s, const std::pair<T1, T2> &p)
480 {
481     s << p.first << p.second;
482     return s;
483 }
484 #endif
485 
486 #else
487 
488 template <class T>
489 QDataStream &operator>>(QDataStream &s, QList<T> &l);
490 
491 template <class T>
492 QDataStream &operator<<(QDataStream &s, const QList<T> &l);
493 
494 template <class T>
495 QDataStream &operator>>(QDataStream &s, QSet<T> &set);
496 
497 template <class T>
498 QDataStream &operator<<(QDataStream &s, const QSet<T> &set);
499 
500 template <class Key, class T>
501 QDataStream &operator>>(QDataStream &s, QHash<Key, T> &hash);
502 
503 template <class Key, class T>
504 QDataStream &operator<<(QDataStream &s, const QHash<Key, T> &hash);
505 
506 template <class Key, class T>
507 QDataStream &operator>>(QDataStream &s, QMultiHash<Key, T> &hash);
508 
509 template <class Key, class T>
510 QDataStream &operator<<(QDataStream &s, const QMultiHash<Key, T> &hash);
511 
512 template <class Key, class T>
513 QDataStream &operator>>(QDataStream &s, QMap<Key, T> &map);
514 
515 template <class Key, class T>
516 QDataStream &operator<<(QDataStream &s, const QMap<Key, T> &map);
517 
518 template <class Key, class T>
519 QDataStream &operator>>(QDataStream &s, QMultiMap<Key, T> &map);
520 
521 template <class Key, class T>
522 QDataStream &operator<<(QDataStream &s, const QMultiMap<Key, T> &map);
523 
524 template <class T1, class T2>
525 QDataStream &operator>>(QDataStream& s, std::pair<T1, T2> &p);
526 
527 template <class T1, class T2>
528 QDataStream &operator<<(QDataStream& s, const std::pair<T1, T2> &p);
529 
530 #endif // Q_CLANG_QDOC
531 
532 inline QDataStream &operator>>(QDataStream &s, QKeyCombination &combination)
533 {
534     int combined;
535     s >> combined;
536     combination = QKeyCombination::fromCombined(combined);
537     return s;
538 }
539 
540 inline QDataStream &operator<<(QDataStream &s, QKeyCombination combination)
541 {
542     return s << combination.toCombined();
543 } +/
544 
545 }
546 
547 
548 version(QT_NO_DATASTREAM)
549 {
550 extern(C++, class) struct QDataStream;
551 }
552 
553 
554 
555