~ubuntu-branches/ubuntu/wily/qtbase-opensource-src/wily

« back to all changes in this revision

Viewing changes to src/corelib/io/qiodevice_p.h

  • Committer: Package Import Robot
  • Author(s): Timo Jyrinki
  • Date: 2013-02-05 12:46:17 UTC
  • Revision ID: package-import@ubuntu.com-20130205124617-c8jouts182j002fx
Tags: upstream-5.0.1+dfsg
ImportĀ upstreamĀ versionĀ 5.0.1+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
 
4
** Contact: http://www.qt-project.org/legal
 
5
**
 
6
** This file is part of the QtCore module of the Qt Toolkit.
 
7
**
 
8
** $QT_BEGIN_LICENSE:LGPL$
 
9
** Commercial License Usage
 
10
** Licensees holding valid commercial Qt licenses may use this file in
 
11
** accordance with the commercial license agreement provided with the
 
12
** Software or, alternatively, in accordance with the terms contained in
 
13
** a written agreement between you and Digia.  For licensing terms and
 
14
** conditions see http://qt.digia.com/licensing.  For further information
 
15
** use the contact form at http://qt.digia.com/contact-us.
 
16
**
 
17
** GNU Lesser General Public License Usage
 
18
** Alternatively, this file may be used under the terms of the GNU Lesser
 
19
** General Public License version 2.1 as published by the Free Software
 
20
** Foundation and appearing in the file LICENSE.LGPL included in the
 
21
** packaging of this file.  Please review the following information to
 
22
** ensure the GNU Lesser General Public License version 2.1 requirements
 
23
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 
24
**
 
25
** In addition, as a special exception, Digia gives you certain additional
 
26
** rights.  These rights are described in the Digia Qt LGPL Exception
 
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
 
28
**
 
29
** GNU General Public License Usage
 
30
** Alternatively, this file may be used under the terms of the GNU
 
31
** General Public License version 3.0 as published by the Free Software
 
32
** Foundation and appearing in the file LICENSE.GPL included in the
 
33
** packaging of this file.  Please review the following information to
 
34
** ensure the GNU General Public License version 3.0 requirements will be
 
35
** met: http://www.gnu.org/copyleft/gpl.html.
 
36
**
 
37
**
 
38
** $QT_END_LICENSE$
 
39
**
 
40
****************************************************************************/
 
41
 
 
42
#ifndef QIODEVICE_P_H
 
43
#define QIODEVICE_P_H
 
44
 
 
45
//
 
46
//  W A R N I N G
 
47
//  -------------
 
48
//
 
49
// This file is not part of the Qt API.  It exists for the convenience
 
50
// of QIODevice. This header file may change from version to
 
51
// version without notice, or even be removed.
 
52
//
 
53
// We mean it.
 
54
//
 
55
 
 
56
#include "QtCore/qiodevice.h"
 
57
#include "QtCore/qbytearray.h"
 
58
#include "QtCore/qobjectdefs.h"
 
59
#include "QtCore/qstring.h"
 
60
#include "private/qringbuffer_p.h"
 
61
#ifndef QT_NO_QOBJECT
 
62
#include "private/qobject_p.h"
 
63
#endif
 
64
 
 
65
QT_BEGIN_NAMESPACE
 
66
 
 
67
#ifndef QIODEVICE_BUFFERSIZE
 
68
#define QIODEVICE_BUFFERSIZE Q_INT64_C(16384)
 
69
#endif
 
70
 
 
71
// This is QIODevice's read buffer, optimized for read(), isEmpty() and getChar()
 
72
class QIODevicePrivateLinearBuffer
 
