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

« back to all changes in this revision

Viewing changes to src/corelib/io/qfiledevice.cpp

  • 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
#include "qplatformdefs.h"
 
43
#include "qfiledevice.h"
 
44
#include "qfiledevice_p.h"
 
45
#include "qfsfileengine_p.h"
 
46
 
 
47
#ifdef QT_NO_QOBJECT
 
48
#define tr(X) QString::fromLatin1(X)
 
49
#endif
 
50
 
 
51
QT_BEGIN_NAMESPACE
 
52
 
 
53
static const int QFILE_WRITEBUFFER_SIZE = 16384;
 
54
 
 
55
QFileDevicePrivate::QFileDevicePrivate()
 
56
    : fileEngine(0), lastWasWrite(false),
 
57
      writeBuffer(QFILE_WRITEBUFFER_SIZE), error(QFile::NoError),
 
58
      cachedSize(0)
 
59
{
 
60
}
 
61
 
 
62
QFileDevicePrivate::~QFileDevicePrivate()
 
63
{
 
64
    delete fileEngine;
 
65
    fileEngine = 0;
 
66
}
 
67
 
 
68
QAbstractFileEngine * QFileDevicePrivate::engine() const
 
69
{
 
70
    if (!fileEngine)
 
71
        fileEngine = new QFSFileEngine;
 
72
    return fileEngine;
 
73
}
 
74
 
 
75
void QFileDevicePrivate::setError(QFileDevice::FileError err)
 
76
{
 
77
    error = err;
 
78
    errorString.clear();
 
79
}
 
80
 
 
81
void QFileDevicePrivate::setError(QFileDevice::FileError err, const QString &errStr)
 
82
{
 
83
    error = err;
 
84
    errorString = errStr;
 
85
}
 
86
 
 
87
void QFileDevicePrivate::setError(QFileDevice::FileError err, int errNum)
 
88
{
 
89
    error = err;
 
90
    errorString = qt_error_string(errNum);
 
91
}
 
92
 
 
93
/*!
 
94
    \enum QFileDevice::FileError
 
95
 
 
96
    This enum describes the errors that may be returned by the error()
 
97
    function.
 
98
 
 
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.
 
103
    \value ResourceError
 
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.
 
114
*/
 
115
 
 
116
/*!
 
117
    \enum QFileDevice::Permission
 
118
 
 
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.
 
122
 
 
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.
 
135
 
 
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.
 
141
 
 
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:
 
146
 
 
147
    \snippet ntfsp.cpp 0
 
148
 
 
149
    Permission checking is then turned on and off by incrementing and
 
150
    decrementing \c qt_ntfs_permission_lookup by 1.
 
151
 
 
152
    \snippet ntfsp.cpp 1
 
153
*/
 
154
 
 
155
//************* QFileDevice
 
156
 
 
157
/*!
 
158
    \class QFileDevice
 
159
    \inmodule QtCore
 
160
    \since 5.0
 
161
 
 
162
    \brief The QFileDevice class provides an interface for reading from and writing to open files.
 
163
 
 
164
    \ingroup io
 
165
 
 
166
    \reentrant
 
167
 
 
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.
 
173
 
 
174
    \sa QFile, QTemporaryFile
 
175
*/
 
176
 
 
177
/*!
 
178
    \enum QFileDevice::FileHandleFlag
 
179
 
 
180
    This enum is used when opening a file to specify additional
 
181
    options which only apply to files and not to a generic
 
182
    QIODevice.
 
183
 
 
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.
 
191
 */
 
192
 
 
193
#ifdef QT_NO_QOBJECT
 
194
QFileDevice::QFileDevice()
 
195
    : QIODevice(*new QFileDevicePrivate)
 
196
{
 
197
}
 
198
QFileDevice::QFileDevice(QFileDevicePrivate &dd)
 
199
    : QIODevice(dd)
 
200
{
 
201
}
 
202
#else
 
203
/*!
 
204
    \internal
 
205
*/
 
206
QFileDevice::QFileDevice()
 
