src/corelib/io/qfile.cpp
branchRCL_3
changeset 4 3b1da2848fc7
parent 3 41300fa6a67c
child 7 3f74d0d4af4c
equal deleted inserted replaced
3:41300fa6a67c 4:3b1da2848fc7
     1 /****************************************************************************
     1 /****************************************************************************
     2 **
     2 **
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     4 ** All rights reserved.
     4 ** All rights reserved.
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     6 **
     6 **
     7 ** This file is part of the QtCore module of the Qt Toolkit.
     7 ** This file is part of the QtCore module of the Qt Toolkit.
     8 **
     8 **
   641     Q_D(QFile);
   641     Q_D(QFile);
   642     if (d->fileName.isEmpty()) {
   642     if (d->fileName.isEmpty()) {
   643         qWarning("QFile::remove: Empty or null file name");
   643         qWarning("QFile::remove: Empty or null file name");
   644         return false;
   644         return false;
   645     }
   645     }
       
   646     unsetError();
   646     close();
   647     close();
   647     if(error() == QFile::NoError) {
   648     if(error() == QFile::NoError) {
   648         if(fileEngine()->remove()) {
   649         if(fileEngine()->remove()) {
   649             unsetError();
   650             unsetError();
   650             return true;
   651             return true;
   651         }
   652         }
   652         d->setError(QFile::RemoveError, fileEngine()->errorString());
   653         d->setError(QFile::RemoveError, d->fileEngine->errorString());
   653     }
   654     }
   654     return false;
   655     return false;
   655 }
   656 }
   656 
   657 
   657 /*!
   658 /*!
   701     close();
   702     close();
   702     if(error() == QFile::NoError) {
   703     if(error() == QFile::NoError) {
   703         if (fileEngine()->rename(newName)) {
   704         if (fileEngine()->rename(newName)) {
   704             unsetError();
   705             unsetError();
   705             // engine was able to handle the new name so we just reset it
   706             // engine was able to handle the new name so we just reset it
   706             fileEngine()->setFileName(newName);
   707             d->fileEngine->setFileName(newName);
   707             d->fileName = newName;
   708             d->fileName = newName;
   708             return true;
   709             return true;
   709         }
   710         }
   710 
   711 
   711         if (isSequential()) {
   712         if (isSequential()) {
   737                     }
   738                     }
   738                 }
   739                 }
   739                 if (error) {
   740                 if (error) {
   740                     out.remove();
   741                     out.remove();
   741                 } else {
   742                 } else {
   742                     fileEngine()->setFileName(newName);
   743                     d->fileEngine->setFileName(newName);
   743                     setPermissions(permissions());
   744                     setPermissions(permissions());
   744                     unsetError();
   745                     unsetError();
   745                     setFileName(newName);
   746                     setFileName(newName);
   746                 }
   747                 }
   747                 close();
   748                 close();
   802     QFileInfo fi(linkName);
   803     QFileInfo fi(linkName);
   803     if(fileEngine()->link(fi.absoluteFilePath())) {
   804     if(fileEngine()->link(fi.absoluteFilePath())) {
   804         unsetError();
   805         unsetError();
   805         return true;
   806         return true;
   806     }
   807     }
   807     d->setError(QFile::RenameError, fileEngine()->errorString());
   808     d->setError(QFile::RenameError, d->fileEngine->errorString());
   808     return false;
   809     return false;
   809 }
   810 }
   810 
   811 
   811 /*!
   812 /*!
   812     \overload
   813     \overload
   966 
   967 
   967     \note In \l{QIODevice::}{WriteOnly} or \l{QIODevice::}{ReadWrite}
   968     \note In \l{QIODevice::}{WriteOnly} or \l{QIODevice::}{ReadWrite}
   968     mode, if the relevant file does not already exist, this function
   969     mode, if the relevant file does not already exist, this function
   969     will try to create a new file before opening it.
   970     will try to create a new file before opening it.
   970 
   971 
   971     \note Because of limitations in the native API, QFile ignores the
       
   972     Unbuffered flag on Windows.
       
   973 
       
   974     \sa QIODevice::OpenMode, setFileName()
   972     \sa QIODevice::OpenMode, setFileName()
   975 */
   973 */
   976 bool QFile::open(OpenMode mode)
   974 bool QFile::open(OpenMode mode)
   977 {
   975 {
   978     Q_D(QFile);
   976     Q_D(QFile);
   986     unsetError();
   984     unsetError();
   987     if ((mode & (ReadOnly | WriteOnly)) == 0) {
   985     if ((mode & (ReadOnly | WriteOnly)) == 0) {
   988         qWarning("QIODevice::open: File access not specified");
   986         qWarning("QIODevice::open: File access not specified");
   989         return false;
   987         return false;
   990     }
   988     }
   991     if (fileEngine()->open(mode)) {
   989 
       
   990     // QIODevice provides the buffering, so there's no need to request it from the file engine.
       
   991     if (fileEngine()->open(mode | QIODevice::Unbuffered)) {
   992         QIODevice::open(mode);
   992         QIODevice::open(mode);
   993         if (mode & Append)
   993         if (mode & Append)
   994             seek(size());
   994             seek(size());
   995         return true;
   995         return true;
   996     }
   996     }
   997     QFile::FileError err = fileEngine()->error();
   997     QFile::FileError err = d->fileEngine->error();
   998     if(err == QFile::UnspecifiedError)
   998     if(err == QFile::UnspecifiedError)
   999         err = QFile::OpenError;
   999         err = QFile::OpenError;
  1000     d->setError(err, fileEngine()->errorString());
  1000     d->setError(err, d->fileEngine->errorString());
  1001     return false;
  1001     return false;
  1002 }
  1002 }
  1003 
  1003 
  1004 /*! \fn QFile::open(OpenMode, FILE*)
  1004 /*! \fn QFile::open(OpenMode, FILE*)
  1005 
  1005 
  1150 */
  1150 */
  1151 
  1151 
  1152 int
  1152 int
  1153 QFile::handle() const
  1153 QFile::handle() const
  1154 {
  1154 {
  1155     if (!isOpen())
  1155     Q_D(const QFile);
       
  1156     if (!isOpen() || !d->fileEngine)
  1156         return -1;
  1157         return -1;
  1157 
  1158 
  1158     if (QAbstractFileEngine *engine = fileEngine())
  1159     return d->fileEngine->handle();
  1159         return engine->handle();
       
  1160     return -1;
       
  1161 }
  1160 }
  1162 
  1161 
  1163 /*!
  1162 /*!
  1164     \enum QFile::MemoryMapFlags
  1163     \enum QFile::MemoryMapFlags
  1165     \since 4.4
  1164     \since 4.4
  1187     \sa unmap(), QAbstractFileEngine::supportsExtension()
  1186     \sa unmap(), QAbstractFileEngine::supportsExtension()
  1188  */
  1187  */
  1189 uchar *QFile::map(qint64 offset, qint64 size, MemoryMapFlags flags)
  1188 uchar *QFile::map(qint64 offset, qint64 size, MemoryMapFlags flags)
  1190 {
  1189 {
  1191     Q_D(QFile);
  1190     Q_D(QFile);
  1192     QAbstractFileEngine *engine = fileEngine();
  1191     if (fileEngine()
  1193     if (engine
  1192             && d->fileEngine->supportsExtension(QAbstractFileEngine::MapExtension)) {
  1194         && engine->supportsExtension(QAbstractFileEngine::MapExtension)) {
       
  1195         unsetError();
  1193         unsetError();
  1196         uchar *address = engine->map(offset, size, flags);
  1194         uchar *address = d->fileEngine->map(offset, size, flags);
  1197         if (address == 0)
  1195         if (address == 0)
  1198             d->setError(engine->error(), engine->errorString());
  1196             d->setError(d->fileEngine->error(), d->fileEngine->errorString());
  1199         return address;
  1197         return address;
  1200     }
  1198     }
  1201     return 0;
  1199     return 0;
  1202 }
  1200 }
  1203 
  1201 
  1210     \sa map(), QAbstractFileEngine::supportsExtension()
  1208     \sa map(), QAbstractFileEngine::supportsExtension()
  1211  */
  1209  */
  1212 bool QFile::unmap(uchar *address)
  1210 bool QFile::unmap(uchar *address)
  1213 {
  1211 {
  1214     Q_D(QFile);
  1212     Q_D(QFile);
  1215     QAbstractFileEngine *engine = fileEngine();
  1213     if (fileEngine()
  1216     if (engine
  1214         && d->fileEngine->supportsExtension(QAbstractFileEngine::UnMapExtension)) {
  1217         && engine->supportsExtension(QAbstractFileEngine::UnMapExtension)) {
       
  1218         unsetError();
  1215         unsetError();
  1219         bool success = engine->unmap(address);
  1216         bool success = d->fileEngine->unmap(address);
  1220         if (!success)
  1217         if (!success)
  1221             d->setError(engine->error(), engine->errorString());
  1218             d->setError(d->fileEngine->error(), d->fileEngine->errorString());
  1222         return success;
  1219         return success;
  1223     }
  1220     }
  1224     return false;
  1221     return false;
  1225 }
  1222 }
  1226 
  1223 
  1249 QFile::resize(qint64 sz)
  1246 QFile::resize(qint64 sz)
  1250 {
  1247 {
  1251     Q_D(QFile);
  1248     Q_D(QFile);
  1252     if (!d->ensureFlushed())
  1249     if (!d->ensureFlushed())
  1253         return false;
  1250         return false;
  1254     if (isOpen() && fileEngine()->pos() > sz)
  1251     fileEngine();
       
  1252     if (isOpen() && d->fileEngine->pos() > sz)
  1255         seek(sz);
  1253         seek(sz);
  1256     if(fileEngine()->setSize(sz)) {
  1254     if(d->fileEngine->setSize(sz)) {
  1257         unsetError();
  1255         unsetError();
  1258         return true;
  1256         return true;
  1259     }
  1257     }
  1260     d->setError(QFile::ResizeError, fileEngine()->errorString());
  1258     d->setError(QFile::ResizeError, d->fileEngine->errorString());
  1261     return false;
  1259     return false;
  1262 }
  1260 }
  1263 
  1261 
  1264 /*!
  1262 /*!
  1265     \overload
  1263     \overload
  1319     Q_D(QFile);
  1317     Q_D(QFile);
  1320     if(fileEngine()->setPermissions(permissions)) {
  1318     if(fileEngine()->setPermissions(permissions)) {
  1321         unsetError();
  1319         unsetError();
  1322         return true;
  1320         return true;
  1323     }
  1321     }
  1324     d->setError(QFile::PermissionsError, fileEngine()->errorString());
  1322     d->setError(QFile::PermissionsError, d->fileEngine->errorString());
  1325     return false;
  1323     return false;
  1326 }
  1324 }
  1327 
  1325 
  1328 /*!
  1326 /*!
  1329     \overload
  1327     \overload
  1352 
  1350 
  1353 bool
  1351 bool
  1354 QFile::flush()
  1352 QFile::flush()
  1355 {
  1353 {
  1356     Q_D(QFile);
  1354     Q_D(QFile);
       
  1355     if (!d->fileEngine) {
       
  1356         qWarning("QFile::flush: No file engine. Is IODevice open?");
       
  1357         return false;
       
  1358     }
       
  1359 
  1357     if (!d->writeBuffer.isEmpty()) {
  1360     if (!d->writeBuffer.isEmpty()) {
  1358         qint64 size = d->writeBuffer.size();
  1361         qint64 size = d->writeBuffer.size();
  1359         if (_qfile_writeData(d->fileEngine ? d->fileEngine : fileEngine(),
  1362         if (_qfile_writeData(d->fileEngine, &d->writeBuffer) != size) {
  1360                              &d->writeBuffer) != size) {
  1363             QFile::FileError err = d->fileEngine->error();
  1361             QFile::FileError err = fileEngine()->error();
       
  1362             if(err == QFile::UnspecifiedError)
  1364             if(err == QFile::UnspecifiedError)
  1363                 err = QFile::WriteError;
  1365                 err = QFile::WriteError;
  1364             d->setError(err, fileEngine()->errorString());
  1366             d->setError(err, d->fileEngine->errorString());
  1365             return false;
  1367             return false;
  1366         }
  1368         }
  1367     }
  1369     }
  1368 
  1370 
  1369     if (!fileEngine()->flush()) {
  1371     if (!d->fileEngine->flush()) {
  1370         QFile::FileError err = fileEngine()->error();
  1372         QFile::FileError err = d->fileEngine->error();
  1371         if(err == QFile::UnspecifiedError)
  1373         if(err == QFile::UnspecifiedError)
  1372             err = QFile::WriteError;
  1374             err = QFile::WriteError;
  1373         d->setError(err, fileEngine()->errorString());
  1375         d->setError(err, d->fileEngine->errorString());
  1374         return false;
  1376         return false;
  1375     }
  1377     }
  1376     return true;
  1378     return true;
  1377 }
  1379 }
  1378 
  1380 
  1385 QFile::close()
  1387 QFile::close()
  1386 {
  1388 {
  1387     Q_D(QFile);
  1389     Q_D(QFile);
  1388     if(!isOpen())
  1390     if(!isOpen())
  1389         return;
  1391         return;
  1390     flush();
  1392     bool flushed = flush();
  1391     QIODevice::close();
  1393     QIODevice::close();
  1392 
  1394 
  1393     unsetError();
  1395     // reset write buffer
  1394     if(!fileEngine()->close())
  1396     d->lastWasWrite = false;
  1395         d->setError(fileEngine()->error(), fileEngine()->errorString());
  1397     d->writeBuffer.clear();
       
  1398 
       
  1399     // keep earlier error from flush
       
  1400     if (d->fileEngine->close() && flushed)
       
  1401         unsetError();
       
  1402     else if (flushed)
       
  1403         d->setError(d->fileEngine->error(), d->fileEngine->errorString());
  1396 }
  1404 }
  1397 
  1405 
  1398 /*!
  1406 /*!
  1399   Returns the size of the file.
  1407   Returns the size of the file.
  1400 
  1408 
  1443     // If there's buffered data left, we're not at the end.
  1451     // If there's buffered data left, we're not at the end.
  1444     if (!d->buffer.isEmpty())
  1452     if (!d->buffer.isEmpty())
  1445         return false;
  1453         return false;
  1446 
  1454 
  1447     // If the file engine knows best, say what it says.
  1455     // If the file engine knows best, say what it says.
  1448     if (fileEngine()->supportsExtension(QAbstractFileEngine::AtEndExtension)) {
  1456     if (d->fileEngine->supportsExtension(QAbstractFileEngine::AtEndExtension)) {
  1449         // Check if the file engine supports AtEndExtension, and if it does,
  1457         // Check if the file engine supports AtEndExtension, and if it does,
  1450         // check if the file engine claims to be at the end.
  1458         // check if the file engine claims to be at the end.
  1451         return fileEngine()->atEnd();
  1459         return d->fileEngine->atEnd();
  1452     }
  1460     }
  1453 
  1461 
  1454     // Fall back to checking how much is available (will stat files).
  1462     // Fall back to checking how much is available (will stat files).
  1455     return bytesAvailable() == 0;
  1463     return bytesAvailable() == 0;
  1456 }
  1464 }
  1468     }
  1476     }
  1469 
  1477 
  1470     if (!d->ensureFlushed())
  1478     if (!d->ensureFlushed())
  1471         return false;
  1479         return false;
  1472 
  1480 
  1473     if (!fileEngine()->seek(off) || !QIODevice::seek(off)) {
  1481     if (!d->fileEngine->seek(off) || !QIODevice::seek(off)) {
  1474         QFile::FileError err = fileEngine()->error();
  1482         QFile::FileError err = d->fileEngine->error();
  1475         if(err == QFile::UnspecifiedError)
  1483         if(err == QFile::UnspecifiedError)
  1476             err = QFile::PositionError;
  1484             err = QFile::PositionError;
  1477         d->setError(err, fileEngine()->errorString());
  1485         d->setError(err, d->fileEngine->errorString());
  1478         return false;
  1486         return false;
  1479     }
  1487     }
  1480     unsetError();
  1488     unsetError();
  1481     return true;
  1489     return true;
  1482 }
  1490 }
  1488 {
  1496 {
  1489     Q_D(QFile);
  1497     Q_D(QFile);
  1490     if (!d->ensureFlushed())
  1498     if (!d->ensureFlushed())
  1491         return -1;
  1499         return -1;
  1492 
  1500 
  1493     if (fileEngine()->supportsExtension(QAbstractFileEngine::FastReadLineExtension))
  1501     if (d->fileEngine->supportsExtension(QAbstractFileEngine::FastReadLineExtension))
  1494         return fileEngine()->readLine(data, maxlen);
  1502         return d->fileEngine->readLine(data, maxlen);
  1495 
  1503 
  1496     // Fall back to QIODevice's readLine implementation if the engine
  1504     // Fall back to QIODevice's readLine implementation if the engine
  1497     // cannot do it faster.
  1505     // cannot do it faster.
  1498     return QIODevice::readLineData(data, maxlen);
  1506     return QIODevice::readLineData(data, maxlen);
  1499 }
  1507 }
  1507     Q_D(QFile);
  1515     Q_D(QFile);
  1508     unsetError();
  1516     unsetError();
  1509     if (!d->ensureFlushed())
  1517     if (!d->ensureFlushed())
  1510         return -1;
  1518         return -1;
  1511 
  1519 
  1512     qint64 ret = -1;
  1520     qint64 read = d->fileEngine->read(data, len);
  1513     qint64 read = fileEngine()->read(data, len);
  1521     if(read < 0) {
  1514     if (read != -1)
  1522         QFile::FileError err = d->fileEngine->error();
  1515         ret = read;
       
  1516 
       
  1517     if(ret < 0) {
       
  1518         QFile::FileError err = fileEngine()->error();
       
  1519         if(err == QFile::UnspecifiedError)
  1523         if(err == QFile::UnspecifiedError)
  1520             err = QFile::ReadError;
  1524             err = QFile::ReadError;
  1521         d->setError(err, fileEngine()->errorString());
  1525         d->setError(err, d->fileEngine->errorString());
  1522     }
  1526     }
  1523     return ret;
  1527     return read;
  1524 }
  1528 }
  1525 
  1529 
  1526 /*!
  1530 /*!
  1527     \internal
  1531     \internal
  1528 */
  1532 */
  1598     }
  1602     }
  1599 
  1603 
  1600     // Write directly to the engine if the block size is larger than
  1604     // Write directly to the engine if the block size is larger than
  1601     // the write buffer size.
  1605     // the write buffer size.
  1602     if (!buffered || len > QFILE_WRITEBUFFER_SIZE) {
  1606     if (!buffered || len > QFILE_WRITEBUFFER_SIZE) {
  1603         QAbstractFileEngine *fe = d->fileEngine ? d->fileEngine : fileEngine();
  1607         qint64 ret = d->fileEngine->write(data, len);
  1604         qint64 ret = fe->write(data, len);
       
  1605         if(ret < 0) {
  1608         if(ret < 0) {
  1606             QFile::FileError err = fileEngine()->error();
  1609             QFile::FileError err = d->fileEngine->error();
  1607             if(err == QFile::UnspecifiedError)
  1610             if(err == QFile::UnspecifiedError)
  1608                 err = QFile::WriteError;
  1611                 err = QFile::WriteError;
  1609             d->setError(err, fileEngine()->errorString());
  1612             d->setError(err, d->fileEngine->errorString());
  1610         }
  1613         }
  1611         return ret;
  1614         return ret;
  1612     }
  1615     }
  1613 
  1616 
  1614     // Write to the buffer.
  1617     // Write to the buffer.