73
{
 
74
public:
 
75
    QIODevicePrivateLinearBuffer(int) : len(0), first(0), buf(0), capacity(0) {
 
76
    }
 
77
    ~QIODevicePrivateLinearBuffer() {
 
78
        delete [] buf;
 
79
    }
 
80
    void clear() {
 
81
        len = 0;
 
82
        delete [] buf;
 
83
        buf = 0;
 
84
        first = buf;
 
85
        capacity = 0;
 
86
    }
 
87
    int size() const {
 
88
        return len;
 
89
    }
 
90
    bool isEmpty() const {
 
91
        return len == 0;
 
92
    }
 
93
    void skip(int n) {
 
94
        if (n >= len) {
 
95
            clear();
 
96
        } else {
 
97
            len -= n;
 
98
            first += n;
 
99
        }
 
100
    }
 
101
    int getChar() {
 
102
        if (len == 0)
 
103
            return -1;
 
104
        int ch = uchar(*first);
 
105
        len--;
 
106
        first++;
 
107
        return ch;
 
108
    }
 
109
    int read(char* target, int size) {
 
110
        int r = qMin(size, len);
 
111
        memcpy(target, first, r);
 
112
        len -= r;
 
113
        first += r;
 
114
        return r;
 
115
    }
 
116
    int peek(char* target, int size) {
 
117
        int r = qMin(size, len);
 
118
        memcpy(target, first, r);
 
119
        return r;
 
120
    }
 
121
    char* reserve(int size) {
 
122
        makeSpace(size + len, freeSpaceAtEnd);
 
123
        char* writePtr = first + len;
 
124
        len += size;
 
125
        return writePtr;
 
126
    }
 
127
    void chop(int size) {
 
128
        if (size >= len) {
 
129
            clear();
 
130
        } else {
 
131
            len -= size;
 
132
        }
 
133
    }
 
134
    QByteArray readAll() {
 
135
        QByteArray retVal(first, len);
 
136
        clear();
 
137
        return retVal;
 
138
    }
 
139
    int readLine(char* target, int size) {
 
140
        int r = qMin(size, len);
 
141
        char* eol = static_cast<char*>(memchr(first, '\n', r));
 
142
        if (eol)
 
143
            r = 1+(eol-first);
 
144
        memcpy(target, first, r);
 
145
        len -= r;
 
146
        first += r;
 
147
        return int(r);
 
148
        }
 
149
    bool canReadLine() const {
 
150
        return memchr(first, '\n', len);
 
151
    }
 
152
    void ungetChar(char c) {
 
153
        if (first == buf) {
 
154
            // underflow, the existing valid data needs to move to the end of the (potentially bigger) buffer
 
155
            makeSpace(len+1, freeSpaceAtStart);
 
156
        }
 
157
        first--;
 
158
        len++;
 
159
        *first = c;
 
160
    }
 
161
    void ungetBlock(const char* block, int size) {
 
162
        if ((first - buf) < size) {
 
163
            // underflow, the existing valid data needs to move to the end of the (potentially bigger) buffer
 
164
            makeSpace(len + size, freeSpaceAtStart);
 
165
        }
 
166
        first -= size;
 
167
        len += size;
 
168
        memcpy(first, block, size);
 
169
    }
 
170
 
 
171
private:
 
172
    enum FreeSpacePos {freeSpaceAtStart, freeSpaceAtEnd};
 
173
    void makeSpace(size_t required, FreeSpacePos where) {
 
174
        size_t newCapacity = qMax(capacity, size_t(QIODEVICE_BUFFERSIZE));
 
175
        while (newCapacity < required)
 
176
            newCapacity *= 2;
 
177
        const size_t moveOffset = (where == freeSpaceAtEnd) ? 0 : newCapacity - size_t(len);
 
178
        if (newCapacity > capacity) {
 
179
            // allocate more space
 
180
            char* newBuf = new char[newCapacity];
 
181
            memmove(newBuf + moveOffset, first, len);
 
182
            delete [] buf;
 
183
            buf = newBuf;
 
184
            capacity = newCapacity;
 
185
        } else {
 
186
            // shift any existing data to make space
 
187
            memmove(buf + moveOffset, first, len);
 
188
        }
 
189
        first = buf + moveOffset;
 
190
    }
 
191
 
 
192
private:
 
193
    // length of the unread data
 
194
    int len;
 
195
    // start of the unread data
 
196
    char* first;
 
197
    // the allocated buffer
 
198
    char* buf;
 
199
    // allocated buffer size
 
200
    size_t capacity;
 
201
};
 
202
 
 
203
class Q_CORE_EXPORT QIODevicePrivate
 
204
#ifndef QT_NO_QOBJECT
 
205
    : public QObjectPrivate
 
206
#endif
 
207
{
 
208
    Q_DECLARE_PUBLIC(QIODevice)
 
209
 
 
210
public:
 
211
    QIODevicePrivate();
 
212
    virtual ~QIODevicePrivate();
 
213
 
 
214
    QIODevice::OpenMode openMode;
 
215
    QString errorString;
 
216
 
 
217
    QIODevicePrivateLinearBuffer buffer;
 
218
    qint64 pos;
 
219
    qint64 devicePos;
 
220
    // these three are for fast position updates during read, avoiding isSequential test
 
221
    qint64 seqDumpPos;
 
222
    qint64 *pPos;
 
223
    qint64 *pDevicePos;
 
224
    bool baseReadLineDataCalled;
 
225
    bool firstRead;
 
226
 
 
227
    virtual bool putCharHelper(char c);
 
228
 
 
229
    enum AccessMode {
 
230
        Unset,
 
231
        Sequential,
 
232
        RandomAccess
 
233
    };
 
234
    mutable AccessMode accessMode;
 
235
    inline bool isSequential() const
 
236
    {
 
237
        if (accessMode == Unset)
 
238
            accessMode = q_func()->isSequential() ? Sequential : RandomAccess;
 
239
        return accessMode == Sequential;
 
240
    }
 
241
 
 
242
    virtual qint64 peek(char *data, qint64 maxSize);
 
243
    virtual QByteArray peek(qint64 maxSize);
 
244
 
 
245
#ifdef QT_NO_QOBJECT
 
246
    QIODevice *q_ptr;
 
247
#endif
 
248
};
 
249
 
 
250
QT_END_NAMESPACE
 
251
 
 
252
#endif // QIODEVICE_P_H