1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). |
4 | ** Contact: http://www.qt-project.org/ |
5 | ** |
6 | ** This file is part of the QtCore module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** GNU Lesser General Public License Usage |
10 | ** This file may be used under the terms of the GNU Lesser General Public |
11 | ** License version 2.1 as published by the Free Software Foundation and |
12 | ** appearing in the file LICENSE.LGPL included in the packaging of this |
13 | ** file. Please review the following information to ensure the GNU Lesser |
14 | ** General Public License version 2.1 requirements will be met: |
15 | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
16 | ** |
17 | ** In addition, as a special exception, Nokia gives you certain additional |
18 | ** rights. These rights are described in the Nokia Qt LGPL Exception |
19 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
20 | ** |
21 | ** GNU General Public License Usage |
22 | ** Alternatively, this file may be used under the terms of the GNU General |
23 | ** Public License version 3.0 as published by the Free Software Foundation |
24 | ** and appearing in the file LICENSE.GPL included in the packaging of this |
25 | ** file. Please review the following information to ensure the GNU General |
26 | ** Public License version 3.0 requirements will be met: |
27 | ** http://www.gnu.org/copyleft/gpl.html. |
28 | ** |
29 | ** Other Usage |
30 | ** Alternatively, this file may be used in accordance with the terms and |
31 | ** conditions contained in a signed written agreement between you and Nokia. |
32 | ** |
33 | ** |
34 | ** |
35 | ** |
36 | ** |
37 | ** |
38 | ** $QT_END_LICENSE$ |
39 | ** |
40 | ****************************************************************************/ |
41 | |
42 | #ifndef QDATASTREAM_H |
43 | #define QDATASTREAM_H |
44 | |
45 | #include <QtCore/qscopedpointer.h> |
46 | #include <QtCore/qiodevice.h> |
47 | #include <QtCore/qglobal.h> |
48 | |
49 | #ifdef Status |
50 | #error qdatastream.h must be included before any header file that defines Status |
51 | #endif |
52 | |
53 | QT_BEGIN_HEADER |
54 | |
55 | QT_BEGIN_NAMESPACE |
56 | |
57 | QT_MODULE(Core) |
58 | |
59 | class QByteArray; |
60 | class QIODevice; |
61 | |
62 | template <typename T> class QList; |
63 | template <typename T> class QLinkedList; |
64 | template <typename T> class QVector; |
65 | template <typename T> class QSet; |
66 | template <class Key, class T> class QHash; |
67 | template <class Key, class T> class QMap; |
68 | |
69 | #if !defined(QT_NO_DATASTREAM) || defined(QT_BOOTSTRAPPED) |
70 | class QDataStreamPrivate; |
71 | class Q_CORE_EXPORT QDataStream |
72 | { |
73 | public: |
74 | enum Version { |
75 | Qt_1_0 = 1, |
76 | Qt_2_0 = 2, |
77 | Qt_2_1 = 3, |
78 | Qt_3_0 = 4, |
79 | Qt_3_1 = 5, |
80 | Qt_3_3 = 6, |
81 | Qt_4_0 = 7, |
82 | Qt_4_1 = Qt_4_0, |
83 | Qt_4_2 = 8, |
84 | Qt_4_3 = 9, |
85 | Qt_4_4 = 10, |
86 | Qt_4_5 = 11, |
87 | Qt_4_6 = 12, |
88 | Qt_4_7 = Qt_4_6, |
89 | Qt_4_8 = Qt_4_7 |
90 | #if QT_VERSION >= 0x040900 |
91 | #error Add the datastream version for this Qt version |
92 | Qt_4_9 = Qt_4_8 |
93 | #endif |
94 | }; |
95 | |
96 | enum ByteOrder { |
97 | BigEndian = QSysInfo::BigEndian, |
98 | LittleEndian = QSysInfo::LittleEndian |
99 | }; |
100 | |
101 | enum Status { |
102 | Ok, |
103 | ReadPastEnd, |
104 | ReadCorruptData, |
105 | WriteFailed |
106 | }; |
107 | |
108 | enum FloatingPointPrecision { |
109 | SinglePrecision, |
110 | DoublePrecision |
111 | }; |
112 | |
113 | QDataStream(); |
114 | explicit QDataStream(QIODevice *); |
115 | #ifdef QT3_SUPPORT |
116 | QDataStream(QByteArray *, int mode); |
117 | #endif |
118 | QDataStream(QByteArray *, QIODevice::OpenMode flags); |
119 | QDataStream(const QByteArray &); |
120 | virtual ~QDataStream(); |
121 | |
122 | QIODevice *device() const; |
123 | void setDevice(QIODevice *); |
124 | void unsetDevice(); |
125 | |
126 | bool atEnd() const; |
127 | #ifdef QT3_SUPPORT |
128 | inline QT3_SUPPORT bool eof() const { return atEnd(); } |
129 | #endif |
130 | |
131 | Status status() const; |
132 | void setStatus(Status status); |
133 | void resetStatus(); |
134 | |
135 | FloatingPointPrecision floatingPointPrecision() const; |
136 | void setFloatingPointPrecision(FloatingPointPrecision precision); |
137 | |
138 | ByteOrder byteOrder() const; |
139 | void setByteOrder(ByteOrder); |
140 | |
141 | int version() const; |
142 | void setVersion(int); |
143 | |
144 | QDataStream &operator>>(qint8 &i); |
145 | QDataStream &operator>>(quint8 &i); |
146 | QDataStream &operator>>(qint16 &i); |
147 | QDataStream &operator>>(quint16 &i); |
148 | QDataStream &operator>>(qint32 &i); |
149 | QDataStream &operator>>(quint32 &i); |
150 | QDataStream &operator>>(qint64 &i); |
151 | QDataStream &operator>>(quint64 &i); |
152 | |
153 | QDataStream &operator>>(bool &i); |
154 | QDataStream &operator>>(float &f); |
155 | QDataStream &operator>>(double &f); |
156 | QDataStream &operator>>(char *&str); |
157 | |
158 | QDataStream &operator<<(qint8 i); |
159 | QDataStream &operator<<(quint8 i); |
160 | QDataStream &operator<<(qint16 i); |
161 | QDataStream &operator<<(quint16 i); |
162 | QDataStream &operator<<(qint32 i); |
163 | QDataStream &operator<<(quint32 i); |
164 | QDataStream &operator<<(qint64 i); |
165 | QDataStream &operator<<(quint64 i); |
166 | QDataStream &operator<<(bool i); |
167 | QDataStream &operator<<(float f); |
168 | QDataStream &operator<<(double f); |
169 | QDataStream &operator<<(const char *str); |
170 | |
171 | QDataStream &readBytes(char *&, uint &len); |
172 | int readRawData(char *, int len); |
173 | |
174 | QDataStream &writeBytes(const char *, uint len); |
175 | int writeRawData(const char *, int len); |
176 | |
177 | int skipRawData(int len); |
178 | |
179 | #ifdef QT3_SUPPORT |
180 | inline QT3_SUPPORT QDataStream &readRawBytes(char *str, uint len) |
181 | { readRawData(str, static_cast<int>(len)); return *this; } |
182 | inline QT3_SUPPORT QDataStream &writeRawBytes(const char *str, uint len) |
183 | { writeRawData(str, static_cast<int>(len)); return *this; } |
184 | inline QT3_SUPPORT bool isPrintableData() const { return false; } |
185 | inline QT3_SUPPORT void setPrintableData(bool) {} |
186 | #endif |
187 | |
188 | private: |
189 | Q_DISABLE_COPY(QDataStream) |
190 | |
191 | QScopedPointer<QDataStreamPrivate> d; |
192 | |
193 | QIODevice *dev; |
194 | bool owndev; |
195 | bool noswap; |
196 | ByteOrder byteorder; |
197 | int ver; |
198 | Status q_status; |
199 | }; |
200 | |
201 | |
202 | /***************************************************************************** |
203 | QDataStream inline functions |
204 | *****************************************************************************/ |
205 | |
206 | inline QIODevice *QDataStream::device() const |
207 | { return dev; } |
208 | |
209 | inline QDataStream::ByteOrder QDataStream::byteOrder() const |
210 | { return byteorder; } |
211 | |
212 | inline int QDataStream::version() const |
213 | { return ver; } |
214 | |
215 | inline void QDataStream::setVersion(int v) |
216 | { ver = v; } |
217 | |
218 | inline QDataStream &QDataStream::operator>>(quint8 &i) |
219 | { return *this >> reinterpret_cast<qint8&>(i); } |
220 | |
221 | inline QDataStream &QDataStream::operator>>(quint16 &i) |
222 | { return *this >> reinterpret_cast<qint16&>(i); } |
223 | |
224 | inline QDataStream &QDataStream::operator>>(quint32 &i) |
225 | { return *this >> reinterpret_cast<qint32&>(i); } |
226 | |
227 | inline QDataStream &QDataStream::operator>>(quint64 &i) |
228 | { return *this >> reinterpret_cast<qint64&>(i); } |
229 | |
230 | inline QDataStream &QDataStream::operator<<(quint8 i) |
231 | { return *this << qint8(i); } |
232 | |
233 | inline QDataStream &QDataStream::operator<<(quint16 i) |
234 | { return *this << qint16(i); } |
235 | |
236 | inline QDataStream &QDataStream::operator<<(quint32 i) |
237 | { return *this << qint32(i); } |
238 | |
239 | inline QDataStream &QDataStream::operator<<(quint64 i) |
240 | { return *this << qint64(i); } |
241 | |
242 | template <typename T> |
243 | QDataStream& operator>>(QDataStream& s, QList<T>& l) |
244 | { |
245 | l.clear(); |
246 | quint32 c; |
247 | s >> c; |
248 | l.reserve(c); |
249 | for(quint32 i = 0; i < c; ++i) |
250 | { |
251 | T t; |
252 | s >> t; |
253 | l.append(t); |
254 | if (s.atEnd()) |
255 | break; |
256 | } |
257 | return s; |
258 | } |
259 | |
260 | template <typename T> |
261 | QDataStream& operator<<(QDataStream& s, const QList<T>& l) |
262 | { |
263 | s << quint32(l.size()); |
264 | for (int i = 0; i < l.size(); ++i) |
265 | s << l.at(i); |
266 | return s; |
267 | } |
268 | |
269 | template <typename T> |
270 | QDataStream& operator>>(QDataStream& s, QLinkedList<T>& l) |
271 | { |
272 | l.clear(); |
273 | quint32 c; |
274 | s >> c; |
275 | for(quint32 i = 0; i < c; ++i) |
276 | { |
277 | T t; |
278 | s >> t; |
279 | l.append(t); |
280 | if (s.atEnd()) |
281 | break; |
282 | } |
283 | return s; |
284 | } |
285 | |
286 | template <typename T> |
287 | QDataStream& operator<<(QDataStream& s, const QLinkedList<T>& l) |
288 | { |
289 | s << quint32(l.size()); |
290 | typename QLinkedList<T>::ConstIterator it = l.constBegin(); |
291 | for(; it != l.constEnd(); ++it) |
292 | s << *it; |
293 | return s; |
294 | } |
295 | |
296 | template<typename T> |
297 | QDataStream& operator>>(QDataStream& s, QVector<T>& v) |
298 | { |
299 | v.clear(); |
300 | quint32 c; |
301 | s >> c; |
302 | v.resize(c); |
303 | for(quint32 i = 0; i < c; ++i) { |
304 | T t; |
305 | s >> t; |
306 | v[i] = t; |
307 | } |
308 | return s; |
309 | } |
310 | |
311 | template<typename T> |
312 | QDataStream& operator<<(QDataStream& s, const QVector<T>& v) |
313 | { |
314 | s << quint32(v.size()); |
315 | for (typename QVector<T>::const_iterator it = v.begin(); it != v.end(); ++it) |
316 | s << *it; |
317 | return s; |
318 | } |
319 | |
320 | template <typename T> |
321 | QDataStream &operator>>(QDataStream &in, QSet<T> &set) |
322 | { |
323 | set.clear(); |
324 | quint32 c; |
325 | in >> c; |
326 | for (quint32 i = 0; i < c; ++i) { |
327 | T t; |
328 | in >> t; |
329 | set << t; |
330 | if (in.atEnd()) |
331 | break; |
332 | } |
333 | return in; |
334 | } |
335 | |
336 | template <typename T> |
337 | QDataStream& operator<<(QDataStream &out, const QSet<T> &set) |
338 | { |
339 | out << quint32(set.size()); |
340 | typename QSet<T>::const_iterator i = set.constBegin(); |
341 | while (i != set.constEnd()) { |
342 | out << *i; |
343 | ++i; |
344 | } |
345 | return out; |
346 | } |
347 | |
348 | template <class Key, class T> |
349 | Q_OUTOFLINE_TEMPLATE QDataStream &operator>>(QDataStream &in, QHash<Key, T> &hash) |
350 | { |
351 | QDataStream::Status oldStatus = in.status(); |
352 | in.resetStatus(); |
353 | hash.clear(); |
354 | |
355 | quint32 n; |
356 | in >> n; |
357 | |
358 | for (quint32 i = 0; i < n; ++i) { |
359 | if (in.status() != QDataStream::Ok) |
360 | break; |
361 | |
362 | Key k; |
363 | T t; |
364 | in >> k >> t; |
365 | hash.insertMulti(k, t); |
366 | } |
367 | |
368 | if (in.status() != QDataStream::Ok) |
369 | hash.clear(); |
370 | if (oldStatus != QDataStream::Ok) |
371 | in.setStatus(oldStatus); |
372 | return in; |
373 | } |
374 | |
375 | template <class Key, class T> |
376 | Q_OUTOFLINE_TEMPLATE QDataStream &operator<<(QDataStream &out, const QHash<Key, T>& hash) |
377 | { |
378 | out << quint32(hash.size()); |
379 | typename QHash<Key, T>::ConstIterator it = hash.end(); |
380 | typename QHash<Key, T>::ConstIterator begin = hash.begin(); |
381 | while (it != begin) { |
382 | --it; |
383 | out << it.key() << it.value(); |
384 | } |
385 | return out; |
386 | } |
387 | #ifdef qdoc |
388 | template <class Key, class T> |
389 | Q_OUTOFLINE_TEMPLATE QDataStream &operator>>(QDataStream &in, QMap<Key, T> &map) |
390 | #else |
391 | template <class aKey, class aT> |
392 | Q_OUTOFLINE_TEMPLATE QDataStream &operator>>(QDataStream &in, QMap<aKey, aT> &map) |
393 | #endif |
394 | { |
395 | QDataStream::Status oldStatus = in.status(); |
396 | in.resetStatus(); |
397 | map.clear(); |
398 | |
399 | quint32 n; |
400 | in >> n; |
401 | |
402 | map.detach(); |
403 | map.setInsertInOrder(true); |
404 | for (quint32 i = 0; i < n; ++i) { |
405 | if (in.status() != QDataStream::Ok) |
406 | break; |
407 | |
408 | aKey key; |
409 | aT value; |
410 | in >> key >> value; |
411 | map.insertMulti(key, value); |
412 | } |
413 | map.setInsertInOrder(false); |
414 | if (in.status() != QDataStream::Ok) |
415 | map.clear(); |
416 | if (oldStatus != QDataStream::Ok) |
417 | in.setStatus(oldStatus); |
418 | return in; |
419 | } |
420 | |
421 | template <class Key, class T> |
422 | Q_OUTOFLINE_TEMPLATE QDataStream &operator<<(QDataStream &out, const QMap<Key, T> &map) |
423 | { |
424 | out << quint32(map.size()); |
425 | typename QMap<Key, T>::ConstIterator it = map.end(); |
426 | typename QMap<Key, T>::ConstIterator begin = map.begin(); |
427 | while (it != begin) { |
428 | --it; |
429 | out << it.key() << it.value(); |
430 | } |
431 | return out; |
432 | } |
433 | |
434 | #endif // QT_NO_DATASTREAM |
435 | |
436 | QT_END_NAMESPACE |
437 | |
438 | QT_END_HEADER |
439 | |
440 | #endif // QDATASTREAM_H |
441 | |