207
    : QIODevice(*new QFileDevicePrivate, 0)
 
208
{
 
209
}
 
210
/*!
 
211
    \internal
 
212
*/
 
213
QFileDevice::QFileDevice(QObject *parent)
 
214
    : QIODevice(*new QFileDevicePrivate, parent)
 
215
{
 
216
}
 
217
/*!
 
218
    \internal
 
219
*/
 
220
QFileDevice::QFileDevice(QFileDevicePrivate &dd, QObject *parent)
 
221
    : QIODevice(dd, parent)
 
222
{
 
223
}
 
224
#endif
 
225
 
 
226
/*!
 
227
    Destroys the file device, closing it if necessary.
 
228
*/
 
229
QFileDevice::~QFileDevice()
 
230
{
 
231
    close();
 
232
}
 
233
 
 
234
/*!
 
235
    Returns true if the file can only be manipulated sequentially;
 
236
    otherwise returns false.
 
237
 
 
238
    Most files support random-access, but some special files may not.
 
239
 
 
240
    \sa QIODevice::isSequential()
 
241
*/
 
242
bool QFileDevice::isSequential() const
 
243
{
 
244
    Q_D(const QFileDevice);
 
245
    return d->fileEngine && d->fileEngine->isSequential();
 
246
}
 
247
 
 
248
/*!
 
249
  Returns the file handle of the file.
 
250
 
 
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.
 
255
 
 
256
  If the file is not open, or there is an error, handle() returns -1.
 
257
 
 
258
  This function is not supported on Windows CE.
 
259
 
 
260
  \sa QSocketNotifier
 
261
*/
 
262
int QFileDevice::handle() const
 
263
{
 
264
    Q_D(const QFileDevice);
 
265
    if (!isOpen() || !d->fileEngine)
 
266
        return -1;
 
267
 
 
268
    return d->fileEngine->handle();
 
269
}
 
270
 
 
271
/*!
 
272
    Returns the name of the file.
 
273
    The default implementation in QFileDevice returns QString().
 
274
*/
 
275
QString QFileDevice::fileName() const
 
276
{
 
277
    return QString();
 
278
}
 
279
 
 
280
static inline qint64 _qfile_writeData(QAbstractFileEngine *engine, QRingBuffer *buffer)
 
281
{
 
282
    qint64 ret = engine->write(buffer->readPointer(), buffer->nextDataBlockSize());
 
283
    if (ret > 0)
 
284
        buffer->free(ret);
 
285
    return ret;
 
286
}
 
287
 
 
288
/*!
 
289
    Flushes any buffered data to the file. Returns true if successful;
 
290
    otherwise returns false.
 
291
*/
 
292
bool QFileDevice::flush()
 
293
{
 
294
    Q_D(QFileDevice);
 
295
    if (!d->fileEngine) {
 
296
        qWarning("QFileDevice::flush: No file engine. Is IODevice open?");
 
297
        return false;
 
298
    }
 
299
 
 
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());
 
307
            return false;
 
308
        }
 
309
    }
 
310
 
 
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());
 
316
        return false;
 
317
    }
 
318
    return true;
 
319
}
 
320
 
 
321
/*!
 
322
  Calls QFileDevice::flush() and closes the file. Errors from flush are ignored.
 
323
 
 
324
  \sa QIODevice::close()
 
325
*/
 
326
void QFileDevice::close()
 
327
{
 
328
    Q_D(QFileDevice);
 
329
    if (!isOpen())
 
330
        return;
 
331
    bool flushed = flush();
 
332
    QIODevice::close();
 
333
 
 
334
    // reset write buffer
 
335
    d->lastWasWrite = false;
 
336
    d->writeBuffer.clear();
 
337
 
 
338
    // keep earlier error from flush
 
339
    if (d->fileEngine->close() && flushed)
 
340
        unsetError();
 
341
    else if (flushed)
 
342
        d->setError(d->fileEngine->error(), d->fileEngine->errorString());
 
343
}
 
344
 
 
345
/*!
 
346
  \reimp
 
347
*/
 
348
qint64 QFileDevice::pos() const
 
349
{
 
350
    return QIODevice::pos();
 
351
}
 
352
 
 
353
/*!
 
354
  Returns true if the end of the file has been reached; otherwise returns
 
355
  false.
 
356
 
 
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.
 
361
*/
 
362
bool QFileDevice::atEnd() const
 
363
{
 
364
    Q_D(const QFileDevice);
 
365
 
 
366
    // If there's buffered data left, we're not at the end.
 
367
    if (!d->buffer.isEmpty())
 
368
        return false;
 
369
 
 
370
    if (!isOpen())
 
371
        return true;
 
372
 
 
373
    if (!d->ensureFlushed())
 
374
        return false;
 
375
 
 
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();
 
381
    }
 
382
 
 
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)
 
386
        return false;
 
387
 
 
388
    // Fall back to checking how much is available (will stat files).
 
389
    return bytesAvailable() == 0;
 
390
}
 
391
 
 
392
/*!
 
393
    \fn bool QFileDevice::seek(qint64 pos)
 
394
 
 
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
 
398
    return false.
 
399
 
 
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.
 
406
*/
 
407
bool QFileDevice::seek(qint64 off)
 
408
{
 
409
    Q_D(QFileDevice);
 
410
    if (!isOpen()) {
 
411
        qWarning("QFileDevice::seek: IODevice is not open");
 
412
        return false;
 
413
    }
 
414
 
 
415
    if (!d->ensureFlushed())
 
416
        return false;
 
417
 
 
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());
 
423
        return false;
 
424
    }
 
425
    unsetError();
 
426
    return true;
 
427
}
 
428
 
 
429
/*!
 
430
  \reimp
 
431
*/
 
432
qint64 QFileDevice::readLineData(char *data, qint64 maxlen)
 
433
{
 
434
    Q_D(QFileDevice);
 
435
    if (!d->ensureFlushed())
 
436
        return -1;
 
437
 
 
438
    qint64 read;
 
439
    if (d->fileEngine->supportsExtension(QAbstractFileEngine::FastReadLineExtension)) {
 
440
        read = d->fileEngine->readLine(data, maxlen);
 
441
    } else {
 
442
        // Fall back to QIODevice's readLine implementation if the engine
 
443
        // cannot do it faster.
 
444
        read = QIODevice::readLineData(data, maxlen);
 
445
    }
 
446
 
 
447
    if (read < maxlen) {
 
448
        // failed to read all requested, may be at the end of file, stop caching size so that it's rechecked
 
449
        d->cachedSize = 0;
 
450
    }
 
451
 
 
452
    return read;
 
453
}
 
454
 
 
455
/*!
 
456
  \reimp
 
457
*/
 
458
qint64 QFileDevice::readData(char *data, qint64 len)
 
459
{
 
460
    Q_D(QFileDevice);
 
461
    if (!len)
 
462
        return 0;
 
463
    unsetError();
 
464
    if (!d->ensureFlushed())
 
465
        return -1;
 
466
 
 
467
    const qint64 read = d->fileEngine->read(data, len);
 
468
    if (read < 0) {
 
469
        QFileDevice::FileError err = d->fileEngine->error();
 
470
        if (err == QFileDevice::UnspecifiedError)
 
471
            err = QFileDevice::ReadError;
 
472
        d->setError(err, d->fileEngine->errorString());
 
473
    }
 
474
 
 
475
    if (read < len) {
 
476
        // failed to read all requested, may be at the end of file, stop caching size so that it's rechecked
 
477
        d->cachedSize = 0;
 
478
    }
 
479
 
 
480
    return read;
 
481
}
 
482
 
 
483
/*!
 
484
    \internal
 
485
*/
 
486
bool QFileDevicePrivate::putCharHelper(char c)
 
487
{
 
488
#ifdef QT_NO_QOBJECT
 
489
    return QIODevicePrivate::putCharHelper(c);
 
490
#else
 
491
 
 
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
 
495
#ifdef Q_OS_WIN
 
496
        || ((openMode & QIODevice::Text) && c == '\n' && writeBufferSize + 2 >= QFILE_WRITEBUFFER_SIZE)
 
497
#endif
 
498
        ) {
 
499
        return QIODevicePrivate::putCharHelper(c);
 
500
    }
 
