void HciManager::handleLeMetaEvent(const quint8 *data) { // Spec v4.2, Vol 2, part E, 7.7.65ff switch (*data) { case 0x1: { const quint16 handle = bt_get_le16(data + 2); emit connectionComplete(handle); break; } case 0x3: { // TODO: From little endian! struct ConnectionUpdateData { quint8 status; quint16 handle; quint16 interval; quint16 latency; quint16 timeout; } __attribute((packed)); const auto * const updateData = reinterpret_cast<const ConnectionUpdateData *>(data + 1); if (updateData->status == 0) { QLowEnergyConnectionParameters params; const double interval = qFromLittleEndian(updateData->interval) * 1.25; params.setIntervalRange(interval, interval); params.setLatency(qFromLittleEndian(updateData->latency)); params.setSupervisionTimeout(qFromLittleEndian(updateData->timeout) * 10); emit connectionUpdate(qFromLittleEndian(updateData->handle), params); } break; } default: break; } }
int Value::usedStorage(const Base *b) const { int s = 0; switch (type) { case QJsonValue::Double: if (latinOrIntValue) break; s = sizeof(double); break; case QJsonValue::String: { char *d = data(b); if (latinOrIntValue) s = sizeof(ushort) + qFromLittleEndian(*(ushort *)d); else s = sizeof(int) + sizeof(ushort) * qFromLittleEndian(*(int *)d); break; } case QJsonValue::Array: case QJsonValue::Object: s = base(b)->size; break; case QJsonValue::Null: case QJsonValue::Bool: default: break; } return alignedSize(s); }
void PacketDecodeNode::processByteArray( QByteArray A ) { if( A.size() < sizeof( PktHdr ) ) { return; } PktHdr PacketHeader; memcpy( &PacketHeader, A.constData(), sizeof( PacketHeader ) ); PacketHeader.mLength = qFromLittleEndian( PacketHeader.mLength ); if( PacketHeader.mLength != A.size() ) { return; } PacketHeader.mCRC = qFromLittleEndian( PacketHeader.mCRC ); memset( A.data() + offsetof( PktHdr, mCRC ), 0, sizeof( quint32 ) ); quint32 CRC = CRC32::crc32( A ); if( CRC != PacketHeader.mCRC ) { return; } if( PacketHeader.mLength > sizeof( PacketHeader ) ) { mValOutputData->variantAppend( A.mid( sizeof( PacketHeader ) ) ); } }
void HciManager::handleHciAclPacket(const quint8 *data, int size) { if (size < int(sizeof(AclData))) { qCWarning(QT_BT_BLUEZ) << "Unexpected HCI ACL packet size"; return; } quint16 rawAclData[sizeof(AclData) / sizeof(quint16)]; rawAclData[0] = bt_get_le16(data); rawAclData[1] = bt_get_le16(data + sizeof(quint16)); const AclData *aclData = reinterpret_cast<AclData *>(rawAclData); data += sizeof *aclData; size -= sizeof *aclData; // Consider only directed, complete messages. if ((aclData->pbFlag != 0 && aclData->pbFlag != 2) || aclData->bcFlag != 0) return; if (size < aclData->dataLen) { qCWarning(QT_BT_BLUEZ) << "HCI ACL packet data size" << size << "is smaller than specified size" << aclData->dataLen; return; } // qCDebug(QT_BT_BLUEZ) << "handle:" << aclData->handle << "PB:" << aclData->pbFlag // << "BC:" << aclData->bcFlag << "data len:" << aclData->dataLen; if (size < int(sizeof(L2CapHeader))) { qCWarning(QT_BT_BLUEZ) << "Unexpected HCI ACL packet size"; return; } L2CapHeader l2CapHeader = *reinterpret_cast<const L2CapHeader*>(data); l2CapHeader.channelId = qFromLittleEndian(l2CapHeader.channelId); l2CapHeader.length = qFromLittleEndian(l2CapHeader.length); data += sizeof l2CapHeader; size -= sizeof l2CapHeader; if (size < l2CapHeader.length) { qCWarning(QT_BT_BLUEZ) << "L2Cap payload size" << size << "is smaller than specified size" << l2CapHeader.length; return; } // qCDebug(QT_BT_BLUEZ) << "l2cap channel id:" << l2CapHeader.channelId // << "payload length:" << l2CapHeader.length; if (l2CapHeader.channelId != SECURITY_CHANNEL_ID) return; if (*data != 0xa) // "Signing Information". Spec v4.2, Vol 3, Part H, 3.6.6 return; if (size != 17) { qCWarning(QT_BT_BLUEZ) << "Unexpected key size" << size << "in Signing Information packet"; return; } quint128 csrk; memcpy(&csrk, data + 1, sizeof csrk); const bool isRemoteKey = aclData->pbFlag == 2; emit signatureResolvingKeyReceived(aclData->handle, isRemoteKey, csrk); }
MachineType machineType() { int32_t peOffset = qFromLittleEndian(* reinterpret_cast<int32_t*>(m_map + 0x3C)); uchar* peSignature = m_map + peOffset; if (memcmp(peSignature, "PE\0\0", 4)) { throw std::runtime_error("Invalid PE file"); } uchar * coffHeader = peSignature + 4; uint16_t machineType = qFromLittleEndian(* reinterpret_cast<uint16_t*>(coffHeader)); return static_cast<MachineType>(machineType); }
quint32 getUnsignedDWord(const void *src) { quint32 result = 0; memcpy(reinterpret_cast<void *>(&result), src, 4); result = qFromLittleEndian(result); return result; }
qint64 getSignedQWord(const void *src) { qint64 result = 0; memcpy(reinterpret_cast<void *>(&result), src, 8); result = qFromLittleEndian(result); return result; }
qint64 StateImport::loadCTM5(State *state, QFile& file, struct CTMHeader5* v5header) { if (v5header->flags & 03) { state->setErrorMessage(QObject::tr("Error: CTM is not expanded")); qDebug() << "CTM is not expanded. Cannot load it"; return -1; } int num_chars = qFromLittleEndian(v5header->num_chars); int toRead = std::min(num_chars * 8, State::CHAR_BUFFER_SIZE); // clean previous memory in case not all the chars are loaded state->resetCharsetBuffer(); auto total = file.read((char*)state->getCharsetBuffer(), toRead); for (int i=0; i<4; i++) state->setColorForPen(i, v5header->colors[i]); state->setMulticolorMode(v5header->flags & 0b00000100); State::TileProperties tp; tp.interleaved = 1; // some files reports size == 0. Bug in CTMv5? tp.size.setWidth(qMax((int)v5header->tile_width,1)); tp.size.setHeight(qMax((int)v5header->tile_height,1)); state->setTileProperties(tp); return total; }
CacheEntry MemcachedCache::value(const QString& key) const { QReadLocker lock(&m_lock); const QByteArray rawKey(fullKey(key)); char* rawData; size_t rawDataLength; uint32_t flags; memcached_return rt; rawData = memcached_get( m_memcached, rawKey.constData(), rawKey.length(), &rawDataLength, &flags, &rt ); if(rt != MEMCACHED_SUCCESS && rt != MEMCACHED_NOTFOUND) { qFatal("Memcached error: %s", memcached_strerror(m_memcached, rt)); } Q_ASSERT(rawDataLength >= sizeof(quint64) || !rawData); if(rawDataLength < sizeof(quint64) || !rawData) { return CacheEntry(); } const quint64 timeStamp = qFromLittleEndian(*reinterpret_cast<quint64*>(rawData)); const QByteArray data(rawData + sizeof(quint64), rawDataLength - sizeof(quint64)); return CacheEntry(QDateTime::fromTime_t(timeStamp), data); }
int Sample::toInt() const { if (signal->sampleSize() == 1) { if (signal->getFormat().sampleType() == QAudioFormat::SignedInt) { return constSampleData[0]; } else { return static_cast<unsigned char>(sampleData[0]); } } else if (signal->sampleSize() == 2) { if (signal->getFormat().sampleType() == QAudioFormat::SignedInt) { const short* val = reinterpret_cast<const short*>(constSampleData); if (signal->getFormat().byteOrder() == QAudioFormat::LittleEndian) { return qFromLittleEndian(*val); } else { return qFromBigEndian(*val); } } else { const unsigned short* val = reinterpret_cast<const unsigned short*>(sampleData); if (signal->getFormat().byteOrder() == QAudioFormat::LittleEndian) { return qFromLittleEndian(*val); } else { return qFromBigEndian(*val); } } } else { throw Signal::SampleSizeUnset(); } }
quint32 PeerToPeerPacket::requiredLen(const QByteArray &p_data) { // Return the minimum length (to have the actual length) if(p_data.length() < 4) return 4; // Return the length as the header states (first two bytes) return qFromLittleEndian(*(reinterpret_cast<const quint32*>(p_data.constData()))); }
qint32 readSignedDWord(QIODevice &device) { qint32 result = 0; if (device.read(reinterpret_cast<char *> (&result), Q_INT64_C(4)) != Q_INT64_C(4)) { throw std::runtime_error("Unable to read file"); } result = qFromLittleEndian(result); return result; }
void Transfer::onReadyRead() { // Add all of the new data to the buffer mBuffer.append(mSocket->readAll()); // Process as many packets as can be read from the buffer forever { // If the transfer is finished, ignore any packets being received if (mProtocolState == ProtocolState::Finished) { break; } // If the size of the packet is not yet known attempt to read it if (!mBufferSize) { // See if there is enough data in the buffer to read the size if (static_cast<size_t>(mBuffer.size()) >= sizeof(mBufferSize)) { // memcpy must be used in order to avoid alignment issues // Also, the integer uses little endian byte order // so convert it to the host format if necessary memcpy(&mBufferSize, mBuffer.constData(), sizeof(mBufferSize)); mBufferSize = qFromLittleEndian(mBufferSize); mBuffer.remove(0, sizeof(mBufferSize)); // A packet size of zero is an error if (!mBufferSize) { writeErrorPacket(tr("Empty packet received")); break; } } else { break; } } // If the buffer contains enough data to read the packet, then do so if (mBuffer.size() >= mBufferSize) { processPacket(); } else { break; } } }
qint64 StateImport::loadVChar64(State *state, QFile& file) { struct VChar64Header header; auto size = file.size(); if ((std::size_t)size<sizeof(header)) { state->setErrorMessage(QObject::tr("Error: Invalid VChar file")); qDebug() << "Error. File size too small to be VChar64 (" << size << ")."; return -1; } size = file.read((char*)&header, sizeof(header)); if ((std::size_t)size<sizeof(header)) return -1; // check header if (header.id[0] != 'V' || header.id[1] != 'C' || header.id[2] != 'h' || header.id[3] != 'a' || header.id[4] != 'r') { state->setErrorMessage(QObject::tr("Error: Invalid VChar file")); qDebug() << "Not a valid VChar64 file"; return -1; } int num_chars = qFromLittleEndian((int)header.num_chars); int toRead = std::min(num_chars * 8, State::CHAR_BUFFER_SIZE); // clean previous memory in case not all the chars are loaded state->resetCharsetBuffer(); auto total = file.read((char*)state->getCharsetBuffer(), toRead); for (int i=0; i<4; i++) state->setColorForPen(i, header.colors[i]); state->setMulticolorMode(header.vic_res); State::TileProperties properties; properties.size = {header.tile_width, header.tile_height}; properties.interleaved = header.char_interleaved; state->setTileProperties(properties); return total; }
qint64 StateImport::loadPRG(State *state, QFile& file, quint16* outAddress) { auto size = file.size(); if (size < 10) { // 2 + 8 (at least one char) state->setErrorMessage(QObject::tr("Error: File size too small")); qDebug() << "Error: File Size too small."; return -1; } // ignore first 2 bytes quint16 address; file.read((char*)&address, 2); if (outAddress) { *outAddress = qFromLittleEndian(address); } return StateImport::loadRaw(state, file); }
void ARControlConnection::onNavdata(const ARControlFrame &frame) { Q_D(ARControlConnection); // TODO: Should we do this, or should we allow application to decide // when/if an acknowledge occurs? // Construct acknowledge frame, if this incoming frame requires it. if(frame.type == ARControlConnection::AcknowledgeData) { QByteArray payload(1, 0x00); QDataStream datastream(&payload, QIODevice::WriteOnly); datastream.setByteOrder(QDataStream::LittleEndian); datastream << (quint8)frame.seq; sendFrame(ARControlConnection::Acknowledge, ARNET_C2D_NAVDATA_ACK_ID, payload.constData(), payload.size()); } // Decode command header. quint8 project = static_cast<quint8>(frame.payload[0]); quint8 klass = static_cast<quint8>(frame.payload[1]); quint16 id = qFromLittleEndian(static_cast<quint16>(frame.payload[2])); const char *data = frame.payload.data() + 4; // Resolve command meta-type information. ARCommandInfo *command = d->commands->find(project, klass, id); if(command == NULL) { WARNING_T(QString("Unrecognised command: %1 %2 %3") .arg(project) .arg(klass) .arg(id)); return; } // Use command codec to decode command parameters. QVariantMap params = d->codec->decode(command, data); DEBUG_T(QString("Decoded Command %1 %2 %3").arg(command->klass->project).arg(command->klass->name).arg(command->name)); d->controller->onCommandReceived(*command, params); }
qint64 StateImport::loadCTM4(State *state, QFile& file, struct CTMHeader4* v4header) { // only expanded files are supported if (!v4header->expanded) { state->setErrorMessage(QObject::tr("Error: CTM is not expanded")); qDebug() << "CTM is not expanded. Cannot load it"; return -1; } // only 20 bytes were read, but v4 headers has 24 bytes. // but the 4 remaing bytes are not important. char ignore[4]; file.read(ignore, sizeof(ignore)); int num_chars = qFromLittleEndian(v4header->num_chars); int toRead = std::min(num_chars * 8, State::CHAR_BUFFER_SIZE); // clean previous memory in case not all the chars are loaded state->resetCharsetBuffer(); auto total = file.read((char*)state->getCharsetBuffer(), toRead); for (int i=0; i<4; i++) state->setColorForPen(i, v4header->colors[i]); state->setMulticolorMode(v4header->vic_res); State::TileProperties tp; tp.interleaved = 1; tp.size.setWidth(v4header->tile_width); tp.size.setHeight(v4header->tile_height); state->setTileProperties(tp); return total; }
PeerToPeerPacket *PeerToPeerPacket::parseData(const QByteArray &p_data) { // Return an invalid packet, if there is not even a complete header if(p_data.length() < XFIRE_HEADER_LEN_P2P) return 0; quint32 offset = 0; // Packet length quint32 len = requiredLen(p_data); offset += 4; // Return an invalid packet, if there is not enough data available if((len < XFIRE_HEADER_LEN_P2P) || (p_data.length() < len)) return 0; // Packet id quint16 id = qFromLittleEndian(*(reinterpret_cast<const quint16*>(p_data.constData() + offset))); offset += 2; // Attribute count quint8 attr_count = *(reinterpret_cast<const quint8*>(p_data.constData() + offset)); offset += 1; PeerToPeerPacket *ret = new PeerToPeerPacket(id); static const quint16 stringPackets[] = { 0x3E87, 0x3E88, 0x3E89, 0x3E8A, 0x3E8B, 0x3E8C, 0x3E8D, 0x3E8E, 0x0000 }; bool uses_strings = false; int i = 0; while(stringPackets[i] != 0x0000) { if(stringPackets[i] == id) { uses_strings = true; break; } i++; } for(i = 0; i < attr_count; i++) { Attribute *attr = uses_strings ? Attribute::parseAttributeString(p_data, offset, len) : Attribute::parseAttributeByte(p_data, offset, len); // Return an invalid packet, if at least one attribute parsing failed if(!attr || !attr->isValid()) { if(attr) delete attr; delete ret; return 0; } ret->m_attributes.append(attr); } // Return an invalid packet, if the size did not match the attributes if(offset != len) { delete ret; return 0; } return ret; }
void ARControlConnection::onVideoData(const ARControlFrame &frame) { TRACE Q_D(ARControlConnection); quint16 frameNumber = qFromLittleEndian(*((quint16*)(frame.payload.constData()))); quint8 frameFlags = static_cast<quint8>(frame.payload[2]); quint8 fragmentNumber = static_cast<quint8>(frame.payload[3]); quint8 fragsPerFrame = static_cast<quint8>(frame.payload[4]); if(frameNumber != d->frameNumber) { if(frameFlags == 0x01) { DEBUG_T(QString("Video Key Frame Header [%1] (%2 %3 %4)") .arg(QString(QByteArray().append(frame.payload.constData(), 5).toHex())) .arg(frameNumber) .arg(fragmentNumber) .arg(fragsPerFrame)); } else { DEBUG_T(QString("Video Frame Header (%2 %3 %4)") .arg(frameNumber) .arg(fragmentNumber) .arg(fragsPerFrame)); } if(fragsPerFrame < 64) { d->hiAck = 0xffffffffffffffff; d->loAck = 0xffffffffffffffff << fragsPerFrame; } else if(fragsPerFrame < 128) { d->hiAck = 0xffffffffffffffff << (fragsPerFrame - 64); d->loAck = 0ll; } else { d->hiAck = 0ll; d->loAck = 0ll; } d->frameNumber = frameNumber; } if(fragmentNumber < 64) { d->loAck |= (1ll << fragmentNumber); } else if(fragmentNumber < 128) { d->hiAck |= (1ll << (fragmentNumber - 64)); } // Construct reply. QByteArray payload(2 + 8 + 8, 0x00); QDataStream datastream(&payload, QIODevice::WriteOnly); if(!d->sequenceIds.contains(ARNET_C2D_VIDEO_ACK_ID)) d->sequenceIds.insert(ARNET_C2D_VIDEO_ACK_ID, 0x00); datastream.setByteOrder(QDataStream::LittleEndian); datastream << (quint16)frameNumber << (quint64)d->hiAck << (quint64)d->loAck; sendFrame(ARControlConnection::LowLatencyData, ARNET_C2D_VIDEO_ACK_ID, payload.constData(), payload.size()); }
void ARControlConnection::onReadyRead() { Q_D(ARControlConnection); while(d->d2c->hasPendingDatagrams()) { QHostAddress remoteAddr; quint16 remotePort; // If we've not received enough data, then return and wait for more. if(d->d2c->pendingDatagramSize() < ARNETWORK_FRAME_HEADER_SIZE) break; QByteArray datagram(d->d2c->pendingDatagramSize(), 0x00); quint32 offset = 0; d->d2c->readDatagram(datagram.data(), datagram.size(), &remoteAddr, &remotePort); while(offset < datagram.size()) { ARControlFrame frame; frame.type = static_cast<quint8>(datagram[offset + 0]); frame.id = static_cast<quint8>(datagram[offset + 1]); frame.seq = static_cast<quint8>(datagram[offset + 2]); frame.size = qFromLittleEndian(*((quint32*)(datagram.constData() + offset + 3))); // Copy datagram data to frame if the frame size is larger than just the header. if(frame.size > ARNETWORK_FRAME_HEADER_SIZE) { const char *data = datagram.constData(); frame.payload.insert(0, data + offset + ARNETWORK_FRAME_HEADER_SIZE, frame.size - ARNETWORK_FRAME_HEADER_SIZE); } // Output comms debug info (if it's not a video data frame). if(frame.id != ARNET_D2C_VIDEO_DATA_ID) { DEBUG_T(QString("<< %1:%2 [%3]") .arg(remoteAddr.toString()) .arg(remotePort) .arg(QString(datagram.toHex()))); } // Process frame depending on buffer id. if(frame.id == ARNET_D2C_PING_ID) { onPing(frame); } else if(frame.id == ARNET_D2C_EVENT_ID || frame.id == ARNET_D2C_NAVDATA_ID) { onNavdata(frame); } else if(frame.id == ARNET_D2C_VIDEO_DATA_ID) { onVideoData(frame); } else { WARNING_T(QString("Unhandled frame id: %1").arg(frame.id)); } // Increment datagram offset to continue processing next frame. offset += frame.size; } } }
qint64 StateImport::parseVICESnapshot(QFile& file, quint8* buffer64k) { struct VICESnapshotHeader header; struct VICESnapshoptModule module; struct VICESnapshoptC64Mem c64mem; static const char VICE_MAGIC[] = "VICE Snapshot File\032"; static const char VICE_C64MEM[] = "C64MEM"; auto state = State::getInstance(); if (!file.isOpen()) file.open(QIODevice::ReadOnly); auto size = file.size(); if (size < (qint64)sizeof(VICESnapshotHeader)) { state->setErrorMessage(QObject::tr("Error: VICE file too small")); return -1; } file.seek(0); size = file.read((char*)&header, sizeof(header)); if (size != sizeof(header)) { state->setErrorMessage(QObject::tr("Error: VICE header too small")); return -1; } if (memcmp(header.id, VICE_MAGIC, sizeof(header.id)) != 0) { state->setErrorMessage(QObject::tr("Error: Invalid VICE header Id")); return -1; } int offset = file.pos(); bool found = false; while (1) { size = file.read((char*)&module, sizeof(module)); if (size != sizeof(module)) break; /* Found? */ if (memcmp(module.moduleName, VICE_C64MEM, sizeof(VICE_C64MEM)) == 0 && module.major == 0) { found = true; break; } offset += qFromLittleEndian(module.lenght); if (!file.seek(offset)) break; } if (found) { size = file.read((char*)&c64mem, sizeof(c64mem)); if (size != sizeof(c64mem)) { state->setErrorMessage(QObject::tr("Error: Invalid VICE C64MEM segment")); return -1; } memcpy(buffer64k, c64mem.ram, sizeof(c64mem.ram)); } else { state->setErrorMessage(QObject::tr("Error: VICE C64MEM segment not found")); return -1; } return 0; }
CQueryHit* CQueryHit::ReadPacket(G2Packet *pPacket, QSharedPointer<QueryHitInfo> pHitInfo) { if( !pPacket->m_bCompound ) return 0; pPacket->m_nPosition = 0; // reset packet position bool bHaveHits = false; bool bFirstHit = true; CQueryHit* pThisHit = new CQueryHit(); try { char szType[9], szTypeX[9]; quint32 nLength = 0, nLengthX = 0, nNext = 0, nNextX = 0; bool bCompound = false; while( pPacket->ReadPacket(&szType[0], nLength, &bCompound) ) { nNext = pPacket->m_nPosition + nLength; if( strcmp("H", szType) == 0 && bCompound ) { CQueryHit* pHit = (bFirstHit ? pThisHit : new CQueryHit()); if( !bFirstHit ) { CQueryHit* pPrevHit = pThisHit; while( pPrevHit->m_pNext != 0 ) { pPrevHit = pPrevHit->m_pNext; } pPrevHit->m_pNext = pHit; } bool bHaveSize = false; QByteArray baTemp; bool bHaveDN = false; bool bHaveURN = false; while( pPacket->m_nPosition < nNext && pPacket->ReadPacket(&szTypeX[0], nLengthX)) { nNextX = pPacket->m_nPosition + nLengthX; if( strcmp("URN", szTypeX) == 0 ) { QString sURN; char hashBuff[256]; sURN = pPacket->ReadString(); if( nLengthX >= 44u && sURN.compare("bp") == 0 ) { pPacket->Read(&hashBuff[0], CSHA1::ByteCount()); if( pHit->m_oSha1.FromRawData(&hashBuff[0], CSHA1::ByteCount()) ) { bHaveURN = true; } else { pHit->m_oSha1.Clear(); } } else if( nLengthX >= CSHA1::ByteCount() + 5u && sURN.compare("sha1") == 0 ) { pPacket->Read(&hashBuff[0], CSHA1::ByteCount()); if( pHit->m_oSha1.FromRawData(&hashBuff[0], CSHA1::ByteCount()) ) { bHaveURN = true; } else { pHit->m_oSha1.Clear(); } } } else if( strcmp("URL", szTypeX) == 0 && nLengthX ) { // if url empty - try uri-res resolver or a node do not have this object // bez sensu... pHit->m_sURL = pPacket->ReadString(); } else if( strcmp("DN", szTypeX) == 0 ) { if( bHaveSize ) { pHit->m_sDescriptiveName = pPacket->ReadString(nLengthX); } else if( nLengthX > 4 ) { baTemp.resize(4); pPacket->Read(baTemp.data(), 4); pHit->m_sDescriptiveName = pPacket->ReadString(nLengthX - 4); } bHaveDN = true; } else if( strcmp("MD", szTypeX) == 0 ) { pHit->m_sMetadata = pPacket->ReadString(); } else if( strcmp("SZ", szTypeX) == 0 && nLengthX >= 4 ) { if( nLengthX >= 8 ) { if( !baTemp.isEmpty() ) { pHit->m_sDescriptiveName.prepend(baTemp); } pHit->m_nObjectSize = pPacket->ReadIntLE<quint64>(); bHaveSize = true; } else if( nLengthX >= 4 ) { if( !baTemp.isEmpty() ) { pHit->m_sDescriptiveName.prepend(baTemp); } pHit->m_nObjectSize = pPacket->ReadIntLE<quint32>(); bHaveSize = true; } } else if( strcmp("CSC", szTypeX) == 0 && nLengthX >= 2 ) { pHit->m_nCachedSources = pPacket->ReadIntLE<quint16>(); } else if( strcmp("PART", szTypeX) == 0 && nLengthX >= 4 ) { pHit->m_bIsPartial = true; pHit->m_nPartialBytesAvailable = pPacket->ReadIntLE<quint32>(); } pPacket->m_nPosition = nNextX; } if( !bHaveSize && baTemp.size() == 4 ) { pHit->m_nObjectSize = qFromLittleEndian(*(quint32*)baTemp.constData()); } else { pHit->m_sDescriptiveName.prepend(baTemp); } if( bHaveURN && bHaveDN ) { bFirstHit = false; bHaveHits = true; } else { if( !bFirstHit ) { // może teraz się nie wywali... // można by było to lepiej zrobić... for( CQueryHit* pTest = pThisHit; pTest != 0; pTest = pTest->m_pNext ) { if( pTest->m_pNext == pHit ) { pTest->m_pNext = 0; break; } } pHit->Delete(); } } } pPacket->m_nPosition = nNext; } } catch(...) // packet incomplete, packet error, parser takes care of stream end { qDebug() << "EXCEPTION IN QUERY HIT PARSING!"; if( pThisHit ) { pThisHit->Delete(); } //throw; return 0; } // we already know query hit informations, so don't reparse them if( !bHaveHits ) { pThisHit->Delete(); return 0; } CQueryHit* pHit = pThisHit; while( pHit != 0 ) { pHit->m_pHitInfo = pHitInfo; pHit = pHit->m_pNext; } // TODO: sprawdzic poprawnosc hita... (Validate hit) pHit = pThisHit; while( pHit != 0 ) { pHit->ResolveURLs(); pHit = pHit->m_pNext; } return pThisHit; }