?? qiodevice.cpp
字號:
// optimization to avoid initial self-assignment while (*readPtr != '\r') { if (++readPtr == endPtr) return readSoFar; } char *writePtr = readPtr; while (readPtr < endPtr) { char ch = *readPtr++; if (ch != '\r') *writePtr++ = ch; else --readSoFar; } // Make sure we get more data if there is room for more. This // is very important for when someone seeks to the start of a // '\r\n' and reads one character - they should get the '\n'. moreToRead = (readPtr != writePtr); } } } 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 If the '\n' character is the 1023th character read then it will be inserted into the buffer; if it occurs after the 1023 character then it is not read. 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') { 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();}/*! \fn bool QIODevice::getChar(char *c) Reads one character from the device and stores it in \a c. If \a c is 0, the character is discarded. Returns true on success; otherwise returns false. \sa read() putChar() ungetChar()*//*! 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_OPEN(write, qint64(-1)); 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) {
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -