📄 qiodevice.cpp
字号:
} } while (moreToRead);#if defined QIODEVICE_DEBUG printf("%p \treturning %d, d->pos == %d, d->buffer.size() == %d\n", this, int(readSoFar), int(d->pos), d->buffer.size()); debugBinaryString(data, readSoFar);#endif return readSoFar;}/*! \overload Reads at most \a maxSize bytes from the device, and returns the data read as a QByteArray. This function has no way of reporting errors; returning an empty QByteArray() can mean either that no data was currently available for reading, or that an error occurred.*/QByteArray QIODevice::read(qint64 maxSize){ Q_D(QIODevice); CHECK_MAXLEN(read, QByteArray()); QByteArray tmp; qint64 readSoFar = 0; char buffer[4096];#if defined QIODEVICE_DEBUG printf("%p QIODevice::read(%d), d->pos = %d, d->buffer.size() = %d\n", this, int(maxSize), int(d->pos), int(d->buffer.size()));#else Q_UNUSED(d);#endif do { qint64 bytesToRead = qMin(int(maxSize - readSoFar), int(sizeof(buffer))); qint64 readBytes = read(buffer, bytesToRead); if (readBytes <= 0) break; tmp += QByteArray(buffer, (int) readBytes); readSoFar += readBytes; } while (readSoFar < maxSize && bytesAvailable() > 0); return tmp;}/*! \overload Reads all available data from the device, and returns it as a QByteArray. This function has no way of reporting errors; returning an empty QByteArray() can mean either that no data was currently available for reading, or that an error occurred.*/QByteArray QIODevice::readAll(){ Q_D(QIODevice);#if defined QIODEVICE_DEBUG printf("%p QIODevice::readAll(), d->pos = %d, d->buffer.size() = %d\n", this, int(d->pos), int(d->buffer.size()));#endif QByteArray tmp; if (d->isSequential() || size() == 0) { // Read it in chunks, bytesAvailable() is unreliable for sequential // devices. const int chunkSize = 4096; qint64 totalRead = 0; forever { tmp.resize(tmp.size() + chunkSize); qint64 readBytes = read(tmp.data() + totalRead, chunkSize); tmp.chop(chunkSize - (readBytes < 0 ? 0 : readBytes)); if (readBytes <= 0) return tmp; totalRead += readBytes; } } else { // Read it all in one go. tmp.resize(int(bytesAvailable())); qint64 readBytes = read(tmp.data(), tmp.size()); tmp.resize(readBytes < 0 ? 0 : int(readBytes)); } return tmp;}/*! This function reads a line of ASCII characters from the device, up to a maximum of \a maxSize - 1 bytes, stores the characters in \a data, and returns the number of bytes read. If an error occurred, -1 is returned. A terminating '\0' byte is always appended to \a data, so \a maxSize must be larger than 1. Data is read until either of the following conditions are met: \list \o The first '\n' character is read. \o \a maxSize - 1 bytes are read. \o The end of the device data is detected. \endlist For example, the following code reads a line of characters from a file: \code QFile file("box.txt"); if (file.open(QFile::ReadOnly)) { char buf[1024]; qint64 lineLength = file.readLine(buf, sizeof(buf)); if (lineLength != -1) { // the line is available in buf } } \endcode The newline character ('\n') is included in the buffer. If a newline is not encountered before maxSize - 1 bytes are read, a newline will not be inserted into the buffer. On windows newline characters are replaced with '\n'. This function calls readLineData(), which is implemented using repeated calls to getChar(). You can provide a more efficient implementation by reimplementing readLineData() in your own subclass. \sa getChar(), read(), write()*/qint64 QIODevice::readLine(char *data, qint64 maxSize){ Q_D(QIODevice); if (maxSize < 2) { qWarning("QIODevice::readLine: Called with maxSize < 2"); return qint64(-1); }#if defined QIODEVICE_DEBUG printf("%p QIODevice::readLine(%p, %d), d->pos = %d, d->buffer.size() = %d\n", this, data, int(maxSize), int(d->pos), int(d->buffer.size()));#endif // Leave room for a '\0' --maxSize; const bool sequential = d->isSequential(); qint64 readSoFar = 0; if (!d->buffer.isEmpty()) { readSoFar = d->buffer.readLine(data, maxSize); if (!sequential) d->pos += readSoFar;#if defined QIODEVICE_DEBUG printf("%p \tread from buffer: %d bytes, last character read: %hhx\n", this, int(readSoFar), data[int(readSoFar) - 1]); if (readSoFar) debugBinaryString(data, int(readSoFar));#endif if (readSoFar && data[readSoFar - 1] == '\n') { if (d->openMode & Text) { // QRingBuffer::readLine() isn't Text aware. if (readSoFar > 1 && data[readSoFar - 2] == '\r') { --readSoFar; data[readSoFar - 1] = '\n'; } } data[readSoFar] = '\0'; return readSoFar; } } if (d->pos != d->devicePos && !sequential && !seek(d->pos)) return qint64(-1); d->baseReadLineDataCalled = false; qint64 readBytes = readLineData(data + readSoFar, maxSize - readSoFar);#if defined QIODEVICE_DEBUG printf("%p \tread from readLineData: %d bytes, readSoFar = %d bytes\n", this, int(readBytes), int(readSoFar)); if (readBytes > 0) { debugBinaryString(data, int(readSoFar + readBytes)); }#endif if (readBytes <= 0) { data[readSoFar] = '\0'; return readSoFar ? readSoFar : -1; } readSoFar += readBytes; if (!d->baseReadLineDataCalled && !sequential) { d->pos += readBytes; // If the base implementation was not called, then we must // assume the device position is invalid and force a seek. d->devicePos = qint64(-1); } data[readSoFar] = '\0'; if (d->openMode & Text) { if (readSoFar > 1 && data[readSoFar - 1] == '\n' && data[readSoFar - 2] == '\r') { data[readSoFar - 2] = '\n'; data[readSoFar - 1] = '\0'; --readSoFar; } }#if defined QIODEVICE_DEBUG printf("%p \treturning %d, d->pos = %d, d->buffer.size() = %d, size() = %d\n", this, int(readSoFar), int(d->pos), d->buffer.size(), int(size())); debugBinaryString(data, int(readSoFar));#endif return readSoFar;}/*! \overload Reads a line from the device, but no more than \a maxSize characters, and returns the result as a QByteArray. This function has no way of reporting errors; returning an empty QByteArray() can mean either that no data was currently available for reading, or that an error occurred.*/QByteArray QIODevice::readLine(qint64 maxSize){ Q_D(QIODevice); CHECK_MAXLEN(readLine, QByteArray()); QByteArray tmp; const int BufferGrowth = 4096; qint64 readSoFar = 0; qint64 readBytes = 0;#if defined QIODEVICE_DEBUG printf("%p QIODevice::readLine(%d), d->pos = %d, d->buffer.size() = %d\n", this, int(maxSize), int(d->pos), int(d->buffer.size()));#else Q_UNUSED(d);#endif do { if (maxSize != 0) tmp.resize(int(readSoFar + qMin(int(maxSize), BufferGrowth))); else tmp.resize(int(readSoFar + BufferGrowth)); readBytes = readLine(tmp.data() + readSoFar, tmp.size() - readSoFar); if (readBytes <= 0) break; readSoFar += readBytes; } while ((!maxSize || readSoFar < maxSize) && readSoFar + 1 == tmp.size() && // +1 due to the ending null tmp.at(readSoFar - 1) != '\n'); tmp.resize(int(readSoFar)); return tmp;}/*! Reads up to \a maxSize characters into \a data and returns the number of characters read. This function is called by readLine(), and provides its base implementation, using getChar(). Buffered devices can improve the performance of readLine() by reimplementing this function. readLine() appends a '\0' byte to \a data; readLineData() does not need to do this.*/qint64 QIODevice::readLineData(char *data, qint64 maxSize){ qint64 readSoFar = 0; char c; bool lastGetSucceeded = false; d_func()->baseReadLineDataCalled = true; while (readSoFar < maxSize && (lastGetSucceeded = getChar(&c))) { *data++ = c; ++readSoFar; if (c == '\n') break; }#if defined QIODEVICE_DEBUG Q_D(QIODevice); printf("%p QIODevice::readLineData(%p, %d), d->pos = %d, d->buffer.size() = %d, returns %d\n", this, data, int(maxSize), int(d->pos), int(d->buffer.size()), int(readSoFar));#endif if (!lastGetSucceeded && readSoFar == 0) return qint64(-1); return readSoFar;}/*! Returns true if a complete line of data can be read from the device; otherwise returns false. Note that unbuffered devices, which have no way of determining what can be read, always return false. This function is often called in conjunction with the readyRead() signal. Subclasses that reimplement this function must call the base implementation in order to include the size of the QIODevice's buffer. Example: \code bool CustomDevice::canReadLine() const { return buffer.contains('\n') || QIODevice::canReadLine(); } \endcode \sa readyRead(), readLine()*/bool QIODevice::canReadLine() const{ return d_func()->buffer.canReadLine();}/*! Writes at most \a maxSize bytes of data from \a data to the device. Returns the number of bytes that were actually written, or -1 if an error occurred. \sa read() writeData()*/qint64 QIODevice::write(const char *data, qint64 maxSize){ Q_D(QIODevice); CHECK_WRITABLE(write, qint64(-1)); CHECK_MAXLEN(write, qint64(-1)); const bool sequential = d->isSequential(); // Make sure the device is positioned correctly. if (d->pos != d->devicePos && !sequential && !seek(d->pos)) return qint64(-1);#ifdef Q_OS_WIN if (d->openMode & Text) { const char *endOfData = data + maxSize; const char *startOfBlock = data; qint64 writtenSoFar = 0; forever { const char *endOfBlock = startOfBlock; while (endOfBlock < endOfData && *endOfBlock != '\n') ++endOfBlock; qint64 blockSize = endOfBlock - startOfBlock; if (blockSize > 0) { qint64 ret = writeData(startOfBlock, blockSize); if (ret <= 0) { if (writtenSoFar && !sequential) d->buffer.skip(writtenSoFar); return writtenSoFar ? writtenSoFar : ret; } if (!sequential) { d->pos += ret; d->devicePos += ret; } writtenSoFar += ret; } if (endOfBlock == endOfData) break; qint64 ret = writeData("\r\n", 2); if (ret <= 0) { if (writtenSoFar && !sequential) d->buffer.skip(writtenSoFar); return writtenSoFar ? writtenSoFar : ret; } if (!sequential) { d->pos += ret; d->devicePos += ret; } ++writtenSoFar; startOfBlock = endOfBlock + 1; } if (writtenSoFar && !sequential) d->buffer.skip(writtenSoFar); return writtenSoFar; }#endif qint64 written = writeData(data, maxSize); if (written > 0) { if (!sequential) { d->pos += written; d->devicePos += written; } if (!d->buffer.isEmpty() && !sequential) d->buffer.skip(written); } return written;}/*! \fn qint64 QIODevice::write(const QByteArray &byteArray) \overload Writes the content of \a byteArray to the device. Returns the number of bytes that were actually written, or -1 if an error occurred. \sa read() writeData()*//*! Puts the character \a c back into the device, and decrements the current position unless the position is 0. This function is usually called to "undo" a getChar() operation, such as when writing a backtracking parser. If \a c was not previously read from the device, the behavior is undefined.*/void QIODevice::ungetChar(char c){ Q_D(QIODevice); CHECK_READABLE(read, Q_VOID);#if defined QIODEVICE_DEBUG printf("%p QIODevice::ungetChar(0x%hhx '%c')\n", this, c, isprint(c) ? c : '?');#endif d->buffer.ungetChar(c); if (!d->isSequential()) --d->pos;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -