void XmlWriter::readFragment(const QTextBlock ¤tBlock, QDomElement blockElement, QDomDocument *document) { //! [3] //! [4] QTextBlock::iterator it; for (it = currentBlock.begin(); !(it.atEnd()); ++it) { QTextFragment currentFragment = it.fragment(); if (currentFragment.isValid()) //! [3] //! [5] processFragment(currentFragment); //! [4] //! [5] if (currentFragment.isValid()) { QDomElement fragmentElement = document->createElement("fragment"); blockElement.appendChild(fragmentElement); fragmentElement.setAttribute("length", currentFragment.length()); QDomText fragmentText = document->createTextNode(currentFragment.text()); fragmentElement.appendChild(fragmentText); } //! [6] //! [7] } //! [7] //! [6] }
QString TextDocumentSerializer::processBlockContent(QTextBlock block) { QTextBlock::iterator it = block.begin(); QString text; while(!it.atEnd()){ QTextFragment currentFragment = it.fragment(); if (currentFragment.isValid()) text += processFragment(currentFragment); ++it; } if(block.textList()) return QString("<li>%1</li>").arg(text); else return QString("%1<br>").arg(text); }
//////////////////////////////////////////////////// // handle a new packet on the stream void EQPacketStream::handlePacket(EQUDPIPPacketFormat& packet) { emit numPacket(++m_packetCount, (int)m_streamid); if (!packet.isARQ()) // process packets that don't have an arq sequence { // we only handle packets with opcodes if (packet.payloadLength() < 2) return; // process the packets payload immediately processPayload(packet.payload(), packet.payloadLength()); } else if (packet.isARQ()) // process ARQ sequences { uint16_t arqSeq = packet.arq(); emit seqReceive(arqSeq, (int)m_streamid); /* this conditions should only be met once per zone/world, New Sequence */ if (packet.isSEQStart() && !packet.isClosingLo() && (m_session_tracking_enabled < 2)) { #ifdef PACKET_PROCESS_DIAG seqDebug("EQPacket: SEQStart found, setting arq seq, %04x stream %s", arqSeq, EQStreamStr[m_streamid]); #endif initDecode(); // hey, a SEQStart, use it's packet to set ARQ m_arqSeqExp = arqSeq; m_arqSeqFound = true; emit seqExpect(m_arqSeqExp, (int)m_streamid); if ((m_streamid == zone2client) && m_session_tracking_enabled) { m_session_tracking_enabled = 2; emit lockOnClient(packet.getSourcePort(), packet.getDestPort()); // notify that the client port has been latched emit sessionTrackingChanged(m_session_tracking_enabled); } } else if (!m_arqSeqFound && m_session_tracking_enabled == 0 && !packet.isClosingHi() && !packet.isClosingLo() && (m_streamid == zone2client)) { #ifdef PACKET_PROCESS_DIAG seqDebug("SEQ: new sequence found, setting arq seq, %04x stream %s", arqSeq, EQStreamStr[m_streamid]); #endif m_arqSeqExp = arqSeq; m_arqSeqFound = true; emit seqExpect(m_arqSeqExp, (int)m_streamid); } // is this the currently expected sequence, if so, do something with it. if (m_arqSeqExp == arqSeq) { m_arqSeqExp = arqSeq + 1; emit seqExpect(m_arqSeqExp, (int)m_streamid); #ifdef PACKET_PROCESS_DIAG seqDebug("SEQ: Found next arq in data stream %s, incrementing arq seq, %04x", EQStreamStr[m_streamid], arqSeq); #endif if (!packet.isASQ() && !packet.isFragment() && !packet.isClosingHi()) { // seems to be a sort of ping from client to server, has ARQ // but no ASQ, Flags look like 0x0201 (network byte order) #ifdef PACKET_PROCESS_DIAG seqDebug("SEQ: ARQ without ASQ from stream %s arq 0x%04x", EQStreamStr[m_streamid], arqSeq); #endif } // since the servers do not care about client closing sequences, we won't either // Hey clients have rights too, or not! else if (packet.isClosingHi() && packet.isClosingLo() && (m_streamid == zone2client)) { if (m_session_tracking_enabled) m_session_tracking_enabled = 1; emit closing(); return; } // if the packet is a fragment do appropriate processing else if (packet.isFragment()) processFragment(packet); else if (packet.payloadLength() >= 2) // has to have an opcode processPayload(packet.payload(), packet.payloadLength()); } // it's a packet from the future, add it to the cache else if ( ( (arqSeq > m_arqSeqExp) && (arqSeq < (uint32_t(m_arqSeqExp + arqSeqWrapCutoff))) ) || (arqSeq < (int32_t(m_arqSeqExp) - arqSeqWrapCutoff)) ) { #ifdef PACKET_PROCESS_DIAG seqDebug("SEQ: out of order arq %04x stream %s, sending to cache, %04d", arqSeq, EQStreamStr[m_streamid], m_cache.size()); #endif setCache(arqSeq, packet); } // if the cache isn't empty, then check for the expected ARQ sequence if (!m_cache.empty()) processCache(); } /* end ARQ processing */ }
//////////////////////////////////////////////////// // Cache processing void EQPacketStream::processCache() { #if defined(PACKET_CACHE_DIAG) seqDebug("SEQ: START checking stream %s cache, arq %04x, cache count %04d", EQStreamStr[m_streamid], m_arqSeqExp, m_cache.size()); #endif EQPacketMap::iterator it; EQPacketMap::iterator eraseIt; EQPacketFormat* pf; // check if the cache has grown large enough that we should give up // on seeing the current serverArqSeqExp // this should really only kick in for people with pathetic // network cards that missed the packet. if (m_cache.size() >= m_arqSeqGiveUp) { // ok, if the expected server arq sequence isn't here yet, give up // attempt to find the current expencted arq seq it = m_cache.find(m_arqSeqExp); // keep trying to find a new serverArqSeqExp if we haven't found a good // one yet... while(it == m_cache.end()) { seqDebug("SEQ: Giving up on finding arq %04x in stream %s cache, skipping!", m_arqSeqExp, EQStreamStr[m_streamid]); // incremente the expected arq sequence number m_arqSeqExp++; emit seqExpect(m_arqSeqExp, (int)m_streamid); // attempt to find the new current expencted arq seq it = m_cache.find(m_arqSeqExp); } } else { // haven't given up yet, just try to find the current serverArqSeqExp // attempt to find the current expected ARQ seq it = m_cache.find(m_arqSeqExp); } // iterate over cache until we reach the end or run out of // immediate followers while (it != m_cache.end()) { // get the PacketFormat for the iterator pf = it->second; // make sure this is the expected packet // (we might have incremented to the one after the one returned // by find above). if (pf->arq() != m_arqSeqExp) break; #ifdef PACKET_CACHE_DIAG seqDebug("SEQ: found next arq %04x in stream %s cache, cache count %04d", m_arqSeqExp, EQStreamStr[m_streamid], m_cache.size()); #endif #if defined (PACKET_CACHE_DIAG) && (PACKET_CACHE_DIAG > 2) // validate the packet against a memory corruption if (!pf->isValid()) { // Something's screwed up seqDebug("SEQ: INVALID PACKET: Bad CRC32 in packet in stream %s cache with arq %04x!", EQStreamStr[m_streamid], pf->arq()); } #endif #if defined (PACKET_CACHE_DIAG) && (PACKET_CACHE_DIAG > 2) seqDebug("SEQ: Found next arq in stream %s cache, incrementing arq seq, %04x", EQStreamStr[m_streamid], pf->arq()); #endif // Duplicate ARQ processing functionality from dispatchPacket, // should prolly be its own function processARQ() or some such beast if (!pf->isASQ() && !pf->isFragment() && !pf->isClosingHi()) { // seems to be a sort of ping from client to server, has ARQ // but no ASQ, Flags look like 0x0201 (network byte order) #if defined (PACKET_CACHE_DIAG) && (PACKET_CACHE_DIAG > 2) seqDebug("SEQ: ARQ without ASQ from stream %s arq 0x%04x", EQStreamStr[m_streamid], pf->arq()); #endif } // since the servers do not care about client closing sequences, we won't either else if (pf->isClosingHi() && pf->isClosingLo() && (m_streamid == zone2client)) { #if defined (PACKET_CACHE_DIAG) && (PACKET_CACHE_DIAG > 2) seqDebug("EQPacketStream: Closing HI & LO, stream %s arq %04x", EQStreamStr[m_streamid], pf->arq()); #endif if (m_session_tracking_enabled) m_session_tracking_enabled = 1; emit closing(); break; } // if the packet isn't a fragment dispatch normally, otherwise to split else if (pf->isFragment()) processFragment(*pf); else processPayload(pf->payload(), pf->payloadLength()); eraseIt = it; // increment the current position iterator it++; // erase the packet from the cache m_cache.erase(eraseIt); emit cacheSize(m_cache.size(), (int)m_streamid); #ifdef PACKET_CACHE_DIAG seqDebug("SEQ: REMOVING arq %04x from stream %s cache, cache count %04d", pf->arq(), EQStreamStr[m_streamid], m_cache.size()); #endif // delete the packet delete pf; // increment the expected arq number m_arqSeqExp++; emit seqExpect(m_arqSeqExp, (int)m_streamid); if (m_arqSeqExp == 0) it = m_cache.begin(); } #ifdef PACKET_CACHE_DIAG seqDebug("SEQ: FINISHED checking stream %s cache, arq %04x, cache count %04d", EQStreamStr[m_streamid], m_arqSeqExp, m_cache.size()); #endif }