1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Copyright (C) 2016 Intel Corporation.
5 ** Contact: https://www.qt.io/licensing/
6 **
7 ** This file is part of the QtCore module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** Commercial License Usage
11 ** Licensees holding valid commercial Qt licenses may use this file in
12 ** accordance with the commercial license agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and The Qt Company. For licensing terms
15 ** and conditions see https://www.qt.io/terms-conditions. For further
16 ** information use the contact form at https://www.qt.io/contact-us.
17 **
18 ** GNU Lesser General Public License Usage
19 ** Alternatively, this file may be used under the terms of the GNU Lesser
20 ** General Public License version 3 as published by the Free Software
21 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
22 ** packaging of this file. Please review the following information to
23 ** ensure the GNU Lesser General Public License version 3 requirements
24 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25 **
26 ** GNU General Public License Usage
27 ** Alternatively, this file may be used under the terms of the GNU
28 ** General Public License version 2.0 or (at your option) the GNU General
29 ** Public license version 3 or any later version approved by the KDE Free
30 ** Qt Foundation. The licenses are as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32 ** included in the packaging of this file. Please review the following
33 ** information to ensure the GNU General Public License requirements will
34 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35 ** https://www.gnu.org/licenses/gpl-3.0.html.
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40 
41 #ifndef QTEXTSTREAM_P_H
42 #define QTEXTSTREAM_P_H
43 
44 //
45 //  W A R N I N G
46 //  -------------
47 //
48 // This file is not part of the Qt API.  It exists purely as an
49 // implementation detail.  This header file may change from version to
50 // version without notice, or even be removed.
51 //
52 // We mean it.
53 //
54 
55 #include <QtCore/private/qglobal_p.h>
56 #include "qtextstream.h"
57 #if QT_CONFIG(textcodec)
58 #include "qtextcodec.h"
59 #endif
60 
61 QT_BEGIN_NAMESPACE
62 
63 #ifndef QT_NO_QOBJECT
64 class QDeviceClosedNotifier : public QObject
65 {
66     Q_OBJECT
67 public:
QDeviceClosedNotifier()68     inline QDeviceClosedNotifier()
69     { }
70 
setupDevice(QTextStream * stream,QIODevice * device)71     inline void setupDevice(QTextStream *stream, QIODevice *device)
72     {
73         disconnect();
74         if (device)
75             connect(device, SIGNAL(aboutToClose()), this, SLOT(flushStream()));
76         this->stream = stream;
77     }
78 
79 public Q_SLOTS:
flushStream()80     inline void flushStream() { stream->flush(); }
81 
82 private:
83     QTextStream *stream;
84 };
85 #endif
86 
87 class QTextStreamPrivate
88 {
Q_DECLARE_PUBLIC(QTextStream)89     Q_DECLARE_PUBLIC(QTextStream)
90 public:
91     // streaming parameters
92     class Params
93     {
94     public:
95         void reset();
96 
97         int realNumberPrecision;
98         int integerBase;
99         int fieldWidth;
100         QChar padChar;
101         QTextStream::FieldAlignment fieldAlignment;
102         QTextStream::RealNumberNotation realNumberNotation;
103         QTextStream::NumberFlags numberFlags;
104     };
105 
106     QTextStreamPrivate(QTextStream *q_ptr);
107     ~QTextStreamPrivate();
108     void reset();
109 
110     // device
111     QIODevice *device;
112 #ifndef QT_NO_QOBJECT
113     QDeviceClosedNotifier deviceClosedNotifier;
114 #endif
115 
116     // string
117     QString *string;
118     int stringOffset;
119     QIODevice::OpenMode stringOpenMode;
120 
121 #if QT_CONFIG(textcodec)
122     // codec
123     QTextCodec *codec;
124     QTextCodec::ConverterState readConverterState;
125     QTextCodec::ConverterState writeConverterState;
126     QTextCodec::ConverterState *readConverterSavedState;
127 #endif
128 
129     QString writeBuffer;
130     QString readBuffer;
131     int readBufferOffset;
132     int readConverterSavedStateOffset; //the offset between readBufferStartDevicePos and that start of the buffer
133     qint64 readBufferStartDevicePos;
134 
135     Params params;
136 
137     // status
138     QTextStream::Status status;
139     QLocale locale;
140     QTextStream *q_ptr;
141 
142     int lastTokenSize;
143     bool deleteDevice;
144 #if QT_CONFIG(textcodec)
145     bool autoDetectUnicode;
146 #endif
147 
148     // i/o
149     enum TokenDelimiter {
150         Space,
151         NotSpace,
152         EndOfLine
153     };
154 
155     QString read(int maxlen);
156     bool scan(const QChar **ptr, int *tokenLength,
157               int maxlen, TokenDelimiter delimiter);
158     inline const QChar *readPtr() const;
159     inline void consumeLastToken();
160     inline void consume(int nchars);
161     void saveConverterState(qint64 newPos);
162     void restoreToSavedConverterState();
163 
164     // Return value type for getNumber()
165     enum NumberParsingStatus {
166         npsOk,
167         npsMissingDigit,
168         npsInvalidPrefix
169     };
170 
171     inline bool getChar(QChar *ch);
172     inline void ungetChar(QChar ch);
173     NumberParsingStatus getNumber(qulonglong *l);
174     bool getReal(double *f);
175 
write(const QString & data)176     inline void write(const QString &data) { write(data.begin(), data.length()); }
177     inline void write(QChar ch);
178     void write(const QChar *data, int len);
179     void write(QLatin1String data);
180     void writePadding(int len);
181     inline void putString(const QString &ch, bool number = false) { putString(ch.constData(), ch.length(), number); }
182     void putString(const QChar *data, int len, bool number = false);
183     void putString(QLatin1String data, bool number = false);
184     inline void putChar(QChar ch);
185     void putNumber(qulonglong number, bool negative);
186 
187     struct PaddingResult {
188         int left, right;
189     };
190     PaddingResult padding(int len) const;
191 
192     // buffers
193     bool fillReadBuffer(qint64 maxBytes = -1);
194     void resetReadBuffer();
195     void flushWriteBuffer();
196 };
197 
198 QT_END_NAMESPACE
199 
200 #endif // QTEXTSTREAM_P_H
201