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