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()) { |
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 |
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 |
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. |