/*! \internal */ qint64 QFSFileEnginePrivate::nativeRead(char *data, qint64 len) { Q_Q(QFSFileEngine); if (fh && nativeIsSequential()) { size_t readBytes = 0; int oldFlags = fcntl(QT_FILENO(fh), F_GETFL); for (int i = 0; i < 2; ++i) { // Unix: Make the underlying file descriptor non-blocking int v = 1; if ((oldFlags & O_NONBLOCK) == 0) fcntl(QT_FILENO(fh), F_SETFL, oldFlags | O_NONBLOCK, &v, sizeof(v)); // Cross platform stdlib read size_t read = 0; do { read = fread(data + readBytes, 1, size_t(len - readBytes), fh); } while (read == 0 && !feof(fh) && errno == EINTR); if (read > 0) { readBytes += read; break; } else { if (readBytes) break; readBytes = read; } // Unix: Restore the blocking state of the underlying socket if ((oldFlags & O_NONBLOCK) == 0) { int v = 1; fcntl(QT_FILENO(fh), F_SETFL, oldFlags, &v, sizeof(v)); if (readBytes == 0) { int readByte = 0; do { readByte = fgetc(fh); } while (readByte == -1 && errno == EINTR); if (readByte != -1) { *data = uchar(readByte); readBytes += 1; } else { break; } } } } // Unix: Restore the blocking state of the underlying socket if ((oldFlags & O_NONBLOCK) == 0) { int v = 1; fcntl(QT_FILENO(fh), F_SETFL, oldFlags, &v, sizeof(v)); } if (readBytes == 0 && !feof(fh)) { // if we didn't read anything and we're not at EOF, it must be an error q->setError(QFile::ReadError, qt_error_string(int(errno))); return -1; } return readBytes; } return readFdFh(data, len); }
/* \internal */ qint64 QFSFileEnginePrivate::nativeRead(char *data, qint64 maxlen) { Q_Q(QFSFileEngine); if (fh || fd != -1) { // stdio / stdlib mode. if (fh && nativeIsSequential() && feof(fh)) { q->setError(QFile::ReadError, qt_error_string(int(errno))); return -1; } return readFdFh(data, maxlen); } // Windows native mode. if (fileHandle == INVALID_HANDLE_VALUE) return -1; qint64 bytesToRead = maxlen; // Reading on Windows fails with ERROR_NO_SYSTEM_RESOURCES when // the chunks are too large, so we limit the block size to 32MB. static const qint64 maxBlockSize = 32 * 1024 * 1024; qint64 totalRead = 0; do { DWORD blockSize = DWORD(qMin(bytesToRead, maxBlockSize)); DWORD bytesRead; if (!ReadFile(fileHandle, data + totalRead, blockSize, &bytesRead, NULL)) { if (totalRead == 0) { // Note: only return failure if the first ReadFile fails. q->setError(QFile::ReadError, qt_error_string()); return -1; } break; } if (bytesRead == 0) break; totalRead += bytesRead; bytesToRead -= bytesRead; } while (totalRead < maxlen); return totalRead; }
/*! \internal */ qint64 QFSFileEnginePrivate::nativeRead(char *data, qint64 len) { Q_Q(QFSFileEngine); #ifdef Q_OS_SYMBIAN if (symbianFile.SubSessionHandle()) { if(len > KMaxTInt) { //this check is more likely to catch a corrupt length, since it isn't possible to allocate 2GB buffers (yet..) q->setError(QFile::ReadError, QLatin1String("Maximum 2GB in single read on this platform")); return -1; } TPtr8 ptr(reinterpret_cast<TUint8*>(data), static_cast<TInt>(len)); TInt r = symbianFile.Read(symbianFilePos, ptr); if (r != KErrNone) { q->setError(QFile::ReadError, QSystemError(r, QSystemError::NativeError).toString()); return -1; } symbianFilePos += ptr.Length(); return qint64(ptr.Length()); } #endif if (fh && nativeIsSequential()) { size_t readBytes = 0; int oldFlags = fcntl(QT_FILENO(fh), F_GETFL); for (int i = 0; i < 2; ++i) { // Unix: Make the underlying file descriptor non-blocking if ((oldFlags & O_NONBLOCK) == 0) fcntl(QT_FILENO(fh), F_SETFL, oldFlags | O_NONBLOCK); // Cross platform stdlib read size_t read = 0; do { read = fread(data + readBytes, 1, size_t(len - readBytes), fh); } while (read == 0 && !feof(fh) && errno == EINTR); if (read > 0) { readBytes += read; break; } else { if (readBytes) break; readBytes = read; } // Unix: Restore the blocking state of the underlying socket if ((oldFlags & O_NONBLOCK) == 0) { fcntl(QT_FILENO(fh), F_SETFL, oldFlags); if (readBytes == 0) { int readByte = 0; do { readByte = fgetc(fh); } while (readByte == -1 && errno == EINTR); if (readByte != -1) { *data = uchar(readByte); readBytes += 1; } else { break; } } } } // Unix: Restore the blocking state of the underlying socket if ((oldFlags & O_NONBLOCK) == 0) { fcntl(QT_FILENO(fh), F_SETFL, oldFlags); } if (readBytes == 0 && !feof(fh)) { // if we didn't read anything and we're not at EOF, it must be an error q->setError(QFile::ReadError, qt_error_string(int(errno))); return -1; } return readBytes; } return readFdFh(data, len); }