501
 
 
502
    if (!(openMode & QIODevice::WriteOnly)) {
 
503
        if (openMode == QIODevice::NotOpen)
 
504
            qWarning("QIODevice::putChar: Closed device");
 
505
        else
 
506
            qWarning("QIODevice::putChar: ReadOnly device");
 
507
        return false;
 
508
    }
 
509
 
 
510
    // Make sure the device is positioned correctly.
 
511
    const bool sequential = isSequential();
 
512
    if (pos != devicePos && !sequential && !q_func()->seek(pos))
 
513
        return false;
 
514
 
 
515
    lastWasWrite = true;
 
516
 
 
517
    int len = 1;
 
518
#ifdef Q_OS_WIN
 
519
    if ((openMode & QIODevice::Text) && c == '\n') {
 
520
        ++len;
 
521
        *writeBuffer.reserve(1) = '\r';
 
522
    }
 
523
#endif
 
524
 
 
525
    // Write to buffer.
 
526
    *writeBuffer.reserve(1) = c;
 
527
 
 
528
    if (!sequential) {
 
529
        pos += len;
 
530
        devicePos += len;
 
531
        if (!buffer.isEmpty())
 
532
            buffer.skip(len);
 
533
    }
 
534
 
 
535
    return true;
 
536
#endif
 
537
}
 
538
 
 
539
/*!
 
540
  \reimp
 
541
*/
 
542
qint64 QFileDevice::writeData(const char *data, qint64 len)
 
543
{
 
544
    Q_D(QFileDevice);
 
545
    unsetError();
 
546
    d->lastWasWrite = true;
 
547
    bool buffered = !(d->openMode & Unbuffered);
 
548
 
 
549
    // Flush buffered data if this read will overflow.
 
550
    if (buffered && (d->writeBuffer.size() + len) > QFILE_WRITEBUFFER_SIZE) {
 
551
        if (!flush())
 
552
            return -1;
 
553
    }
 
554
 
 
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);
 
559
        if (ret < 0) {
 
560
            QFileDevice::FileError err = d->fileEngine->error();
 
561
            if (err == QFileDevice::UnspecifiedError)
 
562
                err = QFileDevice::WriteError;
 
563
            d->setError(err, d->fileEngine->errorString());
 
564
        }
 
565
        return ret;
 
566
    }
 
567
 
 
568
    // Write to the buffer.
 
569
    char *writePointer = d->writeBuffer.reserve(len);
 
570
    if (len == 1)
 
571
        *writePointer = *data;
 
572
    else
 
573
        ::memcpy(writePointer, data, len);
 
574
    return len;
 
575
}
 
576
 
 
577
/*!
 
578
    Returns the file error status.
 
579
 
 
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.
 
583
 
 
584
    \sa unsetError()
 
585
*/
 
586
QFileDevice::FileError QFileDevice::error() const
 
587
{
 
588
    Q_D(const QFileDevice);
 
589
    return d->error;
 
590
}
 
591
 
 
592
/*!
 
593
    Sets the file's error to QFileDevice::NoError.
 
594
 
 
595
    \sa error()
 
596
*/
 
597
void QFileDevice::unsetError()
 
598
{
 
599
    Q_D(QFileDevice);
 
600
    d->setError(QFileDevice::NoError);
 
601
}
 
602
 
 
603
/*!
 
604
  Returns the size of the file.
 
605
 
 
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().
 
609
*/
 
610
qint64 QFileDevice::size() const
 
611
{
 
612
    Q_D(const QFileDevice);
 
613
    if (!d->ensureFlushed())
 
614
        return 0;
 
615
    d->cachedSize = d->engine()->size();
 
616
    return d->cachedSize;
 
617
}
 
618
 
 
619
/*!
 
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.
 
624
 
 
625
    \sa size()
 
626
*/
 
