Logo Search packages:      
Sourcecode: qt4-x11 version File versions  Download package

qint64 QIODevice::read ( char *  data,
qint64  maxSize 
) [inherited]

Reads at most maxSize bytes from the device into data, and returns the number of bytes read. If an error occurs, such as when attempting to read from a device opened in WriteOnly mode, this function returns -1.

0 is returned when no more data is available for reading.

See also:
readData() readLine() write()

Definition at line 733 of file qiodevice.cpp.

References QIODevice::readData(), and QIODevice::seek().

Referenced by QGLContext::bindTexture(), QFile::copy(), QTemporaryFile::createLocalFile(), QXmlInputSource::fetchData(), QIODevice::getChar(), QTranslator::load(), QDataStream::operator>>(), QIODevice::peek(), QPictureIO::pictureFormat(), QIODevice::read(), QIODevice::readAll(), Q3SocketDevice::readBlock(), QDataStream::readBytes(), Q3SocketDevice::readData(), QFile::readData(), QDataStream::readRawData(), QFile::rename(), QDataStream::skipRawData(), and QIODevice::ungetChar().

{
    Q_D(QIODevice);
    CHECK_READABLE(read, qint64(-1));
    CHECK_MAXLEN(read, qint64(-1));

#if defined QIODEVICE_DEBUG
    printf("%p QIODevice::read(%p, %d), d->pos = %d, d->buffer.size() = %d\n",
           this, data, int(maxSize), int(d->pos), int(d->buffer.size()));
#endif
    const bool sequential = d->isSequential();

    // Short circuit for getChar()
    if (maxSize == 1) {
        int chint = d->buffer.getChar();
        if (chint != -1) {
            char c = char(uchar(chint));
            if (c == '\r' && (d->openMode & Text)) {
                d->buffer.ungetChar(c);
            } else {
                if (data)
                    *data = c;
                if (!sequential)
                    ++d->pos;
#if defined QIODEVICE_DEBUG
                printf("%p \tread 0x%hhx (%c) returning 1 (shortcut)\n", this,
                       int(c), isprint(c) ? c : '?');
#endif
                return qint64(1);
            }
        }
    }

    qint64 readSoFar = 0;
    bool moreToRead = true;
    do {
        int lastReadChunkSize = 0;

        // Try reading from the buffer.
        if (!d->buffer.isEmpty()) {
            lastReadChunkSize = d->buffer.read(data + readSoFar, maxSize - readSoFar);
            readSoFar += lastReadChunkSize;
            if (!sequential)
                d->pos += lastReadChunkSize;
#if defined QIODEVICE_DEBUG
            printf("%p \treading %d bytes from buffer into position %d\n", this, lastReadChunkSize,
                   int(readSoFar) - lastReadChunkSize);
#endif
        } else if ((d->openMode & Unbuffered) == 0 && maxSize < QIODEVICE_BUFFERSIZE) {
            // In buffered mode, we try to fill up the QIODevice buffer before
            // we do anything else.
            int bytesToBuffer = qMax(maxSize - readSoFar, QIODEVICE_BUFFERSIZE);
            char *writePointer = d->buffer.reserve(bytesToBuffer);

            // Make sure the device is positioned correctly.
            if (d->pos != d->devicePos && !sequential && !seek(d->pos))
                return qint64(-1);
            qint64 readFromDevice = readData(writePointer, bytesToBuffer);
            d->buffer.chop(bytesToBuffer - (readFromDevice < 0 ? 0 : int(readFromDevice)));

            if (readFromDevice > 0) {
                if (!sequential)
                    d->devicePos += readFromDevice;
#if defined QIODEVICE_DEBUG
                printf("%p \treading %d from device into buffer\n", this, int(readFromDevice));
#endif

                if (readFromDevice < bytesToBuffer)
                    d->buffer.truncate(readFromDevice < 0 ? 0 : int(readFromDevice));
                if (!d->buffer.isEmpty()) {
                    lastReadChunkSize = d->buffer.read(data + readSoFar, maxSize - readSoFar);
                    readSoFar += lastReadChunkSize;
                    if (!sequential)
                        d->pos += lastReadChunkSize;
#if defined QIODEVICE_DEBUG
                    printf("%p \treading %d bytes from buffer at position %d\n", this,
                           lastReadChunkSize, int(readSoFar));
#endif
                }
            }
        }

        // If we need more, try reading from the device.
        if (readSoFar < maxSize) {
            // Make sure the device is positioned correctly.
            if (d->pos != d->devicePos && !sequential && !seek(d->pos))
                return qint64(-1);
            qint64 readFromDevice = readData(data + readSoFar, maxSize - readSoFar);
#if defined QIODEVICE_DEBUG
            printf("%p \treading %d bytes from device\n", this, int(readFromDevice));
#endif
            if (readFromDevice <= 0) {
                moreToRead = false;
            } else {
                // see if we read as much data as we asked for
                if (readFromDevice < maxSize - readSoFar)
                    moreToRead = false;

                lastReadChunkSize += int(readFromDevice);
                readSoFar += readFromDevice;
                if (!sequential) {
                    d->pos += readFromDevice;
                    d->devicePos += readFromDevice;
                }
            }
        } else {
            moreToRead = false;
        }

        if (readSoFar && d->openMode & Text) {
            char *readPtr = data + readSoFar - lastReadChunkSize;
            const char *endPtr = data + readSoFar;

            if (readPtr < endPtr) {
                // 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;
}


Generated by  Doxygen 1.6.0   Back to index