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; }
/** 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)); }
/** * @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); }
//-------------------------------------------------------------------- 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"); }
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"); }
//-------------------------------------------------------------------- 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; }
/** * 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()); }