627
bool QFileDevice::resize(qint64 sz)
 
628
{
 
629
    Q_D(QFileDevice);
 
630
    if (!d->ensureFlushed())
 
631
        return false;
 
632
    d->engine();
 
633
    if (isOpen() && d->fileEngine->pos() > sz)
 
634
        seek(sz);
 
635
    if (d->fileEngine->setSize(sz)) {
 
636
        unsetError();
 
637
        d->cachedSize = sz;
 
638
        return true;
 
639
    }
 
640
    d->cachedSize = 0;
 
641
    d->setError(QFile::ResizeError, d->fileEngine->errorString());
 
642
    return false;
 
643
}
 
644
 
 
645
/*!
 
646
    Returns the complete OR-ed together combination of
 
647
    QFile::Permission for the file.
 
648
 
 
649
    \sa setPermissions()
 
650
*/
 
651
QFile::Permissions QFileDevice::permissions() const
 
652
{
 
653
    Q_D(const QFileDevice);
 
654
    QAbstractFileEngine::FileFlags perms = d->engine()->fileFlags(QAbstractFileEngine::PermsMask) & QAbstractFileEngine::PermsMask;
 
655
    return QFile::Permissions((int)perms); //ewww
 
656
}
 
657
 
 
658
/*!
 
659
    Sets the permissions for the file to the \a permissions specified.
 
660
    Returns true if successful, or false if the permissions cannot be
 
661
    modified.
 
662
 
 
663
    \sa permissions()
 
664
*/
 
665
bool QFileDevice::setPermissions(Permissions permissions)
 
666
{
 
667
    Q_D(QFileDevice);
 
668
    if (d->engine()->setPermissions(permissions)) {
 
669
        unsetError();
 
670
        return true;
 
671
    }
 
672
    d->setError(QFile::PermissionsError, d->fileEngine->errorString());
 
673
    return false;
 
674
}
 
675
 
 
676
/*!
 
677
    \enum QFileDevice::MemoryMapFlags
 
678
    \since 4.4
 
679
 
 
680
    This enum describes special options that may be used by the map()
 
681
    function.
 
682
 
 
683
    \value NoOptions        No options.
 
684
*/
 
685
 
 
686
/*!
 
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.
 
692
 
 
693
    Any mapping options can be passed through \a flags.
 
694
 
 
695
    Returns a pointer to the memory or 0 if there is an error.
 
696
 
 
697
    \note On Windows CE 5.0 the file will be closed before mapping occurs.
 
698
 
 
699
    \sa unmap()
 
700
 */
 
701
uchar *QFileDevice::map(qint64 offset, qint64 size, MemoryMapFlags flags)
 
702
{
 
703
    Q_D(QFileDevice);
 
704
    if (d->engine()
 
705
            && d->fileEngine->supportsExtension(QAbstractFileEngine::MapExtension)) {
 
706
        unsetError();
 
707
        uchar *address = d->fileEngine->map(offset, size, flags);
 
708
        if (address == 0)
 
709
            d->setError(d->fileEngine->error(), d->fileEngine->errorString());
 
710
        return address;
 
711
    }
 
712
    return 0;
 
713
}
 
714
 
 
715
/*!
 
716
    Unmaps the memory \a address.
 
717
 
 
718
    Returns true if the unmap succeeds; false otherwise.
 
719
 
 
720
    \sa map()
 
721
 */
 
722
bool QFileDevice::unmap(uchar *address)
 
723
{
 
724
    Q_D(QFileDevice);
 
725
    if (d->engine()
 
726
        && d->fileEngine->supportsExtension(QAbstractFileEngine::UnMapExtension)) {
 
727
        unsetError();
 
728
        bool success = d->fileEngine->unmap(address);
 
729
        if (!success)
 
730
            d->setError(d->fileEngine->error(), d->fileEngine->errorString());
 
731
        return success;
 
732
    }
 
733
    d->setError(PermissionsError, tr("No file engine available or engine does not support UnMapExtension"));
 
734
    return false;
 
735
}
 
736
 
 
737
QT_END_NAMESPACE