QByteArray QIODeviceProto::peek(qint64 maxSize)
{
  QIODevice *item = qscriptvalue_cast<QIODevice*>(thisObject());
  if (item)
    return item->peek(maxSize);
  return QByteArray();
}
qint64 QIODeviceProto::peek(char *data, qint64 maxSize)
{
  QIODevice *item = qscriptvalue_cast<QIODevice*>(thisObject());
  if (item)
    return item->peek(data, maxSize);
  return 0;
}
예제 #3
0
/** Check if a full message is available in the buffer
 *
 * @param ioDevice
 *
 * @return
 *
 * History:
 * - 2010/08/03: STEELJ  - Initial Version.
  */
bool CAdChannel::fullMessageAvailable(QIODevice& ioDevice) const
{
  if (ioDevice.bytesAvailable() < 4)
    return false;
  QByteArray startData = ioDevice.peek(4);
  if (startData.size() < 4)
    return false;
  QDataStream stream(startData);
  quint16 messageId, messageSize;
  stream >> messageId;
  stream >> messageSize;
  return(m_socket->bytesAvailable() >= (messageSize + 8));
}
예제 #4
0
/**
  * @exception notEnoughDataException
  */
MessageHeader MessageHeader::readHeader(QIODevice& device, bool skipReadData)
{
   if (device.bytesAvailable() < HEADER_SIZE)
      throw notEnoughDataException();

   char data[HEADER_SIZE];

   if (skipReadData)
      device.read(data, HEADER_SIZE);
   else
      device.peek(data, HEADER_SIZE);

   return MessageHeader::readHeader(data);
}
예제 #5
0
//--------------------------------------------------------------------
void tst_QIODevice::peek()
{
    QBuffer buffer;
    QFile::remove("peektestfile");
    QFile file("peektestfile");

    for (int i = 0; i < 2; ++i) {
        QIODevice *device = i ? (QIODevice *)&file : (QIODevice *)&buffer;

        device->open(QBuffer::ReadWrite);
        device->write("ZXCV");

        device->seek(0);
        QCOMPARE(device->peek(4), QByteArray("ZXCV"));
        QCOMPARE(device->pos(), qint64(0));
        device->write("ABCDE");
        device->seek(3);
        QCOMPARE(device->peek(1), QByteArray("D"));
        QCOMPARE(device->peek(5), QByteArray("DE"));
        device->seek(0);
        QCOMPARE(device->read(4), QByteArray("ABCD"));
        QCOMPARE(device->pos(), qint64(4));

        device->seek(0);
        device->write("ZXCV");
        device->seek(0);
        char buf[5];
        buf[4] = 0;
        device->peek(buf, 4);
        QCOMPARE(static_cast<const char *>(buf), "ZXCV");
        QCOMPARE(device->pos(), qint64(0));
        device->read(buf, 4);
        QCOMPARE(static_cast<const char *>(buf), "ZXCV");
        QCOMPARE(device->pos(), qint64(4));
    }
    QFile::remove("peektestfile");
}
예제 #6
0
void tst_QIODevice::peekAndRead()
{
    QByteArray originalData;
    for (int i=0; i<1000; i++)
        originalData += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    QBuffer buffer;
    QFile::remove("peektestfile");
    QFile file("peektestfile");

    for (int i = 0; i < 2; ++i) {
        QByteArray readData;
        QIODevice *device = i ? (QIODevice *)&file : (QIODevice *)&buffer;
        device->open(QBuffer::ReadWrite);
        device->write(originalData);
        device->seek(0);
        while (!device->atEnd()) {
            char peekIn[26];
            device->peek(peekIn, 26);
            readData += device->read(26);
        }
        QCOMPARE(readData, originalData);
    }
    QFile::remove("peektestfile");
}
예제 #7
0
//--------------------------------------------------------------------
void tst_QIODevice::unget()
{
#if defined(Q_OS_WINCE) && defined(WINCE_EMULATOR_TEST)
    QSKIP("Networking tests in a WinCE emulator are unstable", SkipAll);
#endif
    QBuffer buffer;
    buffer.open(QBuffer::ReadWrite);
    buffer.write("ZXCV");
    buffer.seek(0);
    QCOMPARE(buffer.read(4), QByteArray("ZXCV"));
    QCOMPARE(buffer.pos(), qint64(4));

    buffer.ungetChar('a');
    buffer.ungetChar('b');
    buffer.ungetChar('c');
    buffer.ungetChar('d');

    QCOMPARE(buffer.pos(), qint64(0));

    char buf[6];
    QCOMPARE(buffer.readLine(buf, 5), qint64(4));
    QCOMPARE(buffer.pos(), qint64(4));
    QCOMPARE(static_cast<const char*>(buf), "dcba");

    buffer.ungetChar('a');
    buffer.ungetChar('b');
    buffer.ungetChar('c');
    buffer.ungetChar('d');

    QCOMPARE(buffer.pos(), qint64(0));

    for (int i = 0; i < 5; ++i) {
        buf[0] = '@';
        buf[1] = '@';
        QTest::ignoreMessage(QtWarningMsg,
                             "QIODevice::readLine: Called with maxSize < 2");
        QCOMPARE(buffer.readLine(buf, 1), qint64(-1));
        QCOMPARE(buffer.readLine(buf, 2), qint64(i < 4 ? 1 : -1));
        switch (i) {
        case 0:
            QCOMPARE(buf[0], 'd');
            break;
        case 1:
            QCOMPARE(buf[0], 'c');
            break;
        case 2:
            QCOMPARE(buf[0], 'b');
            break;
        case 3:
            QCOMPARE(buf[0], 'a');
            break;
        case 4:
            QCOMPARE(buf[0], '\0');
            break;
        }
        QCOMPARE(buf[1], i < 4 ? '\0' : '@');
    }

    buffer.ungetChar('\n');
    QCOMPARE(buffer.readLine(), QByteArray("\n"));

    buffer.seek(1);
    buffer.readLine(buf, 3);
    QCOMPARE(static_cast<const char*>(buf), "XC");

    buffer.seek(4);
    buffer.ungetChar('Q');
    QCOMPARE(buffer.readLine(buf, 3), qint64(1));

    for (int i = 0; i < 2; ++i) {
        QTcpSocket socket;
        QIODevice *dev;
        QByteArray result;
        const char *lineResult;
        if (i == 0) {
            dev = &buffer;
            result = QByteArray("ZXCV");
            lineResult = "ZXCV";
        } else {
            socket.connectToHost(QtNetworkSettings::serverName(), 80);
            socket.write("GET / HTTP/1.0\r\n\r\n");
            QVERIFY(socket.waitForReadyRead());
            dev = &socket;
            result = QByteArray("HTTP");
            lineResult = "Date";
        }
        char ch, ch2;
        dev->seek(0);
        dev->getChar(&ch);
        dev->ungetChar(ch);
        QCOMPARE(dev->peek(4), result);
        dev->getChar(&ch);
        dev->getChar(&ch2);
        dev->ungetChar(ch2);
        dev->ungetChar(ch);
        QCOMPARE(dev->read(1), result.left(1));
        QCOMPARE(dev->read(3), result.right(3));

        if (i == 0)
            dev->seek(0);
        else
            dev->readLine();
        dev->getChar(&ch);
        dev->ungetChar(ch);
        dev->readLine(buf, 5);
        QCOMPARE(static_cast<const char*>(buf), lineResult);

        if (i == 1)
            socket.close();
    }
}
int TAbstractWebSocket::parse(QByteArray &recvData)
{
    tSystemDebug("parse enter  data len:%d  sid:%d", recvData.length(), socketId());
    if (websocketFrames().isEmpty()) {
        websocketFrames().append(TWebSocketFrame());
    } else {
        const TWebSocketFrame &f = websocketFrames().last();
        if (f.state() == TWebSocketFrame::Completed) {
            websocketFrames().append(TWebSocketFrame());
        }
    }

    TWebSocketFrame *pfrm = &websocketFrames().last();
    quint8  b;
    quint16 w;
    quint32 n;
    quint64 d;

    QDataStream ds(recvData);
    ds.setByteOrder(QDataStream::BigEndian);
    QIODevice *dev = ds.device();
    QByteArray hdr;

    while (!ds.atEnd()) {
        switch (pfrm->state()) {
        case TWebSocketFrame::Empty: {
            hdr = dev->peek(14);
            QDataStream dshdr(hdr);
            dshdr.setByteOrder(QDataStream::BigEndian);
            QIODevice *devhdr = dshdr.device();

            if (Q_UNLIKELY(devhdr->bytesAvailable() < 2)) {
                goto parse_end;
            }

            dshdr >> b;
            pfrm->setFirstByte(b);
            dshdr >> b;
            bool maskFlag = b & 0x80;
            quint8 len = b & 0x7f;

            // payload length
            switch (len) {
            case 126:
                if (Q_UNLIKELY(devhdr->bytesAvailable() < (int)sizeof(w))) {
                    goto parse_end;
                }
                dshdr >> w;
                if (Q_UNLIKELY(w < 126)) {
                    tSystemError("WebSocket protocol error  [%s:%d]", __FILE__, __LINE__);
                    return -1;
                }
                pfrm->setPayloadLength( w );
                break;

            case 127:
                if (Q_UNLIKELY(devhdr->bytesAvailable() < (int)sizeof(d))) {
                    goto parse_end;
                }
                dshdr >> d;
                if (Q_UNLIKELY(d <= 0xFFFF)) {
                    tSystemError("WebSocket protocol error  [%s:%d]", __FILE__, __LINE__);
                    return -1;
                }
                pfrm->setPayloadLength( d );
                break;

            default:
                pfrm->setPayloadLength( len );
                break;
            }

            // Mask key
            if (maskFlag) {
                if (Q_UNLIKELY(devhdr->bytesAvailable() < (int)sizeof(n))) {
                    goto parse_end;
                }
                dshdr >> n;
                pfrm->setMaskKey( n );
            }

            if (pfrm->payloadLength() == 0) {
                pfrm->setState(TWebSocketFrame::Completed);
            } else {
                pfrm->setState(TWebSocketFrame::HeaderParsed);
                if (pfrm->payloadLength() >= 2 * 1024 * 1024 * 1024ULL) {
                    tSystemError("Too big frame  [%s:%d]", __FILE__, __LINE__);
                    pfrm->clear();
                } else {
                    pfrm->payload().reserve(pfrm->payloadLength());
                }
            }

            tSystemDebug("WebSocket parse header pos: %lld", devhdr->pos());
            tSystemDebug("WebSocket payload length:%lld", pfrm->payloadLength());

            int hdrlen = hdr.length() - devhdr->bytesAvailable();
            ds.skipRawData(hdrlen);  // Forwards the pos
            break; }

        case TWebSocketFrame::HeaderParsed:  // fall through
        case TWebSocketFrame::MoreData: {
            tSystemDebug("WebSocket reading payload:  available length:%lld", dev->bytesAvailable());
            tSystemDebug("WebSocket parsing  length to read:%llu  current buf len:%d", pfrm->payloadLength(), pfrm->payload().size());
            quint64 size = qMin((pfrm->payloadLength() - pfrm->payload().size()), (quint64)dev->bytesAvailable());
            if (Q_UNLIKELY(size == 0)) {
                Q_ASSERT(0);
                break;
            }

            char *p = pfrm->payload().data() + pfrm->payload().size();
            size = ds.readRawData(p, size);

            if (pfrm->maskKey()) {
                // Unmask
                const quint8 mask[4] = { quint8((pfrm->maskKey() & 0xFF000000) >> 24),
                                         quint8((pfrm->maskKey() & 0x00FF0000) >> 16),
                                         quint8((pfrm->maskKey() & 0x0000FF00) >> 8),
                                         quint8((pfrm->maskKey() & 0x000000FF)) };

                int i = pfrm->payload().size();
                const char *end = p + size;
                while (p < end) {
                    *p++ ^= mask[i++ % 4];
                }
            }
            pfrm->payload().resize( pfrm->payload().size() + size );
            tSystemDebug("WebSocket payload curent buf len: %d", pfrm->payload().length());

            if ((quint64)pfrm->payload().size() == pfrm->payloadLength()) {
                pfrm->setState(TWebSocketFrame::Completed);
                tSystemDebug("Parse Completed   payload len: %d", pfrm->payload().size());
            } else {
                pfrm->setState(TWebSocketFrame::MoreData);
                tSystemDebug("Parse MoreData   payload len: %d", pfrm->payload().size());
            }
            break; }

        case TWebSocketFrame::Completed:  // fall through
        default:
            Q_ASSERT(0);
            break;
        }

        if (pfrm->state() == TWebSocketFrame::Completed) {
            if (Q_UNLIKELY(!pfrm->validate())) {
                pfrm->clear();
                continue;
            }

            // Fragmented message validation
            if (pfrm->opCode() == TWebSocketFrame::Continuation) {
                if (websocketFrames().count() >= 2) {
                    const TWebSocketFrame &before = websocketFrames()[websocketFrames().count() - 2];
                    if (before.isFinalFrame() || before.isControlFrame()) {
                        pfrm->clear();
                        tSystemWarn("Invalid continuation frame detected  [%s:%d]", __FILE__, __LINE__);
                        continue;
                    }
                }
            }

            // In case of control frame, moves forward after previous control frames
            if (pfrm->isControlFrame()) {
                if (websocketFrames().count() >= 2) {
                    TWebSocketFrame frm = websocketFrames().takeLast();
                    QMutableListIterator<TWebSocketFrame> it(websocketFrames());
                    while (it.hasNext()) {
                        TWebSocketFrame &f = it.next();
                        if (!f.isControlFrame()) {
                            break;
                        }
                    }

                    it.insert(frm);
                }
            }

            if (!ds.atEnd()) {
                // Prepare next frame
                websocketFrames().append(TWebSocketFrame());
                pfrm = &websocketFrames().last();
            } else {
                break;
            }
        }
    }

parse_end:
    int parsedlen = recvData.size() - dev->bytesAvailable();
    recvData.remove(0, parsedlen);
    return parsedlen;
}
예제 #9
0
/**
 * Verifies contents of specified archive against test fileset
 * @param archive archive
 */
static void testFileData(KArchive *archive)
{
    const KArchiveDirectory *dir = archive->directory();

    const KArchiveFile *f = dir->file(QStringLiteral("z/test3"));
    QByteArray arr(f->data());
    QCOMPARE(arr.size(), 13);
    QCOMPARE(arr, QByteArray("Noch so einer"));

    // Now test using createDevice()
    QIODevice *dev = f->createDevice();
    QByteArray contents = dev->readAll();
    QCOMPARE(contents, arr);
    delete dev;

    dev = f->createDevice();
    contents = dev->read(5); // test reading in two chunks
    QCOMPARE(contents.size(), 5);
    contents += dev->read(50);
    QCOMPARE(contents.size(), 13);
    QCOMPARE(QString::fromLatin1(contents.constData()), QString::fromLatin1(arr.constData()));
    delete dev;

    // test read/seek/peek work fine
    f = dir->file(QStringLiteral("test1"));
    dev = f->createDevice();
    contents = dev->peek(4);
    QCOMPARE(contents, QByteArray("Hall"));
    contents = dev->peek(2);
    QCOMPARE(contents, QByteArray("Ha"));
    dev->seek(2);
    contents = dev->peek(2);
    QCOMPARE(contents, QByteArray("ll"));
    dev->seek(0);
    contents = dev->read(2);
    QCOMPARE(contents, QByteArray("Ha"));
    contents = dev->peek(2);
    QCOMPARE(contents, QByteArray("ll"));
    dev->seek(1);
    contents = dev->read(1);
    QCOMPARE(contents, QByteArray("a"));
    dev->seek(4);
    contents = dev->read(1);
    QCOMPARE(contents, QByteArray("o"));

    const KArchiveEntry *e = dir->entry(QStringLiteral("mediumfile"));
    QVERIFY(e && e->isFile());
    f = (KArchiveFile *)e;
    QCOMPARE(f->data().size(), SIZE1);

    f = dir->file(QStringLiteral("hugefile"));
    QCOMPARE(f->data().size(), 20000);

    e = dir->entry(QStringLiteral("aaaemptydir"));
    QVERIFY(e && e->isDirectory());
    QVERIFY(!dir->file("aaaemptydir"));

    e = dir->entry(QStringLiteral("my/dir/test3"));
    QVERIFY(e && e->isFile());
    f = (KArchiveFile *)e;
    dev = f->createDevice();
    QByteArray firstLine = dev->readLine();
    QCOMPARE(QString::fromLatin1(firstLine.constData()), QString::fromLatin1("I do not speak German\n"));
    QByteArray secondLine = dev->read(100);
    QCOMPARE(QString::fromLatin1(secondLine.constData()), QString::fromLatin1("David."));
    delete dev;
#ifndef Q_OS_WIN
    e = dir->entry(QStringLiteral("z/test3_symlink"));
    QVERIFY(e);
    QVERIFY(e->isFile());
    QCOMPARE(e->symLinkTarget(), QString("test3"));
#endif

    // Test "./" prefix for KOffice (xlink:href="./ObjectReplacements/Object 1")
    e = dir->entry(QStringLiteral("./hugefile"));
    QVERIFY(e && e->isFile());
    e = dir->entry(QStringLiteral("./my/dir/test3"));
    QVERIFY(e && e->isFile());

    // Test directory entries
    e = dir->entry(QStringLiteral("my"));
    QVERIFY(e && e->isDirectory());
    e = dir->entry(QStringLiteral("my/"));
    QVERIFY(e && e->isDirectory());
    e = dir->entry(QStringLiteral("./my/"));
    QVERIFY(e && e->isDirectory());
}