📄 qxmlstream.cpp
字号:
huge, or it is being delivered over a network connection \sa tokenType(), tokenString() */QXmlStreamReader::TokenType QXmlStreamReader::readNext(){ Q_D(QXmlStreamReader); if (d->type != Invalid) { if (!d->hasCheckedStartDocument) if (!d->checkStartDocument()) return d->type; // synthetic StartDocument or error d->parse(); if (d->atEnd && d->type != EndDocument && d->type != Invalid) d->raiseError(PrematureEndOfDocumentError); else if (!d->atEnd && d->type == EndDocument) d->raiseWellFormedError(QXmlStream::tr("Extra content at end of document.")); } else if (d->error == PrematureEndOfDocumentError) { // resume error d->type = NoToken; d->atEnd = false; d->token = -1; return readNext(); } return d->type;}/*! Returns the type of the current token. The current token can also be queried with the convenience functions isStartDocument(), isEndDocument(), isStartElement(), isEndElement(), isCharacters(), isComment(), isDTD(), isEntityReference(), and isProcessingInstruction() \sa tokenString() */QXmlStreamReader::TokenType QXmlStreamReader::tokenType() const{ Q_D(const QXmlStreamReader); return d->type;}static const char * QXmlStreamReader_tokenTypeString[] = { "NoToken", "Invalid", "StartDocument", "EndDocument", "StartElement", "EndElement", "Characters", "Comment", "DTD", "EntityReference", "ProcessingInstruction"};/*! \property QXmlStreamReader::namespaceProcessing the namespace-processing flag of the stream reader This property controls whether or not the stream reader processes namespaces. If enabled, the reader processes namespaces, otherwise it does not. By default, namespace-processing is enabled.*/void QXmlStreamReader::setNamespaceProcessing(bool enable){ Q_D(QXmlStreamReader); d->namespaceProcessing = enable;}bool QXmlStreamReader::namespaceProcessing() const{ Q_D(const QXmlStreamReader); return d->namespaceProcessing;}/*! Returns the reader's current token as string.\sa tokenType()*/QString QXmlStreamReader::tokenString() const{ Q_D(const QXmlStreamReader); return QLatin1String(QXmlStreamReader_tokenTypeString[d->type]);}QXmlStreamPrivateTagStack::QXmlStreamPrivateTagStack(){ tagStack.reserve(16); tagStackStringStorage.reserve(32); tagStackStringStorageSize = 0; NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.push(); namespaceDeclaration.prefix = addToStringStorage(QLatin1String("xml")); namespaceDeclaration.namespaceUri = addToStringStorage(QLatin1String("http://www.w3.org/XML/1998/namespace")); tagStackDefaultStringStorageSize = tagStackStringStorageSize;}QXmlStreamReaderPrivate::QXmlStreamReaderPrivate(QXmlStreamReader *q) :q_ptr(q){ device = 0; deleteDevice = false;#ifndef QT_NO_TEXTCODEC decoder = 0;#endif stack_size = 64; sym_stack = 0; state_stack = 0; reallocateStack(); init(); entityHash.insert(QLatin1String("lt"), Entity::createLiteral(QLatin1String("<"))); entityHash.insert(QLatin1String("gt"), Entity::createLiteral(QLatin1String(">"))); entityHash.insert(QLatin1String("amp"), Entity::createLiteral(QLatin1String("&"))); entityHash.insert(QLatin1String("apos"), Entity::createLiteral(QLatin1String("'"))); entityHash.insert(QLatin1String("quot"), Entity::createLiteral(QLatin1String("\"")));}void QXmlStreamReaderPrivate::init(){ tos = 0; scanDtd = false; token = -1; token_char = 0; isEmptyElement = false; isWhitespace = false; isCDATA = false; standalone = false; tos = 0; resumeReduction = 0; state_stack[tos++] = 0; state_stack[tos] = 0; putStack.clear(); putStack.reserve(32); textBuffer.clear(); textBuffer.reserve(256); initTagStack(); tagsDone = false; attributes.clear(); attributes.reserve(16); lineNumber = lastLineStart = characterOffset = 0; readBufferPos = 0; nbytesread = 0;#ifndef QT_NO_TEXTCODEC codec = QTextCodec::codecForMib(106); // utf8 delete decoder; decoder = 0;#endif attributeStack.clear(); attributeStack.reserve(16); entityParser = 0; hasCheckedStartDocument = false; normalizeLiterals = false; hasSeenTag = false; atEnd = false; inParseEntity = false; referenceToUnparsedEntityDetected = false; referenceToParameterEntityDetected = false; hasExternalDtdSubset = false; lockEncoding = false; namespaceProcessing = true; rawReadBuffer.clear(); dataBuffer.clear(); readBuffer.clear(); type = QXmlStreamReader::NoToken; error = QXmlStreamReader::NoError;}/* Well-formed requires that we verify entity values. We do this with a standard parser. */void QXmlStreamReaderPrivate::parseEntity(const QString &value){ Q_Q(QXmlStreamReader); if (value.isEmpty()) return; if (!entityParser) entityParser = new QXmlStreamReaderPrivate(q); else entityParser->init(); entityParser->inParseEntity = true; entityParser->readBuffer = value; entityParser->injectToken(PARSE_ENTITY); while (!entityParser->atEnd && entityParser->type != QXmlStreamReader::Invalid) entityParser->parse(); if (entityParser->type == QXmlStreamReader::Invalid || entityParser->tagStack.size()) raiseWellFormedError(QXmlStream::tr("Invalid entity value."));}inline void QXmlStreamReaderPrivate::reallocateStack(){ stack_size <<= 1; sym_stack = reinterpret_cast<Value*> (qRealloc(sym_stack, stack_size * sizeof(Value))); state_stack = reinterpret_cast<int*> (qRealloc(state_stack, stack_size * sizeof(int)));}QXmlStreamReaderPrivate::~QXmlStreamReaderPrivate(){#ifndef QT_NO_TEXTCODEC delete decoder;#endif qFree(sym_stack); qFree(state_stack); delete entityParser;}inline uint QXmlStreamReaderPrivate::filterCarriageReturn(){ uint peekc = peekChar(); if (peekc == '\n') { if (putStack.size()) putStack.pop(); else ++readBufferPos; return peekc; } if (peekc == 0) { putChar('\r'); return 0; } return '\n';}/*! \internal If the end of the file is encountered, 0 is returned. */inline uint QXmlStreamReaderPrivate::getChar(){ uint c; if (putStack.size()) { c = atEnd ? 0 : putStack.pop(); } else { if (readBufferPos < readBuffer.size()) c = readBuffer.at(readBufferPos++).unicode(); else c = getChar_helper(); } return c;}inline uint QXmlStreamReaderPrivate::peekChar(){ uint c; if (putStack.size()) { c = putStack.top(); } else if (readBufferPos < readBuffer.size()) { c = readBuffer.at(readBufferPos).unicode(); } else { if ((c = getChar_helper())) --readBufferPos; } return c;}/*! \internal Scans characters until \a str is encountered, and validates the characters as according to the Char[2] production and do the line-ending normalization. If any character is invalid, false is returned, otherwise true upon success. If \a tokenToInject is not less than zero, injectToken() is called with \a tokenToInject when \a str is found. If any error occurred, false is returned, otherwise true. */bool QXmlStreamReaderPrivate::scanUntil(const char *str, short tokenToInject){ int pos = textBuffer.size(); int oldLineNumber = lineNumber; while (uint c = getChar()) { /* First, we do the validation & normalization. */ switch (c) { case '\r': if ((c = filterCarriageReturn()) == 0) break; // fall through case '\n': ++lineNumber; lastLineStart = characterOffset + readBufferPos; // fall through case '\t': textBuffer.inline_append(c); continue; default: if(c < 0x20 || (c > 0xFFFD && c < 0x10000) || c > 0x10FFFF ) { raiseWellFormedError(QXmlStream::tr("Invalid XML character.")); lineNumber = oldLineNumber; return false; } textBuffer.inline_append(c); } /* Second, attempt to lookup str. */ if (c == uint(*str)) { if (!*(str + 1)) { if (tokenToInject >= 0) injectToken(tokenToInject); return true; } else { if (scanString(str + 1, tokenToInject, false)) return true; } } } putString(textBuffer, pos); textBuffer.resize(pos); lineNumber = oldLineNumber; return false;}bool QXmlStreamReaderPrivate::scanString(const char *str, short tokenToInject, bool requireSpace){ int n = 0; while (str[n]) { ushort c = getChar(); if (c != ushort(str[n])) { if (c) putChar(c); while (n--) { putChar(ushort(str[n])); } return false; } ++n; } for (int i = 0; i < n; ++i) textBuffer.inline_append(ushort(str[i])); if (requireSpace) { int s = fastScanSpace(); if (!s || atEnd) { int pos = textBuffer.size() - n - s; putString(textBuffer, pos); textBuffer.resize(pos); return false; } } if (tokenToInject >= 0) injectToken(tokenToInject); return true;}bool QXmlStreamReaderPrivate::scanAfterLangleBang(){ switch (peekChar()) { case '[': return scanString(spell[CDATA_START], CDATA_START, false); case 'D': return scanString(spell[DOCTYPE], DOCTYPE); case 'A': return scanString(spell[ATTLIST], ATTLIST); case 'N': return scanString(spell[NOTATION], NOTATION); case 'E': if (scanString(spell[ELEMENT], ELEMENT)) return true; return scanString(spell[ENTITY], ENTITY); default: ; }; return false;}bool QXmlStreamReaderPrivate::scanPublicOrSystem(){ switch (peekChar()) { case 'S': return scanString(spell[SYSTEM], SYSTEM); case 'P': return scanString(spell[PUBLIC], PUBLIC); default: ; } return false;}bool QXmlStreamReaderPrivate::scanNData(){ if (fastScanSpace()) { if (scanString(spell[NDATA], NDATA)) return true; putChar(' '); } return false;}bool QXmlStreamReaderPrivate::scanAfterDefaultDecl(){ switch (peekChar()) { case 'R': return scanString(spell[REQUIRED], REQUIRED, false); case 'I': return scanString(spell[IMPLIED], IMPLIED, false); case 'F': return scanString(spell[FIXED], FIXED, false); default: ; } return false;}bool QXmlStreamReaderPrivate::scanAttType(){ switch (peekChar()) { case 'C': return scanString(spell[CDATA], CDATA); case 'I': if (scanString(spell[ID], ID)) return true; if (scanString(spell[IDREF], IDREF)) return true; return scanString(spell[IDREFS], IDREFS); case 'E': if (scanString(spell[ENTITY], ENTITY)) return true; return scanString(spell[ENTITIES], ENTITIES); case 'N': if (scanString(spell[NOTATION], NOTATION))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -