1
/****************************************************************************
3
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4
** Contact: http://www.qt-project.org/legal
6
** This file is part of the QtCore module of the Qt Toolkit.
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.
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.
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.
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.
40
****************************************************************************/
42
#include "qplatformdefs.h"
43
#include "qfiledevice.h"
44
#include "qfiledevice_p.h"
45
#include "qfsfileengine_p.h"
48
#define tr(X) QString::fromLatin1(X)
53
static const int QFILE_WRITEBUFFER_SIZE = 16384;
55
QFileDevicePrivate::QFileDevicePrivate()
56
: fileEngine(0), lastWasWrite(false),
57
writeBuffer(QFILE_WRITEBUFFER_SIZE), error(QFile::NoError),
62
QFileDevicePrivate::~QFileDevicePrivate()
68
QAbstractFileEngine * QFileDevicePrivate::engine() const
71
fileEngine = new QFSFileEngine;
75
void QFileDevicePrivate::setError(QFileDevice::FileError err)
81
void QFileDevicePrivate::setError(QFileDevice::FileError err, const QString &errStr)
87
void QFileDevicePrivate::setError(QFileDevice::FileError err, int errNum)
90
errorString = qt_error_string(errNum);
94
\enum QFileDevice::FileError
96
This enum describes the errors that may be returned by the error()
99
\value NoError No error occurred.
100
\value ReadError An error occurred when reading from the file.
101
\value WriteError An error occurred when writing to the file.
102
\value FatalError A fatal error occurred.
104
\value OpenError The file could not be opened.
105
\value AbortError The operation was aborted.
106
\value TimeOutError A timeout occurred.
107
\value UnspecifiedError An unspecified error occurred.
108
\value RemoveError The file could not be removed.
109
\value RenameError The file could not be renamed.
110
\value PositionError The position in the file could not be changed.
111
\value ResizeError The file could not be resized.
112
\value PermissionsError The file could not be accessed.
113
\value CopyError The file could not be copied.
117
\enum QFileDevice::Permission
119
This enum is used by the permission() function to report the
120
permissions and ownership of a file. The values may be OR-ed
121
together to test multiple permissions and ownership values.
123
\value ReadOwner The file is readable by the owner of the file.
124
\value WriteOwner The file is writable by the owner of the file.
125
\value ExeOwner The file is executable by the owner of the file.
126
\value ReadUser The file is readable by the user.
127
\value WriteUser The file is writable by the user.
128
\value ExeUser The file is executable by the user.
129
\value ReadGroup The file is readable by the group.
130
\value WriteGroup The file is writable by the group.
131
\value ExeGroup The file is executable by the group.
132
\value ReadOther The file is readable by anyone.
133
\value WriteOther The file is writable by anyone.
134
\value ExeOther The file is executable by anyone.
136
\warning Because of differences in the platforms supported by Qt,
137
the semantics of ReadUser, WriteUser and ExeUser are
138
platform-dependent: On Unix, the rights of the owner of the file
139
are returned and on Windows the rights of the current user are
140
returned. This behavior might change in a future Qt version.
142
Note that Qt does not by default check for permissions on NTFS
143
file systems, as this may decrease the performance of file
144
handling considerably. It is possible to force permission checking
145
on NTFS by including the following code in your source:
149
Permission checking is then turned on and off by incrementing and
150
decrementing \c qt_ntfs_permission_lookup by 1.
155
//************* QFileDevice
162
\brief The QFileDevice class provides an interface for reading from and writing to open files.
168
QFileDevice is the base class for I/O devices that can read and write text and binary files
169
and \l{The Qt Resource System}{resources}. QFile offers the main functionality,
170
QFileDevice serves as a base class for sharing functionality with other file devices such
171
as QTemporaryFile, by providing all the operations that can be done on files that have
172
been opened by QFile or QTemporaryFile.
174
\sa QFile, QTemporaryFile
178
\enum QFileDevice::FileHandleFlag
180
This enum is used when opening a file to specify additional
181
options which only apply to files and not to a generic
184
\value AutoCloseHandle The file handle passed into open() should be
185
closed by close(), the default behavior is that close just flushes
186
the file and the application is responsible for closing the file handle.
187
When opening a file by name, this flag is ignored as Qt always owns the
188
file handle and must close it.
189
\value DontCloseHandle If not explicitly closed, the underlying file
190
handle is left open when the QFile object is destroyed.
194
QFileDevice::QFileDevice()
195
: QIODevice(*new QFileDevicePrivate)
198
QFileDevice::QFileDevice(QFileDevicePrivate &dd)
206
QFileDevice::QFileDevice()
207
: QIODevice(*new QFileDevicePrivate, 0)
213
QFileDevice::QFileDevice(QObject *parent)
214
: QIODevice(*new QFileDevicePrivate, parent)
220
QFileDevice::QFileDevice(QFileDevicePrivate &dd, QObject *parent)
221
: QIODevice(dd, parent)
227
Destroys the file device, closing it if necessary.
229
QFileDevice::~QFileDevice()
235
Returns true if the file can only be manipulated sequentially;
236
otherwise returns false.
238
Most files support random-access, but some special files may not.
240
\sa QIODevice::isSequential()
242
bool QFileDevice::isSequential() const
244
Q_D(const QFileDevice);
245
return d->fileEngine && d->fileEngine->isSequential();
249
Returns the file handle of the file.
251
This is a small positive integer, suitable for use with C library
252
functions such as fdopen() and fcntl(). On systems that use file
253
descriptors for sockets (i.e. Unix systems, but not Windows) the handle
254
can be used with QSocketNotifier as well.
256
If the file is not open, or there is an error, handle() returns -1.
258
This function is not supported on Windows CE.
262
int QFileDevice::handle() const
264
Q_D(const QFileDevice);
265
if (!isOpen() || !d->fileEngine)
268
return d->fileEngine->handle();
272
Returns the name of the file.
273
The default implementation in QFileDevice returns QString().
275
QString QFileDevice::fileName() const
280
static inline qint64 _qfile_writeData(QAbstractFileEngine *engine, QRingBuffer *buffer)
282
qint64 ret = engine->write(buffer->readPointer(), buffer->nextDataBlockSize());
289
Flushes any buffered data to the file. Returns true if successful;
290
otherwise returns false.
292
bool QFileDevice::flush()
295
if (!d->fileEngine) {
296
qWarning("QFileDevice::flush: No file engine. Is IODevice open?");
300
if (!d->writeBuffer.isEmpty()) {
301
qint64 size = d->writeBuffer.size();
302
if (_qfile_writeData(d->fileEngine, &d->writeBuffer) != size) {
303
QFileDevice::FileError err = d->fileEngine->error();
304
if (err == QFileDevice::UnspecifiedError)
305
err = QFileDevice::WriteError;
306
d->setError(err, d->fileEngine->errorString());
311
if (!d->fileEngine->flush()) {
312
QFileDevice::FileError err = d->fileEngine->error();
313
if (err == QFileDevice::UnspecifiedError)
314
err = QFileDevice::WriteError;
315
d->setError(err, d->fileEngine->errorString());
322
Calls QFileDevice::flush() and closes the file. Errors from flush are ignored.
324
\sa QIODevice::close()
326
void QFileDevice::close()
331
bool flushed = flush();
334
// reset write buffer
335
d->lastWasWrite = false;
336
d->writeBuffer.clear();
338
// keep earlier error from flush
339
if (d->fileEngine->close() && flushed)
342
d->setError(d->fileEngine->error(), d->fileEngine->errorString());
348
qint64 QFileDevice::pos() const
350
return QIODevice::pos();
354
Returns true if the end of the file has been reached; otherwise returns
357
For regular empty files on Unix (e.g. those in \c /proc), this function
358
returns true, since the file system reports that the size of such a file is
359
0. Therefore, you should not depend on atEnd() when reading data from such a
360
file, but rather call read() until no more data can be read.
362
bool QFileDevice::atEnd() const
364
Q_D(const QFileDevice);
366
// If there's buffered data left, we're not at the end.
367
if (!d->buffer.isEmpty())
373
if (!d->ensureFlushed())
376
// If the file engine knows best, say what it says.
377
if (d->fileEngine->supportsExtension(QAbstractFileEngine::AtEndExtension)) {
378
// Check if the file engine supports AtEndExtension, and if it does,
379
// check if the file engine claims to be at the end.
380
return d->fileEngine->atEnd();
383
// if it looks like we are at the end, or if size is not cached,
384
// fall through to bytesAvailable() to make sure.
385
if (pos() < d->cachedSize)
388
// Fall back to checking how much is available (will stat files).
389
return bytesAvailable() == 0;
393
\fn bool QFileDevice::seek(qint64 pos)
395
For random-access devices, this function sets the current position
396
to \a pos, returning true on success, or false if an error occurred.
397
For sequential devices, the default behavior is to do nothing and
400
Seeking beyond the end of a file:
401
If the position is beyond the end of a file, then seek() shall not
402
immediately extend the file. If a write is performed at this position,
403
then the file shall be extended. The content of the file between the
404
previous end of file and the newly written data is UNDEFINED and
405
varies between platforms and file systems.
407
bool QFileDevice::seek(qint64 off)
411
qWarning("QFileDevice::seek: IODevice is not open");
415
if (!d->ensureFlushed())
418
if (!d->fileEngine->seek(off) || !QIODevice::seek(off)) {
419
QFileDevice::FileError err = d->fileEngine->error();
420
if (err == QFileDevice::UnspecifiedError)
421
err = QFileDevice::PositionError;
422
d->setError(err, d->fileEngine->errorString());
432
qint64 QFileDevice::readLineData(char *data, qint64 maxlen)
435
if (!d->ensureFlushed())
439
if (d->fileEngine->supportsExtension(QAbstractFileEngine::FastReadLineExtension)) {
440
read = d->fileEngine->readLine(data, maxlen);
442
// Fall back to QIODevice's readLine implementation if the engine
443
// cannot do it faster.
444
read = QIODevice::readLineData(data, maxlen);
448
// failed to read all requested, may be at the end of file, stop caching size so that it's rechecked
458
qint64 QFileDevice::readData(char *data, qint64 len)
464
if (!d->ensureFlushed())
467
const qint64 read = d->fileEngine->read(data, len);
469
QFileDevice::FileError err = d->fileEngine->error();
470
if (err == QFileDevice::UnspecifiedError)
471
err = QFileDevice::ReadError;
472
d->setError(err, d->fileEngine->errorString());
476
// failed to read all requested, may be at the end of file, stop caching size so that it's rechecked
486
bool QFileDevicePrivate::putCharHelper(char c)
489
return QIODevicePrivate::putCharHelper(c);
492
// Cutoff for code that doesn't only touch the buffer.
493
int writeBufferSize = writeBuffer.size();
494
if ((openMode & QIODevice::Unbuffered) || writeBufferSize + 1 >= QFILE_WRITEBUFFER_SIZE
496
|| ((openMode & QIODevice::Text) && c == '\n' && writeBufferSize + 2 >= QFILE_WRITEBUFFER_SIZE)
499
return QIODevicePrivate::putCharHelper(c);
502
if (!(openMode & QIODevice::WriteOnly)) {
503
if (openMode == QIODevice::NotOpen)
504
qWarning("QIODevice::putChar: Closed device");
506
qWarning("QIODevice::putChar: ReadOnly device");
510
// Make sure the device is positioned correctly.
511
const bool sequential = isSequential();
512
if (pos != devicePos && !sequential && !q_func()->seek(pos))
519
if ((openMode & QIODevice::Text) && c == '\n') {
521
*writeBuffer.reserve(1) = '\r';
526
*writeBuffer.reserve(1) = c;
531
if (!buffer.isEmpty())
542
qint64 QFileDevice::writeData(const char *data, qint64 len)
546
d->lastWasWrite = true;
547
bool buffered = !(d->openMode & Unbuffered);
549
// Flush buffered data if this read will overflow.
550
if (buffered && (d->writeBuffer.size() + len) > QFILE_WRITEBUFFER_SIZE) {
555
// Write directly to the engine if the block size is larger than
556
// the write buffer size.
557
if (!buffered || len > QFILE_WRITEBUFFER_SIZE) {
558
const qint64 ret = d->fileEngine->write(data, len);
560
QFileDevice::FileError err = d->fileEngine->error();
561
if (err == QFileDevice::UnspecifiedError)
562
err = QFileDevice::WriteError;
563
d->setError(err, d->fileEngine->errorString());
568
// Write to the buffer.
569
char *writePointer = d->writeBuffer.reserve(len);
571
*writePointer = *data;
573
::memcpy(writePointer, data, len);
578
Returns the file error status.
580
The I/O device status returns an error code. For example, if open()
581
returns false, or a read/write operation returns -1, this function can
582
be called to find out the reason why the operation failed.
586
QFileDevice::FileError QFileDevice::error() const
588
Q_D(const QFileDevice);
593
Sets the file's error to QFileDevice::NoError.
597
void QFileDevice::unsetError()
600
d->setError(QFileDevice::NoError);
604
Returns the size of the file.
606
For regular empty files on Unix (e.g. those in \c /proc), this function
607
returns 0; the contents of such a file are generated on demand in response
608
to you calling read().
610
qint64 QFileDevice::size() const
612
Q_D(const QFileDevice);
613
if (!d->ensureFlushed())
615
d->cachedSize = d->engine()->size();
616
return d->cachedSize;
620
Sets the file size (in bytes) \a sz. Returns true if the file if the
621
resize succeeds; false otherwise. If \a sz is larger than the file
622
currently is the new bytes will be set to 0, if \a sz is smaller the
623
file is simply truncated.
627
bool QFileDevice::resize(qint64 sz)
630
if (!d->ensureFlushed())
633
if (isOpen() && d->fileEngine->pos() > sz)
635
if (d->fileEngine->setSize(sz)) {
641
d->setError(QFile::ResizeError, d->fileEngine->errorString());
646
Returns the complete OR-ed together combination of
647
QFile::Permission for the file.
651
QFile::Permissions QFileDevice::permissions() const
653
Q_D(const QFileDevice);
654
QAbstractFileEngine::FileFlags perms = d->engine()->fileFlags(QAbstractFileEngine::PermsMask) & QAbstractFileEngine::PermsMask;
655
return QFile::Permissions((int)perms); //ewww
659
Sets the permissions for the file to the \a permissions specified.
660
Returns true if successful, or false if the permissions cannot be
665
bool QFileDevice::setPermissions(Permissions permissions)
668
if (d->engine()->setPermissions(permissions)) {
672
d->setError(QFile::PermissionsError, d->fileEngine->errorString());
677
\enum QFileDevice::MemoryMapFlags
680
This enum describes special options that may be used by the map()
683
\value NoOptions No options.
687
Maps \a size bytes of the file into memory starting at \a offset. A file
688
should be open for a map to succeed but the file does not need to stay
689
open after the memory has been mapped. When the QFile is destroyed
690
or a new file is opened with this object, any maps that have not been
691
unmapped will automatically be unmapped.
693
Any mapping options can be passed through \a flags.
695
Returns a pointer to the memory or 0 if there is an error.
697
\note On Windows CE 5.0 the file will be closed before mapping occurs.
701
uchar *QFileDevice::map(qint64 offset, qint64 size, MemoryMapFlags flags)
705
&& d->fileEngine->supportsExtension(QAbstractFileEngine::MapExtension)) {
707
uchar *address = d->fileEngine->map(offset, size, flags);
709
d->setError(d->fileEngine->error(), d->fileEngine->errorString());
716
Unmaps the memory \a address.
718
Returns true if the unmap succeeds; false otherwise.
722
bool QFileDevice::unmap(uchar *address)
726
&& d->fileEngine->supportsExtension(QAbstractFileEngine::UnMapExtension)) {
728
bool success = d->fileEngine->unmap(address);
730
d->setError(d->fileEngine->error(), d->fileEngine->errorString());
733
d->setError(PermissionsError, tr("No file engine available or engine does not support UnMapExtension"));