60 |
60 |
61 static const int QFILE_WRITEBUFFER_SIZE = 16384; |
61 static const int QFILE_WRITEBUFFER_SIZE = 16384; |
62 |
62 |
63 static QByteArray locale_encode(const QString &f) |
63 static QByteArray locale_encode(const QString &f) |
64 { |
64 { |
65 #ifndef Q_OS_DARWIN |
65 #if defined(Q_OS_DARWIN) |
66 return f.toLocal8Bit(); |
|
67 #else |
|
68 // Mac always expects UTF-8... and decomposed... |
66 // Mac always expects UTF-8... and decomposed... |
69 return f.normalized(QString::NormalizationForm_D).toUtf8(); |
67 return f.normalized(QString::NormalizationForm_D).toUtf8(); |
|
68 #elif defined(Q_OS_SYMBIAN) |
|
69 return f.toUtf8(); |
|
70 #else |
|
71 return f.toLocal8Bit(); |
70 #endif |
72 #endif |
71 } |
73 } |
72 |
74 |
73 static QString locale_decode(const QByteArray &f) |
75 static QString locale_decode(const QByteArray &f) |
74 { |
76 { |
75 #ifndef Q_OS_DARWIN |
77 #if defined(Q_OS_DARWIN) |
76 return QString::fromLocal8Bit(f); |
|
77 #else |
|
78 // Mac always gives us UTF-8 and decomposed, we want that composed... |
78 // Mac always gives us UTF-8 and decomposed, we want that composed... |
79 return QString::fromUtf8(f).normalized(QString::NormalizationForm_C); |
79 return QString::fromUtf8(f).normalized(QString::NormalizationForm_C); |
|
80 #elif defined(Q_OS_SYMBIAN) |
|
81 return QString::fromUtf8(f); |
|
82 #else |
|
83 return QString::fromLocal8Bit(f); |
80 #endif |
84 #endif |
81 } |
85 } |
82 |
86 |
83 //************* QFilePrivate |
87 //************* QFilePrivate |
84 QFile::EncoderFn QFilePrivate::encoder = locale_encode; |
88 QFile::EncoderFn QFilePrivate::encoder = locale_encode; |
85 QFile::DecoderFn QFilePrivate::decoder = locale_decode; |
89 QFile::DecoderFn QFilePrivate::decoder = locale_decode; |
86 |
90 |
87 QFilePrivate::QFilePrivate() |
91 QFilePrivate::QFilePrivate() |
88 : fileEngine(0), lastWasWrite(false), |
92 : fileEngine(0), lastWasWrite(false), |
89 writeBuffer(QFILE_WRITEBUFFER_SIZE), error(QFile::NoError) |
93 writeBuffer(QFILE_WRITEBUFFER_SIZE), error(QFile::NoError), |
|
94 cachedSize(0) |
90 { |
95 { |
91 } |
96 } |
92 |
97 |
93 QFilePrivate::~QFilePrivate() |
98 QFilePrivate::~QFilePrivate() |
94 { |
99 { |
1440 |
1448 |
1441 bool QFile::atEnd() const |
1449 bool QFile::atEnd() const |
1442 { |
1450 { |
1443 Q_D(const QFile); |
1451 Q_D(const QFile); |
1444 |
1452 |
|
1453 // If there's buffered data left, we're not at the end. |
|
1454 if (!d->buffer.isEmpty()) |
|
1455 return false; |
|
1456 |
1445 if (!isOpen()) |
1457 if (!isOpen()) |
1446 return true; |
1458 return true; |
1447 |
1459 |
1448 if (!d->ensureFlushed()) |
1460 if (!d->ensureFlushed()) |
1449 return false; |
|
1450 |
|
1451 // If there's buffered data left, we're not at the end. |
|
1452 if (!d->buffer.isEmpty()) |
|
1453 return false; |
1461 return false; |
1454 |
1462 |
1455 // If the file engine knows best, say what it says. |
1463 // If the file engine knows best, say what it says. |
1456 if (d->fileEngine->supportsExtension(QAbstractFileEngine::AtEndExtension)) { |
1464 if (d->fileEngine->supportsExtension(QAbstractFileEngine::AtEndExtension)) { |
1457 // Check if the file engine supports AtEndExtension, and if it does, |
1465 // Check if the file engine supports AtEndExtension, and if it does, |
1458 // check if the file engine claims to be at the end. |
1466 // check if the file engine claims to be at the end. |
1459 return d->fileEngine->atEnd(); |
1467 return d->fileEngine->atEnd(); |
1460 } |
1468 } |
1461 |
1469 |
|
1470 // if it looks like we are at the end, or if size is not cached, |
|
1471 // fall through to bytesAvailable() to make sure. |
|
1472 if (pos() < d->cachedSize) |
|
1473 return false; |
|
1474 |
1462 // Fall back to checking how much is available (will stat files). |
1475 // Fall back to checking how much is available (will stat files). |
1463 return bytesAvailable() == 0; |
1476 return bytesAvailable() == 0; |
1464 } |
1477 } |
1465 |
1478 |
1466 /*! |
1479 /*! |
1496 { |
1509 { |
1497 Q_D(QFile); |
1510 Q_D(QFile); |
1498 if (!d->ensureFlushed()) |
1511 if (!d->ensureFlushed()) |
1499 return -1; |
1512 return -1; |
1500 |
1513 |
1501 if (d->fileEngine->supportsExtension(QAbstractFileEngine::FastReadLineExtension)) |
1514 qint64 read; |
1502 return d->fileEngine->readLine(data, maxlen); |
1515 if (d->fileEngine->supportsExtension(QAbstractFileEngine::FastReadLineExtension)) { |
1503 |
1516 read = d->fileEngine->readLine(data, maxlen); |
1504 // Fall back to QIODevice's readLine implementation if the engine |
1517 } else { |
1505 // cannot do it faster. |
1518 // Fall back to QIODevice's readLine implementation if the engine |
1506 return QIODevice::readLineData(data, maxlen); |
1519 // cannot do it faster. |
|
1520 read = QIODevice::readLineData(data, maxlen); |
|
1521 } |
|
1522 |
|
1523 if (read < maxlen) { |
|
1524 // failed to read all requested, may be at the end of file, stop caching size so that it's rechecked |
|
1525 d->cachedSize = 0; |
|
1526 } |
|
1527 |
|
1528 return read; |
1507 } |
1529 } |
1508 |
1530 |
1509 /*! |
1531 /*! |
1510 \reimp |
1532 \reimp |
1511 */ |
1533 */ |
1522 QFile::FileError err = d->fileEngine->error(); |
1544 QFile::FileError err = d->fileEngine->error(); |
1523 if(err == QFile::UnspecifiedError) |
1545 if(err == QFile::UnspecifiedError) |
1524 err = QFile::ReadError; |
1546 err = QFile::ReadError; |
1525 d->setError(err, d->fileEngine->errorString()); |
1547 d->setError(err, d->fileEngine->errorString()); |
1526 } |
1548 } |
|
1549 |
|
1550 if (read < len) { |
|
1551 // failed to read all requested, may be at the end of file, stop caching size so that it's rechecked |
|
1552 d->cachedSize = 0; |
|
1553 } |
|
1554 |
1527 return read; |
1555 return read; |
1528 } |
1556 } |
1529 |
1557 |
1530 /*! |
1558 /*! |
1531 \internal |
1559 \internal |