src/corelib/io/qdatastream.cpp
changeset 30 5dc02b23752f
parent 18 2f34d5167611
equal deleted inserted replaced
29:b72c6db6890b 30:5dc02b23752f
    46 #include "qbuffer.h"
    46 #include "qbuffer.h"
    47 #include "qstring.h"
    47 #include "qstring.h"
    48 #include <stdio.h>
    48 #include <stdio.h>
    49 #include <ctype.h>
    49 #include <ctype.h>
    50 #include <stdlib.h>
    50 #include <stdlib.h>
       
    51 #include "qendian.h"
    51 
    52 
    52 QT_BEGIN_NAMESPACE
    53 QT_BEGIN_NAMESPACE
    53 
    54 
    54 /*!
    55 /*!
    55     \class QDataStream
    56     \class QDataStream
    88 
    89 
    89     Each item written to the stream is written in a predefined binary
    90     Each item written to the stream is written in a predefined binary
    90     format that varies depending on the item's type. Supported Qt
    91     format that varies depending on the item's type. Supported Qt
    91     types include QBrush, QColor, QDateTime, QFont, QPixmap, QString,
    92     types include QBrush, QColor, QDateTime, QFont, QPixmap, QString,
    92     QVariant and many others. For the complete list of all Qt types
    93     QVariant and many others. For the complete list of all Qt types
    93     supporting data streaming see the \l{Format of the QDataStream
    94     supporting data streaming see \l{Serializing Qt Data Types}.
    94     operators}.
       
    95 
    95 
    96     For integers it is best to always cast to a Qt integer type for
    96     For integers it is best to always cast to a Qt integer type for
    97     writing, and to read back into the same Qt integer type. This
    97     writing, and to read back into the same Qt integer type. This
    98     ensures that you get integers of the size you want and insulates
    98     ensures that you get integers of the size you want and insulates
    99     you from compiler and platform differences.
    99     you from compiler and platform differences.
   574     \value Qt_4_2 Version 8 (Qt 4.2)
   574     \value Qt_4_2 Version 8 (Qt 4.2)
   575     \value Qt_4_3 Version 9 (Qt 4.3)
   575     \value Qt_4_3 Version 9 (Qt 4.3)
   576     \value Qt_4_4 Version 10 (Qt 4.4)
   576     \value Qt_4_4 Version 10 (Qt 4.4)
   577     \value Qt_4_5 Version 11 (Qt 4.5)
   577     \value Qt_4_5 Version 11 (Qt 4.5)
   578     \value Qt_4_6 Version 12 (Qt 4.6)
   578     \value Qt_4_6 Version 12 (Qt 4.6)
       
   579     \value Qt_4_7 Same as Qt_4_6.
   579 
   580 
   580     \sa setVersion(), version()
   581     \sa setVersion(), version()
   581 */
   582 */
   582 
   583 
   583 /*!
   584 /*!
   676 
   677 
   677 QDataStream &QDataStream::operator>>(qint16 &i)
   678 QDataStream &QDataStream::operator>>(qint16 &i)
   678 {
   679 {
   679     i = 0;
   680     i = 0;
   680     CHECK_STREAM_PRECOND(*this)
   681     CHECK_STREAM_PRECOND(*this)
   681     if (noswap) {
   682     if (dev->read((char *)&i, 2) != 2) {
   682         if (dev->read((char *)&i, 2) != 2) {
   683         i = 0;
   683             i = 0;
   684         setStatus(ReadPastEnd);
   684             setStatus(ReadPastEnd);
       
   685         }
       
   686     } else {
   685     } else {
   687         union {
   686         if (!noswap) {
   688             qint16 val1;
   687             i = qbswap(i);
   689             char val2[2];
       
   690         } x;
       
   691         char *p = x.val2;
       
   692         char b[2];
       
   693         if (dev->read(b, 2) == 2) {
       
   694             *p++ = b[1];
       
   695             *p = b[0];
       
   696             i = x.val1;
       
   697         } else {
       
   698             setStatus(ReadPastEnd);
       
   699         }
   688         }
   700     }
   689     }
   701     return *this;
   690     return *this;
   702 }
   691 }
   703 
   692 
   719 
   708 
   720 QDataStream &QDataStream::operator>>(qint32 &i)
   709 QDataStream &QDataStream::operator>>(qint32 &i)
   721 {
   710 {
   722     i = 0;
   711     i = 0;
   723     CHECK_STREAM_PRECOND(*this)
   712     CHECK_STREAM_PRECOND(*this)
   724     if (noswap) {
   713     if (dev->read((char *)&i, 4) != 4) {
   725         if (dev->read((char *)&i, 4) != 4) {
   714         i = 0;
   726             i = 0;
   715         setStatus(ReadPastEnd);
   727             setStatus(ReadPastEnd);
   716     } else {
   728         }
   717         if (!noswap) {
   729     } else {                                        // swap bytes
   718             i = qbswap(i);
   730         union {
       
   731             qint32 val1;
       
   732             char val2[4];
       
   733         } x;
       
   734         char *p = x.val2;
       
   735         char b[4];
       
   736         if (dev->read(b, 4) == 4) {
       
   737             *p++ = b[3];
       
   738             *p++ = b[2];
       
   739             *p++ = b[1];
       
   740             *p   = b[0];
       
   741             i = x.val1;
       
   742         } else {
       
   743             setStatus(ReadPastEnd);
       
   744         }
   719         }
   745     }
   720     }
   746     return *this;
   721     return *this;
   747 }
   722 }
   748 
   723 
   767     CHECK_STREAM_PRECOND(*this)
   742     CHECK_STREAM_PRECOND(*this)
   768     if (version() < 6) {
   743     if (version() < 6) {
   769         quint32 i1, i2;
   744         quint32 i1, i2;
   770         *this >> i2 >> i1;
   745         *this >> i2 >> i1;
   771         i = ((quint64)i1 << 32) + i2;
   746         i = ((quint64)i1 << 32) + i2;
   772     } else if (noswap) {                        // no conversion needed
   747     } else {
   773         if (dev->read((char *)&i, 8) != 8) {
   748         if (dev->read((char *)&i, 8) != 8) {
   774             i = qint64(0);
   749             i = qint64(0);
   775             setStatus(ReadPastEnd);
   750             setStatus(ReadPastEnd);
   776         }
       
   777     } else {                                        // swap bytes
       
   778         union {
       
   779             qint64 val1;
       
   780             char val2[8];
       
   781         } x;
       
   782 
       
   783         char *p = x.val2;
       
   784         char b[8];
       
   785         if (dev->read(b, 8) == 8) {
       
   786             *p++ = b[7];
       
   787             *p++ = b[6];
       
   788             *p++ = b[5];
       
   789             *p++ = b[4];
       
   790             *p++ = b[3];
       
   791             *p++ = b[2];
       
   792             *p++ = b[1];
       
   793             *p   = b[0];
       
   794             i = x.val1;
       
   795         } else {
   751         } else {
   796             setStatus(ReadPastEnd);
   752             if (!noswap) {
       
   753                 i = qbswap(i);
       
   754             }
   797         }
   755         }
   798     }
   756     }
   799     return *this;
   757     return *this;
   800 }
   758 }
   801 
   759 
   831         return *this;
   789         return *this;
   832     }
   790     }
   833 
   791 
   834     f = 0.0f;
   792     f = 0.0f;
   835     CHECK_STREAM_PRECOND(*this)
   793     CHECK_STREAM_PRECOND(*this)
   836     if (noswap) {
   794     if (dev->read((char *)&f, 4) != 4) {
   837         if (dev->read((char *)&f, 4) != 4) {
   795         f = 0.0f;
   838             f = 0.0f;
   796         setStatus(ReadPastEnd);
   839             setStatus(ReadPastEnd);
   797     } else {
   840         }
   798         if (!noswap) {
   841     } else {                                        // swap bytes
   799             union {
   842         union {
   800                 float val1;
   843             float val1;
   801                 quint32 val2;
   844             char val2[4];
   802             } x;
   845         } x;
   803             x.val2 = qbswap(*reinterpret_cast<quint32 *>(&f));
   846 
       
   847         char *p = x.val2;
       
   848         char b[4];
       
   849         if (dev->read(b, 4) == 4) {
       
   850             *p++ = b[3];
       
   851             *p++ = b[2];
       
   852             *p++ = b[1];
       
   853             *p = b[0];
       
   854             f = x.val1;
   804             f = x.val1;
   855         } else {
       
   856             setStatus(ReadPastEnd);
       
   857         }
   805         }
   858     }
   806     }
   859     return *this;
   807     return *this;
   860 }
   808 }
   861 
   809 
   884     }
   832     }
   885 
   833 
   886     f = 0.0;
   834     f = 0.0;
   887     CHECK_STREAM_PRECOND(*this)
   835     CHECK_STREAM_PRECOND(*this)
   888 #ifndef Q_DOUBLE_FORMAT
   836 #ifndef Q_DOUBLE_FORMAT
   889     if (noswap) {
   837     if (dev->read((char *)&f, 8) != 8) {
   890         if (dev->read((char *)&f, 8) != 8) {
   838         f = 0.0;
   891             f = 0.0;
   839         setStatus(ReadPastEnd);
   892             setStatus(ReadPastEnd);
   840     } else {
   893         }
   841         if (!noswap) {
   894     } else {                                        // swap bytes
   842             union {
   895         union {
   843                 double val1;
   896             double val1;
   844                 quint64 val2;
   897             char val2[8];
   845             } x;
   898         } x;
   846             x.val2 = qbswap(*reinterpret_cast<quint64 *>(&f));
   899         char *p = x.val2;
       
   900         char b[8];
       
   901         if (dev->read(b, 8) == 8) {
       
   902             *p++ = b[7];
       
   903             *p++ = b[6];
       
   904             *p++ = b[5];
       
   905             *p++ = b[4];
       
   906             *p++ = b[3];
       
   907             *p++ = b[2];
       
   908             *p++ = b[1];
       
   909             *p   = b[0];
       
   910             f = x.val1;
   847             f = x.val1;
   911         } else {
       
   912             setStatus(ReadPastEnd);
       
   913         }
   848         }
   914     }
   849     }
   915 #else
   850 #else
   916     //non-standard floating point format
   851     //non-standard floating point format
   917     union {
   852     union {
  1079 */
  1014 */
  1080 
  1015 
  1081 QDataStream &QDataStream::operator<<(qint16 i)
  1016 QDataStream &QDataStream::operator<<(qint16 i)
  1082 {
  1017 {
  1083     CHECK_STREAM_PRECOND(*this)
  1018     CHECK_STREAM_PRECOND(*this)
  1084     if (noswap) {
  1019     if (!noswap) {
  1085         dev->write((char *)&i, sizeof(qint16));
  1020         i = qbswap(i);
  1086     } else {                                        // swap bytes
  1021     }
  1087         union {
  1022     dev->write((char *)&i, sizeof(qint16));
  1088             qint16 val1;
       
  1089             char val2[2];
       
  1090         } x;
       
  1091         x.val1 = i;
       
  1092         char *p = x.val2;
       
  1093         char b[2];
       
  1094         b[1] = *p++;
       
  1095         b[0] = *p;
       
  1096         dev->write(b, 2);
       
  1097     }
       
  1098     return *this;
  1023     return *this;
  1099 }
  1024 }
  1100 
  1025 
  1101 /*!
  1026 /*!
  1102     \overload
  1027     \overload
  1106 */
  1031 */
  1107 
  1032 
  1108 QDataStream &QDataStream::operator<<(qint32 i)
  1033 QDataStream &QDataStream::operator<<(qint32 i)
  1109 {
  1034 {
  1110     CHECK_STREAM_PRECOND(*this)
  1035     CHECK_STREAM_PRECOND(*this)
  1111     if (noswap) {
  1036     if (!noswap) {
  1112         dev->write((char *)&i, sizeof(qint32));
  1037         i = qbswap(i);
  1113     } else {                                        // swap bytes
  1038     }
  1114         union {
  1039     dev->write((char *)&i, sizeof(qint32));
  1115             qint32 val1;
       
  1116             char val2[4];
       
  1117         } x;
       
  1118         x.val1 = i;
       
  1119         char *p = x.val2;
       
  1120         char b[4];
       
  1121         b[3] = *p++;
       
  1122         b[2] = *p++;
       
  1123         b[1] = *p++;
       
  1124         b[0] = *p;
       
  1125         dev->write(b, 4);
       
  1126     }
       
  1127     return *this;
  1040     return *this;
  1128 }
  1041 }
  1129 
  1042 
  1130 /*!
  1043 /*!
  1131     \fn QDataStream &QDataStream::operator<<(quint64 i)
  1044     \fn QDataStream &QDataStream::operator<<(quint64 i)
  1147     CHECK_STREAM_PRECOND(*this)
  1060     CHECK_STREAM_PRECOND(*this)
  1148     if (version() < 6) {
  1061     if (version() < 6) {
  1149         quint32 i1 = i & 0xffffffff;
  1062         quint32 i1 = i & 0xffffffff;
  1150         quint32 i2 = i >> 32;
  1063         quint32 i2 = i >> 32;
  1151         *this << i2 << i1;
  1064         *this << i2 << i1;
  1152     } else if (noswap) {                        // no conversion needed
  1065     } else {
       
  1066         if (!noswap) {
       
  1067             i = qbswap(i);
       
  1068         }
  1153         dev->write((char *)&i, sizeof(qint64));
  1069         dev->write((char *)&i, sizeof(qint64));
  1154     } else {                                        // swap bytes
       
  1155         union {
       
  1156             qint64 val1;
       
  1157             char val2[8];
       
  1158         } x;
       
  1159         x.val1 = i;
       
  1160         char *p = x.val2;
       
  1161         char b[8];
       
  1162         b[7] = *p++;
       
  1163         b[6] = *p++;
       
  1164         b[5] = *p++;
       
  1165         b[4] = *p++;
       
  1166         b[3] = *p++;
       
  1167         b[2] = *p++;
       
  1168         b[1] = *p++;
       
  1169         b[0] = *p;
       
  1170         dev->write(b, 8);
       
  1171     }
  1070     }
  1172     return *this;
  1071     return *this;
  1173 }
  1072 }
  1174 
  1073 
  1175 /*!
  1074 /*!
  1209         return *this;
  1108         return *this;
  1210     }
  1109     }
  1211 
  1110 
  1212     CHECK_STREAM_PRECOND(*this)
  1111     CHECK_STREAM_PRECOND(*this)
  1213     float g = f;                                // fixes float-on-stack problem
  1112     float g = f;                                // fixes float-on-stack problem
  1214     if (noswap) {                                // no conversion needed
  1113     if (!noswap) {
  1215         dev->write((char *)&g, sizeof(float));
       
  1216     } else {                                // swap bytes
       
  1217         union {
  1114         union {
  1218             float val1;
  1115             float val1;
  1219             char val2[4];
  1116             quint32 val2;
  1220         } x;
  1117         } x;
  1221         x.val1 = f;
  1118         x.val1 = g;
  1222         char *p = x.val2;
  1119         x.val2 = qbswap(x.val2);
  1223         char b[4];
  1120         g = x.val1;
  1224         b[3] = *p++;
  1121     }
  1225         b[2] = *p++;
  1122     dev->write((char *)&g, sizeof(float));
  1226         b[1] = *p++;
       
  1227         b[0] = *p;
       
  1228         dev->write(b, 4);
       
  1229     }
       
  1230     return *this;
  1123     return *this;
  1231 }
  1124 }
  1232 
  1125 
  1233 
  1126 
  1234 /*!
  1127 /*!
  1253     if (noswap) {
  1146     if (noswap) {
  1254         dev->write((char *)&f, sizeof(double));
  1147         dev->write((char *)&f, sizeof(double));
  1255     } else {
  1148     } else {
  1256         union {
  1149         union {
  1257             double val1;
  1150             double val1;
  1258             char val2[8];
  1151             quint64 val2;
  1259         } x;
  1152         } x;
  1260         x.val1 = f;
  1153         x.val1 = f;
  1261         char *p = x.val2;
  1154         x.val2 = qbswap(x.val2);
  1262         char b[8];
  1155         dev->write((char *)&x.val2, sizeof(double));
  1263         b[7] = *p++;
       
  1264         b[6] = *p++;
       
  1265         b[5] = *p++;
       
  1266         b[4] = *p++;
       
  1267         b[3] = *p++;
       
  1268         b[2] = *p++;
       
  1269         b[1] = *p++;
       
  1270         b[0] = *p;
       
  1271         dev->write(b, 8);
       
  1272     }
  1156     }
  1273 #else
  1157 #else
  1274     union {
  1158     union {
  1275         double val1;
  1159         double val1;
  1276         char val2[8];
  1160         char val2[8];