예제 #1
0
		void checkNeedMore()
		{
			// Here we will work around QXmlSimpleReader strangeness and self-closing tags.
			// The problem is that endElement() is called when the '/' is read, not when
			// the final '>' is read.  This is a potential problem when obtaining unprocessed
			// bytes from StreamInput after this event, as the '>' character will end up
			// in the unprocessed chunk.  To work around this, we need to advance StreamInput's
			// internal byte processing, but not the xml character data.  This way, the '>'
			// will get processed and will no longer be in the unprocessed return, but
			// QXmlSimpleReader can still read it.  To do this, we call StreamInput::readNext
			// with 'peek' mode.
			QChar c = in->readNext(true); // peek
			if(c == QXmlInputSource::EndOfData) {
				needMore = true;
			}
			else {
				// We'll assume the next char is a '>'.  If it isn't, then
				// QXmlSimpleReader will deal with that problem on the next
				// parse.  We don't need to take any action here.
				needMore = false;

				// there should have been a pending event
				Parser::Event *e = eventList.first();
				if(!eventList.isEmpty()) {
					e->setActualString(e->actualString() + '>');
					in->resetLastData();
				}
			}
		}
예제 #2
0
bool XmlProtocol::processStep()
{
	Parser::Event pe;
	notify = 0;
	transferItemList.clear();

	if(state != Closing && (state == RecvOpen || stepAdvancesParser())) {
		// if we get here, then it's because we're in some step that advances the parser
		pe = xml.readNext();
		if(!pe.isNull()) {
			// note: error/close events should be handled for ALL steps, so do them here
			switch(pe.type()) {
				case Parser::Event::DocumentOpen: {
					transferItemList += TransferItem(pe.actualString(), false);

					//stringRecv(pe.actualString());
					break;
				}
				case Parser::Event::DocumentClose: {
					transferItemList += TransferItem(pe.actualString(), false);

					//stringRecv(pe.actualString());
					if(incoming) {
						sendTagClose();
						event = ESend;
						peerClosed = true;
						state = Closing;
					}
					else {
						event = EPeerClosed;
					}
					return true;
				}
				case Parser::Event::Element: {
					QDomElement e = elemDoc.importNode(pe.element(),true).toElement();
					transferItemList += TransferItem(e, false);

					//elementRecv(pe.element());
					break;
				}
				case Parser::Event::Error: {
					if(incoming) {
						// If we get a parse error during the initial element exchange,
						// flip immediately into 'open' mode so that we can report an error.
						if(state == RecvOpen) {
							sendTagOpen();
							state = Open;
						}
						return handleError();
					}
					else {
						event = EError;
						errorCode = ErrParse;
						return true;
					}
				}
			}
		}
		else {
			if(state == RecvOpen || stepRequiresElement()) {
				need = NNotify;
				notify |= NRecv;
				return false;
			}
		}
	}

	return baseStep(pe);
}