diff options
Diffstat (limited to 'src/xml')
-rw-r--r-- | src/xml/CMakeLists.txt | 14 | ||||
-rw-r--r-- | src/xml/dom/dom.pri | 7 | ||||
-rw-r--r-- | src/xml/dom/qdom.cpp | 883 | ||||
-rw-r--r-- | src/xml/dom/qdom.h | 15 | ||||
-rw-r--r-- | src/xml/dom/qdom_p.h | 540 | ||||
-rw-r--r-- | src/xml/dom/qdomhelpers.cpp | 663 | ||||
-rw-r--r-- | src/xml/dom/qdomhelpers_p.h | 258 | ||||
-rw-r--r-- | src/xml/qtxmlglobal.h | 2 | ||||
-rw-r--r-- | src/xml/sax/qxml.cpp | 38 | ||||
-rw-r--r-- | src/xml/sax/qxml.h | 70 | ||||
-rw-r--r-- | src/xml/sax/qxml_p.h | 9 |
11 files changed, 1734 insertions, 765 deletions
diff --git a/src/xml/CMakeLists.txt b/src/xml/CMakeLists.txt index 9a9d431072..8b79b9df45 100644 --- a/src/xml/CMakeLists.txt +++ b/src/xml/CMakeLists.txt @@ -4,9 +4,10 @@ ## Xml Module: ##################################################################### -add_qt_module(Xml +qt_add_module(Xml SOURCES - dom/qdom.cpp dom/qdom.h + dom/qdom.cpp dom/qdom.h dom/qdom_p.h + dom/qdomhelpers.cpp dom/qdomhelpers_p.h qtxmlglobal.h sax/qxml.cpp sax/qxml.h sax/qxml_p.h DEFINES @@ -16,19 +17,18 @@ add_qt_module(Xml Qt::CorePrivate PUBLIC_LIBRARIES Qt::Core + PRIVATE_MODULE_INTERFACE + Qt::CorePrivate ) -#### Keys ignored in scope 1:.:.:xml.pro:<TRUE>: -# _LOADED = "qt_module" - ## Scopes: ##################################################################### -extend_target(Xml CONDITION MSVC AND (TEST_architecture_arch STREQUAL "i386") +qt_extend_target(Xml CONDITION MSVC AND (TEST_architecture_arch STREQUAL "i386") LINK_OPTIONS "/BASE:0x61000000" ) -add_qt_docs(Xml +qt_add_docs(Xml doc/qtxml.qdocconf ) diff --git a/src/xml/dom/dom.pri b/src/xml/dom/dom.pri index d86071e84e..36b6087ede 100644 --- a/src/xml/dom/dom.pri +++ b/src/xml/dom/dom.pri @@ -1,2 +1,5 @@ -HEADERS += $$PWD/qdom.h -SOURCES += $$PWD/qdom.cpp +HEADERS += $$PWD/qdom.h \ + $$PWD/qdom_p.h \ + $$PWD/qdomhelpers_p.h +SOURCES += $$PWD/qdom.cpp \ + $$PWD/qdomhelpers.cpp diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp index 3e8b18d449..1ac13b380a 100644 --- a/src/xml/dom/qdom.cpp +++ b/src/xml/dom/qdom.cpp @@ -39,15 +39,15 @@ #include <qplatformdefs.h> #include <qdom.h> +#include "qdom_p.h" +#include "qdomhelpers_p.h" #include "private/qxmlutils_p.h" #ifndef QT_NO_DOM #include <qatomic.h> #include <qbuffer.h> -#include <qhash.h> #include <qiodevice.h> -#include <qlist.h> #if QT_CONFIG(regularexpression) #include <qregularexpression.h> #endif @@ -56,11 +56,13 @@ #endif #include <qtextstream.h> #include <qxml.h> -#include "private/qxml_p.h" #include <qvariant.h> -#include <qmap.h> #include <qshareddata.h> #include <qdebug.h> +#include <qxmlstream.h> +#include <private/qduplicatetracker_p.h> + + #include <stdio.h> QT_BEGIN_NAMESPACE @@ -119,510 +121,6 @@ static void qt_split_namespace(QString& prefix, QString& name, const QString& qN /************************************************************** * - * Private class declerations - * - **************************************************************/ - -class QDomImplementationPrivate -{ -public: - inline QDomImplementationPrivate() {} - - QDomImplementationPrivate* clone(); - QAtomicInt ref; - static QDomImplementation::InvalidDataPolicy invalidDataPolicy; -}; - -class QDomNodePrivate -{ -public: - QDomNodePrivate(QDomDocumentPrivate*, QDomNodePrivate* parent = nullptr); - QDomNodePrivate(QDomNodePrivate* n, bool deep); - virtual ~QDomNodePrivate(); - - QString nodeName() const { return name; } - QString nodeValue() const { return value; } - virtual void setNodeValue(const QString& v) { value = v; } - - QDomDocumentPrivate* ownerDocument(); - void setOwnerDocument(QDomDocumentPrivate* doc); - - virtual QDomNodePrivate* insertBefore(QDomNodePrivate* newChild, QDomNodePrivate* refChild); - virtual QDomNodePrivate* insertAfter(QDomNodePrivate* newChild, QDomNodePrivate* refChild); - virtual QDomNodePrivate* replaceChild(QDomNodePrivate* newChild, QDomNodePrivate* oldChild); - virtual QDomNodePrivate* removeChild(QDomNodePrivate* oldChild); - virtual QDomNodePrivate* appendChild(QDomNodePrivate* newChild); - - QDomNodePrivate* namedItem(const QString& name); - - virtual QDomNodePrivate* cloneNode(bool deep = true); - virtual void normalize(); - virtual void clear(); - - inline QDomNodePrivate* parent() const { return hasParent ? ownerNode : nullptr; } - inline void setParent(QDomNodePrivate *p) { ownerNode = p; hasParent = true; } - - void setNoParent() { - ownerNode = hasParent ? (QDomNodePrivate*)ownerDocument() : nullptr; - hasParent = false; - } - - // Dynamic cast - bool isAttr() const { return nodeType() == QDomNode::AttributeNode; } - bool isCDATASection() const { return nodeType() == QDomNode::CDATASectionNode; } - bool isDocumentFragment() const { return nodeType() == QDomNode::DocumentFragmentNode; } - bool isDocument() const { return nodeType() == QDomNode::DocumentNode; } - bool isDocumentType() const { return nodeType() == QDomNode::DocumentTypeNode; } - bool isElement() const { return nodeType() == QDomNode::ElementNode; } - bool isEntityReference() const { return nodeType() == QDomNode::EntityReferenceNode; } - bool isText() const { const QDomNode::NodeType nt = nodeType(); - return (nt == QDomNode::TextNode) - || (nt == QDomNode::CDATASectionNode); } - bool isEntity() const { return nodeType() == QDomNode::EntityNode; } - bool isNotation() const { return nodeType() == QDomNode::NotationNode; } - bool isProcessingInstruction() const { return nodeType() == QDomNode::ProcessingInstructionNode; } - bool isCharacterData() const { const QDomNode::NodeType nt = nodeType(); - return (nt == QDomNode::CharacterDataNode) - || (nt == QDomNode::TextNode) - || (nt == QDomNode::CommentNode); } - bool isComment() const { return nodeType() == QDomNode::CommentNode; } - - virtual QDomNode::NodeType nodeType() const { return QDomNode::BaseNode; } - - virtual void save(QTextStream&, int, int) const; - - void setLocation(int lineNumber, int columnNumber); - - // Variables - QAtomicInt ref; - QDomNodePrivate* prev; - QDomNodePrivate* next; - QDomNodePrivate* ownerNode; // either the node's parent or the node's owner document - QDomNodePrivate* first; - QDomNodePrivate* last; - - QString name; // this is the local name if prefix != null - QString value; - QString prefix; // set this only for ElementNode and AttributeNode - QString namespaceURI; // set this only for ElementNode and AttributeNode - bool createdWithDom1Interface : 1; - bool hasParent : 1; - - int lineNumber; - int columnNumber; -}; - -class QDomNodeListPrivate -{ -public: - QDomNodeListPrivate(QDomNodePrivate*); - QDomNodeListPrivate(QDomNodePrivate*, const QString& ); - QDomNodeListPrivate(QDomNodePrivate*, const QString&, const QString& ); - ~QDomNodeListPrivate(); - - bool operator== (const QDomNodeListPrivate&) const; - bool operator!= (const QDomNodeListPrivate&) const; - - void createList(); - QDomNodePrivate* item(int index); - int length() const; - - QAtomicInt ref; - /* - This list contains the children of this node. - */ - QDomNodePrivate* node_impl; - QString tagname; - QString nsURI; - QList<QDomNodePrivate*> list; - long timestamp; -}; - -class QDomNamedNodeMapPrivate -{ -public: - QDomNamedNodeMapPrivate(QDomNodePrivate*); - ~QDomNamedNodeMapPrivate(); - - QDomNodePrivate* namedItem(const QString& name) const; - QDomNodePrivate* namedItemNS(const QString& nsURI, const QString& localName) const; - QDomNodePrivate* setNamedItem(QDomNodePrivate* arg); - QDomNodePrivate* setNamedItemNS(QDomNodePrivate* arg); - QDomNodePrivate* removeNamedItem(const QString& name); - QDomNodePrivate* item(int index) const; - int length() const; - bool contains(const QString& name) const; - bool containsNS(const QString& nsURI, const QString & localName) const; - - /** - * Remove all children from the map. - */ - void clearMap(); - bool isReadOnly() { return readonly; } - void setReadOnly(bool r) { readonly = r; } - bool isAppendToParent() { return appendToParent; } - /** - * If true, then the node will redirect insert/remove calls - * to its parent by calling QDomNodePrivate::appendChild or removeChild. - * In addition the map won't increase or decrease the reference count - * of the nodes it contains. - * - * By default this value is false and the map will handle reference counting - * by itself. - */ - void setAppendToParent(bool b) { appendToParent = b; } - - /** - * Creates a copy of the map. It is a deep copy - * that means that all children are cloned. - */ - QDomNamedNodeMapPrivate* clone(QDomNodePrivate* parent); - - // Variables - QAtomicInt ref; - QHash<QString, QDomNodePrivate *> map; - QDomNodePrivate* parent; - bool readonly; - bool appendToParent; -}; - -class QDomDocumentTypePrivate : public QDomNodePrivate -{ -public: - QDomDocumentTypePrivate(QDomDocumentPrivate*, QDomNodePrivate* parent = nullptr); - QDomDocumentTypePrivate(QDomDocumentTypePrivate* n, bool deep); - ~QDomDocumentTypePrivate(); - void init(); - - // Reimplemented from QDomNodePrivate - QDomNodePrivate* cloneNode(bool deep = true) override; - QDomNodePrivate* insertBefore(QDomNodePrivate* newChild, QDomNodePrivate* refChild) override; - QDomNodePrivate* insertAfter(QDomNodePrivate* newChild, QDomNodePrivate* refChild) override; - QDomNodePrivate* replaceChild(QDomNodePrivate* newChild, QDomNodePrivate* oldChild) override; - QDomNodePrivate* removeChild(QDomNodePrivate* oldChild) override; - QDomNodePrivate* appendChild(QDomNodePrivate* newChild) override; - - QDomNode::NodeType nodeType() const override { return QDomNode::DocumentTypeNode; } - - void save(QTextStream& s, int, int) const override; - - // Variables - QDomNamedNodeMapPrivate* entities; - QDomNamedNodeMapPrivate* notations; - QString publicId; - QString systemId; - QString internalSubset; -}; - -class QDomDocumentFragmentPrivate : public QDomNodePrivate -{ -public: - QDomDocumentFragmentPrivate(QDomDocumentPrivate*, QDomNodePrivate* parent = nullptr); - QDomDocumentFragmentPrivate(QDomNodePrivate* n, bool deep); - - // Reimplemented from QDomNodePrivate - virtual QDomNodePrivate* cloneNode(bool deep = true) override; - QDomNode::NodeType nodeType() const override { return QDomNode::DocumentFragmentNode; } -}; - -class QDomCharacterDataPrivate : public QDomNodePrivate -{ -public: - QDomCharacterDataPrivate(QDomDocumentPrivate*, QDomNodePrivate* parent, const QString& data); - QDomCharacterDataPrivate(QDomCharacterDataPrivate* n, bool deep); - - int dataLength() const; - QString substringData(unsigned long offset, unsigned long count) const; - void appendData(const QString& arg); - void insertData(unsigned long offset, const QString& arg); - void deleteData(unsigned long offset, unsigned long count); - void replaceData(unsigned long offset, unsigned long count, const QString& arg); - - // Reimplemented from QDomNodePrivate - QDomNode::NodeType nodeType() const override { return QDomNode::CharacterDataNode; } - QDomNodePrivate* cloneNode(bool deep = true) override; -}; - -class QDomTextPrivate : public QDomCharacterDataPrivate -{ -public: - QDomTextPrivate(QDomDocumentPrivate*, QDomNodePrivate* parent, const QString& val); - QDomTextPrivate(QDomTextPrivate* n, bool deep); - - QDomTextPrivate* splitText(int offset); - - // Reimplemented from QDomNodePrivate - QDomNodePrivate* cloneNode(bool deep = true) override; - QDomNode::NodeType nodeType() const override { return QDomNode::TextNode; } - virtual void save(QTextStream& s, int, int) const override; -}; - -class QDomAttrPrivate : public QDomNodePrivate -{ -public: - QDomAttrPrivate(QDomDocumentPrivate*, QDomNodePrivate*, const QString& name); - QDomAttrPrivate(QDomDocumentPrivate*, QDomNodePrivate*, const QString& nsURI, const QString& qName); - QDomAttrPrivate(QDomAttrPrivate* n, bool deep); - - bool specified() const; - - // Reimplemented from QDomNodePrivate - void setNodeValue(const QString& v) override; - QDomNodePrivate* cloneNode(bool deep = true) override; - QDomNode::NodeType nodeType() const override { return QDomNode::AttributeNode; } - virtual void save(QTextStream& s, int, int) const override; - - // Variables - bool m_specified; -}; - -class QDomElementPrivate : public QDomNodePrivate -{ -public: - QDomElementPrivate(QDomDocumentPrivate*, QDomNodePrivate* parent, const QString& name); - QDomElementPrivate(QDomDocumentPrivate*, QDomNodePrivate* parent, const QString& nsURI, const QString& qName); - QDomElementPrivate(QDomElementPrivate* n, bool deep); - ~QDomElementPrivate(); - - QString attribute(const QString& name, const QString& defValue) const; - QString attributeNS(const QString& nsURI, const QString& localName, const QString& defValue) const; - void setAttribute(const QString& name, const QString& value); - void setAttributeNS(const QString& nsURI, const QString& qName, const QString& newValue); - void removeAttribute(const QString& name); - QDomAttrPrivate* attributeNode(const QString& name); - QDomAttrPrivate* attributeNodeNS(const QString& nsURI, const QString& localName); - QDomAttrPrivate* setAttributeNode(QDomAttrPrivate* newAttr); - QDomAttrPrivate* setAttributeNodeNS(QDomAttrPrivate* newAttr); - QDomAttrPrivate* removeAttributeNode(QDomAttrPrivate* oldAttr); - bool hasAttribute(const QString& name); - bool hasAttributeNS(const QString& nsURI, const QString& localName); - - QString text(); - - // Reimplemented from QDomNodePrivate - QDomNamedNodeMapPrivate* attributes() { return m_attr; } - bool hasAttributes() { return (m_attr->length() > 0); } - QDomNode::NodeType nodeType() const override { return QDomNode::ElementNode; } - QDomNodePrivate* cloneNode(bool deep = true) override; - virtual void save(QTextStream& s, int, int) const override; - - // Variables - QDomNamedNodeMapPrivate* m_attr; -}; - - -class QDomCommentPrivate : public QDomCharacterDataPrivate -{ -public: - QDomCommentPrivate(QDomDocumentPrivate*, QDomNodePrivate* parent, const QString& val); - QDomCommentPrivate(QDomCommentPrivate* n, bool deep); - - // Reimplemented from QDomNodePrivate - QDomNodePrivate* cloneNode(bool deep = true) override; - QDomNode::NodeType nodeType() const override { return QDomNode::CommentNode; } - virtual void save(QTextStream& s, int, int) const override; -}; - -class QDomCDATASectionPrivate : public QDomTextPrivate -{ -public: - QDomCDATASectionPrivate(QDomDocumentPrivate*, QDomNodePrivate* parent, const QString& val); - QDomCDATASectionPrivate(QDomCDATASectionPrivate* n, bool deep); - - // Reimplemented from QDomNodePrivate - QDomNodePrivate* cloneNode(bool deep = true) override; - QDomNode::NodeType nodeType() const override { return QDomNode::CDATASectionNode; } - virtual void save(QTextStream& s, int, int) const override; -}; - -class QDomNotationPrivate : public QDomNodePrivate -{ -public: - QDomNotationPrivate(QDomDocumentPrivate*, QDomNodePrivate* parent, const QString& name, - const QString& pub, const QString& sys); - QDomNotationPrivate(QDomNotationPrivate* n, bool deep); - - // Reimplemented from QDomNodePrivate - QDomNodePrivate* cloneNode(bool deep = true) override; - QDomNode::NodeType nodeType() const override { return QDomNode::NotationNode; } - virtual void save(QTextStream& s, int, int) const override; - - // Variables - QString m_sys; - QString m_pub; -}; - -class QDomEntityPrivate : public QDomNodePrivate -{ -public: - QDomEntityPrivate(QDomDocumentPrivate*, QDomNodePrivate* parent, const QString& name, - const QString& pub, const QString& sys, const QString& notation); - QDomEntityPrivate(QDomEntityPrivate* n, bool deep); - - // Reimplemented from QDomNodePrivate - QDomNodePrivate* cloneNode(bool deep = true) override; - QDomNode::NodeType nodeType() const override { return QDomNode::EntityNode; } - virtual void save(QTextStream& s, int, int) const override; - - // Variables - QString m_sys; - QString m_pub; - QString m_notationName; -}; - -class QDomEntityReferencePrivate : public QDomNodePrivate -{ -public: - QDomEntityReferencePrivate(QDomDocumentPrivate*, QDomNodePrivate* parent, const QString& name); - QDomEntityReferencePrivate(QDomNodePrivate* n, bool deep); - - // Reimplemented from QDomNodePrivate - QDomNodePrivate* cloneNode(bool deep = true) override; - QDomNode::NodeType nodeType() const override { return QDomNode::EntityReferenceNode; } - virtual void save(QTextStream& s, int, int) const override; -}; - -class QDomProcessingInstructionPrivate : public QDomNodePrivate -{ -public: - QDomProcessingInstructionPrivate(QDomDocumentPrivate*, QDomNodePrivate* parent, const QString& target, - const QString& data); - QDomProcessingInstructionPrivate(QDomProcessingInstructionPrivate* n, bool deep); - - // Reimplemented from QDomNodePrivate - QDomNodePrivate* cloneNode(bool deep = true) override; - QDomNode::NodeType nodeType() const override { return QDomNode::ProcessingInstructionNode; } - virtual void save(QTextStream& s, int, int) const override; -}; - -class QDomDocumentPrivate : public QDomNodePrivate -{ -public: - QDomDocumentPrivate(); - QDomDocumentPrivate(const QString& name); - QDomDocumentPrivate(QDomDocumentTypePrivate* dt); - QDomDocumentPrivate(QDomDocumentPrivate* n, bool deep); - ~QDomDocumentPrivate(); - - bool setContent(QXmlInputSource *source, bool namespaceProcessing, QString *errorMsg, int *errorLine, int *errorColumn); - bool setContent(QXmlInputSource *source, QXmlReader *reader, QXmlSimpleReader *simpleReader, QString *errorMsg, int *errorLine, int *errorColumn); - - // Attributes - QDomDocumentTypePrivate* doctype() { return type.data(); } - QDomImplementationPrivate* implementation() { return impl.data(); } - QDomElementPrivate* documentElement(); - - // Factories - QDomElementPrivate* createElement(const QString& tagName); - QDomElementPrivate* createElementNS(const QString& nsURI, const QString& qName); - QDomDocumentFragmentPrivate* createDocumentFragment(); - QDomTextPrivate* createTextNode(const QString& data); - QDomCommentPrivate* createComment(const QString& data); - QDomCDATASectionPrivate* createCDATASection(const QString& data); - QDomProcessingInstructionPrivate* createProcessingInstruction(const QString& target, const QString& data); - QDomAttrPrivate* createAttribute(const QString& name); - QDomAttrPrivate* createAttributeNS(const QString& nsURI, const QString& qName); - QDomEntityReferencePrivate* createEntityReference(const QString& name); - - QDomNodePrivate* importNode(QDomNodePrivate* importedNode, bool deep); - - // Reimplemented from QDomNodePrivate - QDomNodePrivate* cloneNode(bool deep = true) override; - QDomNode::NodeType nodeType() const override { return QDomNode::DocumentNode; } - void clear() override; - - // Variables - QExplicitlySharedDataPointer<QDomImplementationPrivate> impl; - QExplicitlySharedDataPointer<QDomDocumentTypePrivate> type; - - void saveDocument(QTextStream& stream, const int indent, QDomNode::EncodingPolicy encUsed) const; - - /* \internal - Counter for the QDomNodeListPrivate timestamps. - - This is a cache optimization, that might in some cases be effective. The - dilemma is that QDomNode::childNodes() returns a list, but the - implementation stores the children in a linked list. Hence, in order to - get the children out through childNodes(), a list must be populated each - time, which is O(N). - - DOM has the requirement of node references being live, see DOM Core - Level 3, 1.1.1 The DOM Structure Model, which means that changes to the - underlying documents must be reflected in node lists. - - This mechanism, nodeListTime, is a caching optimization that reduces the - amount of times the node list is rebuilt, by only doing so when the - document actually changes. However, a change to anywhere in any document - invalidate all lists, since no dependency tracking is done. - - It functions by that all modifying functions(insertBefore() and so on) - increment the count; each QDomNodeListPrivate copies nodeListTime on - construction, and compares its own value to nodeListTime in order to - determine whether it needs to rebuild. - - This is reentrant. The nodeListTime may overflow, but that's ok since we - check for equalness, not whether nodeListTime is smaller than the list's - stored timestamp. - */ - long nodeListTime; -}; - -/************************************************************** - * - * QDomHandler - * - **************************************************************/ - -class QDomHandler : public QXmlDefaultHandler -{ -public: - QDomHandler(QDomDocumentPrivate* d, QXmlSimpleReader *reader, bool namespaceProcessing); - ~QDomHandler(); - - // content handler - bool endDocument() override; - bool startElement(const QString& nsURI, const QString& localName, const QString& qName, const QXmlAttributes& atts) override; - bool endElement(const QString& nsURI, const QString& localName, const QString& qName) override; - bool characters(const QString& ch) override; - bool processingInstruction(const QString& target, const QString& data) override; - bool skippedEntity(const QString& name) override; - - // error handler - bool fatalError(const QXmlParseException& exception) override; - - // lexical handler - bool startCDATA() override; - bool endCDATA() override; - bool startEntity(const QString &) override; - bool endEntity(const QString &) override; - bool startDTD(const QString& name, const QString& publicId, const QString& systemId) override; - bool comment(const QString& ch) override; - - // decl handler - bool externalEntityDecl(const QString &name, const QString &publicId, const QString &systemId) override ; - - // DTD handler - bool notationDecl(const QString & name, const QString & publicId, const QString & systemId) override; - bool unparsedEntityDecl(const QString &name, const QString &publicId, const QString &systemId, const QString ¬ationName) override ; - - void setDocumentLocator(QXmlLocator *locator) override; - - QString errorMsg; - int errorLine; - int errorColumn; - -private: - QDomDocumentPrivate *doc; - QDomNodePrivate *node; - QString entityName; - bool cdata; - bool nsProcessing; - QXmlLocator *locator; - QXmlSimpleReader *reader; -}; - -/************************************************************** - * * Functions for verifying legal data * **************************************************************/ @@ -3052,7 +2550,7 @@ QDomNamedNodeMapPrivate* QDomNamedNodeMapPrivate::clone(QDomNodePrivate* p) m->readonly = readonly; m->appendToParent = appendToParent; - QHash<QString, QDomNodePrivate*>::const_iterator it = map.constBegin(); + auto it = map.constBegin(); for (; it != map.constEnd(); ++it) { QDomNodePrivate *new_node = (*it)->cloneNode(); new_node->setParent(p); @@ -3068,7 +2566,7 @@ void QDomNamedNodeMapPrivate::clearMap() { // Dereference all of our children if we took references if (!appendToParent) { - QHash<QString, QDomNodePrivate *>::const_iterator it = map.constBegin(); + auto it = map.constBegin(); for (; it != map.constEnd(); ++it) if (!(*it)->ref.deref()) delete *it; @@ -3078,13 +2576,13 @@ void QDomNamedNodeMapPrivate::clearMap() QDomNodePrivate* QDomNamedNodeMapPrivate::namedItem(const QString& name) const { - QDomNodePrivate* p = map[name]; - return p; + auto it = map.constFind(name); + return it == map.cend() ? nullptr : *it; } QDomNodePrivate* QDomNamedNodeMapPrivate::namedItemNS(const QString& nsURI, const QString& localName) const { - QHash<QString, QDomNodePrivate *>::const_iterator it = map.constBegin(); + auto it = map.constBegin(); QDomNodePrivate *n; for (; it != map.constEnd(); ++it) { n = *it; @@ -3108,7 +2606,7 @@ QDomNodePrivate* QDomNamedNodeMapPrivate::setNamedItem(QDomNodePrivate* arg) QDomNodePrivate *n = map.value(arg->nodeName()); // We take a reference arg->ref.ref(); - map.insertMulti(arg->nodeName(), arg); + map.insert(arg->nodeName(), arg); return n; } @@ -3125,7 +2623,7 @@ QDomNodePrivate* QDomNamedNodeMapPrivate::setNamedItemNS(QDomNodePrivate* arg) QDomNodePrivate *n = namedItemNS(arg->namespaceURI, arg->name); // We take a reference arg->ref.ref(); - map.insertMulti(arg->nodeName(), arg); + map.insert(arg->nodeName(), arg); return n; } else { // ### check the following code if it is ok @@ -3154,7 +2652,7 @@ QDomNodePrivate* QDomNamedNodeMapPrivate::item(int index) const { if (index >= length() || index < 0) return nullptr; - return *(map.constBegin() + index); + return *std::next(map.cbegin(), index); } int QDomNamedNodeMapPrivate::length() const @@ -3468,10 +2966,10 @@ QDomDocumentTypePrivate::QDomDocumentTypePrivate(QDomDocumentTypePrivate* n, boo while (p) { if (p->isEntity()) // Don't use normal insert function since we would create infinite recursion - entities->map.insertMulti(p->nodeName(), p); + entities->map.insert(p->nodeName(), p); if (p->isNotation()) // Don't use normal insert function since we would create infinite recursion - notations->map.insertMulti(p->nodeName(), p); + notations->map.insert(p->nodeName(), p); p = p->next; } } @@ -3515,9 +3013,9 @@ QDomNodePrivate* QDomDocumentTypePrivate::insertBefore(QDomNodePrivate* newChild QDomNodePrivate* p = QDomNodePrivate::insertBefore(newChild, refChild); // Update the maps if (p && p->isEntity()) - entities->map.insertMulti(p->nodeName(), p); + entities->map.insert(p->nodeName(), p); else if (p && p->isNotation()) - notations->map.insertMulti(p->nodeName(), p); + notations->map.insert(p->nodeName(), p); return p; } @@ -3528,9 +3026,9 @@ QDomNodePrivate* QDomDocumentTypePrivate::insertAfter(QDomNodePrivate* newChild, QDomNodePrivate* p = QDomNodePrivate::insertAfter(newChild, refChild); // Update the maps if (p && p->isEntity()) - entities->map.insertMulti(p->nodeName(), p); + entities->map.insert(p->nodeName(), p); else if (p && p->isNotation()) - notations->map.insertMulti(p->nodeName(), p); + notations->map.insert(p->nodeName(), p); return p; } @@ -3547,9 +3045,9 @@ QDomNodePrivate* QDomDocumentTypePrivate::replaceChild(QDomNodePrivate* newChild notations->map.remove(oldChild->nodeName()); if (p->isEntity()) - entities->map.insertMulti(p->nodeName(), p); + entities->map.insert(p->nodeName(), p); else if (p->isNotation()) - notations->map.insertMulti(p->nodeName(), p); + notations->map.insert(p->nodeName(), p); } return p; @@ -3600,11 +3098,11 @@ void QDomDocumentTypePrivate::save(QTextStream& s, int, int indent) const if (entities->length()>0 || notations->length()>0) { s << " [" << Qt::endl; - QHash<QString, QDomNodePrivate *>::const_iterator it2 = notations->map.constBegin(); + auto it2 = notations->map.constBegin(); for (; it2 != notations->map.constEnd(); ++it2) (*it2)->save(s, 0, indent); - QHash<QString, QDomNodePrivate *>::const_iterator it = entities->map.constBegin(); + auto it = entities->map.constBegin(); for (; it != entities->map.constEnd(); ++it) (*it)->save(s, 0, indent); @@ -4586,11 +4084,11 @@ void QDomElementPrivate::save(QTextStream& s, int depth, int indent) const } s << '<' << qName << nsDecl; - QSet<QString> outputtedPrefixes; /* Write out attributes. */ if (!m_attr->map.isEmpty()) { - QHash<QString, QDomNodePrivate *>::const_iterator it = m_attr->map.constBegin(); + QDuplicateTracker<QString> outputtedPrefixes; + auto it = m_attr->map.constBegin(); for (; it != m_attr->map.constEnd(); ++it) { s << ' '; if (it.value()->namespaceURI.isNull()) { @@ -4610,9 +4108,8 @@ void QDomElementPrivate::save(QTextStream& s, int depth, int indent) const * arrive in those situations. */ if((!it.value()->ownerNode || it.value()->ownerNode->prefix != it.value()->prefix) && - !outputtedPrefixes.contains(it.value()->prefix)) { + !outputtedPrefixes.hasSeen(it.value()->prefix)) { s << " xmlns:" << it.value()->prefix << "=\"" << encodeText(it.value()->namespaceURI, s, true, true) << '\"'; - outputtedPrefixes.insert(it.value()->prefix); } } } @@ -4818,20 +4315,20 @@ void QDomElement::setAttribute(const QString& name, const QString& value) \fn void QDomElement::setAttribute(const QString& name, int value) \overload - The number is formatted according to the current locale. + The formatting always uses QLocale::C. */ /*! \fn void QDomElement::setAttribute(const QString& name, uint value) \overload - The number is formatted according to the current locale. + The formatting always uses QLocale::C. */ /*! \overload - The number is formatted according to the current locale. + The formatting always uses QLocale::C. */ void QDomElement::setAttribute(const QString& name, qlonglong value) { @@ -4845,7 +4342,7 @@ void QDomElement::setAttribute(const QString& name, qlonglong value) /*! \overload - The number is formatted according to the current locale. + The formatting always uses QLocale::C. */ void QDomElement::setAttribute(const QString& name, qulonglong value) { @@ -4859,7 +4356,7 @@ void QDomElement::setAttribute(const QString& name, qulonglong value) /*! \overload - The number is formatted according to the current locale. + The formatting always uses QLocale::C. */ void QDomElement::setAttribute(const QString& name, float value) { @@ -4873,19 +4370,14 @@ void QDomElement::setAttribute(const QString& name, float value) /*! \overload - The number is formatted according to the current locale. + The formatting always uses QLocale::C. */ void QDomElement::setAttribute(const QString& name, double value) { if (!impl) return; QString x; - char buf[256]; - int count = qsnprintf(buf, sizeof(buf), "%.16g", value); - if (count > 0) - x = QString::fromLatin1(buf, count); - else - x.setNum(value); // Fallback + x.setNum(value); IMPL->setAttribute(name, x); } @@ -6201,6 +5693,10 @@ void QDomDocumentPrivate::clear() QDomNodePrivate::clear(); } +#if QT_DEPRECATED_SINCE(5, 15) + +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED static void initializeReader(QXmlSimpleReader &reader, bool namespaceProcessing) { reader.setFeature(QLatin1String("http://xml.org/sax/features/namespaces"), namespaceProcessing); @@ -6234,11 +5730,42 @@ bool QDomDocumentPrivate::setContent(QXmlInputSource *source, QXmlReader *reader if (!reader->parse(source)) { if (errorMsg) - *errorMsg = hnd.errorMsg; + *errorMsg = std::get<0>(hnd.errorInfo()); + if (errorLine) + *errorLine = std::get<1>(hnd.errorInfo()); + if (errorColumn) + *errorColumn = std::get<2>(hnd.errorInfo()); + return false; + } + + return true; +} +QT_WARNING_POP + +#endif // QT_DEPRECATED_SINCE(5, 15) + +bool QDomDocumentPrivate::setContent(QXmlStreamReader *reader, bool namespaceProcessing, + QString *errorMsg, int *errorLine, int *errorColumn) +{ + clear(); + impl = new QDomImplementationPrivate; + type = new QDomDocumentTypePrivate(this, this); + type->ref.deref(); + + if (!reader) { + qWarning("Failed to set content, XML reader is not initialized"); + return false; + } + + QDomParser domParser(this, reader, namespaceProcessing); + + if (!domParser.parse()) { + if (errorMsg) + *errorMsg = std::get<0>(domParser.errorInfo()); if (errorLine) - *errorLine = hnd.errorLine; + *errorLine = std::get<1>(domParser.errorInfo()); if (errorColumn) - *errorColumn = hnd.errorColumn; + *errorColumn = std::get<2>(domParser.errorInfo()); return false; } @@ -6664,9 +6191,19 @@ bool QDomDocument::setContent(const QString& text, bool namespaceProcessing, QSt { if (!impl) impl = new QDomDocumentPrivate(); + +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) && QT_DEPRECATED_SINCE(5, 15) +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED QXmlInputSource source; +QT_WARNING_POP source.setData(text); return IMPL->setContent(&source, namespaceProcessing, errorMsg, errorLine, errorColumn); +#else + QXmlStreamReader streamReader(text); + streamReader.setNamespaceProcessing(namespaceProcessing); + return IMPL->setContent(&streamReader, namespaceProcessing, errorMsg, errorLine, errorColumn); +#endif } /*! @@ -6726,10 +6263,20 @@ bool QDomDocument::setContent(const QByteArray &data, bool namespaceProcessing, { if (!impl) impl = new QDomDocumentPrivate(); + +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) && QT_DEPRECATED_SINCE(5, 15) QBuffer buf; buf.setData(data); +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED QXmlInputSource source(&buf); +QT_WARNING_POP return IMPL->setContent(&source, namespaceProcessing, errorMsg, errorLine, errorColumn); +#else + QXmlStreamReader streamReader(data); + streamReader.setNamespaceProcessing(namespaceProcessing); + return IMPL->setContent(&streamReader, namespaceProcessing, errorMsg, errorLine, errorColumn); +#endif } /*! @@ -6742,18 +6289,32 @@ bool QDomDocument::setContent(QIODevice* dev, bool namespaceProcessing, QString { if (!impl) impl = new QDomDocumentPrivate(); + +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) && QT_DEPRECATED_SINCE(5, 15) +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED QXmlInputSource source(dev); +QT_WARNING_POP return IMPL->setContent(&source, namespaceProcessing, errorMsg, errorLine, errorColumn); +#else + QXmlStreamReader streamReader(dev); + streamReader.setNamespaceProcessing(namespaceProcessing); + return IMPL->setContent(&streamReader, namespaceProcessing, errorMsg, errorLine, errorColumn); +#endif } +#if QT_DEPRECATED_SINCE(5, 15) /*! \overload + \obsolete \since 4.5 This function reads the XML document from the QXmlInputSource \a source, returning true if the content was successfully parsed; otherwise returns \c false. */ +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED bool QDomDocument::setContent(QXmlInputSource *source, bool namespaceProcessing, QString *errorMsg, int *errorLine, int *errorColumn ) { if (!impl) @@ -6762,6 +6323,9 @@ bool QDomDocument::setContent(QXmlInputSource *source, bool namespaceProcessing, initializeReader(reader, namespaceProcessing); return IMPL->setContent(source, &reader, &reader, errorMsg, errorLine, errorColumn); } +QT_WARNING_POP + +#endif /*! \overload @@ -6794,6 +6358,7 @@ bool QDomDocument::setContent(const QByteArray& buffer, QString *errorMsg, int * /*! \overload + \obsolete This function reads the XML document from the IO device \a dev, returning true if the content was successfully parsed; otherwise returns \c false. @@ -6805,8 +6370,10 @@ bool QDomDocument::setContent(QIODevice* dev, QString *errorMsg, int *errorLine, return setContent(dev, false, errorMsg, errorLine, errorColumn); } +#if QT_DEPRECATED_SINCE(5, 15) /*! \overload + \obsolete This function reads the XML document from the QXmlInputSource \a source and parses it with the QXmlReader \a reader, returning true if the content was @@ -6818,12 +6385,44 @@ bool QDomDocument::setContent(QIODevice* dev, QString *errorMsg, int *errorLine, \sa QXmlSimpleReader */ +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED bool QDomDocument::setContent(QXmlInputSource *source, QXmlReader *reader, QString *errorMsg, int *errorLine, int *errorColumn ) { if (!impl) impl = new QDomDocumentPrivate(); return IMPL->setContent(source, reader, nullptr, errorMsg, errorLine, errorColumn); } +QT_WARNING_POP + +#endif + +/*! + \overload + \since 5.15 + + This function reads the XML document from the QXmlStreamReader \a reader + and parses it. Returns \c true if the content was successfully parsed; + otherwise returns \c false. + + If \a namespaceProcessing is \c true, the parser recognizes namespaces in the XML + file and sets the prefix name, local name and namespace URI to appropriate values. + If \a namespaceProcessing is \c false, the parser does no namespace processing when + it reads the XML file. + + If a parse error occurs, the error message is placed in \c{*}\a{errorMsg}, the line + number in \c{*}\a{errorLine} and the column number in \c{*}\a{errorColumn} (unless + the associated pointer is set to 0). + + \sa QXmlStreamReader +*/ +bool QDomDocument::setContent(QXmlStreamReader *reader, bool namespaceProcessing, QString *errorMsg, + int *errorLine, int *errorColumn) +{ + if (!impl) + impl = new QDomDocumentPrivate(); + return IMPL->setContent(reader, namespaceProcessing, errorMsg, errorLine, errorColumn); +} /*! Converts the parsed document back to its textual representation. @@ -7361,200 +6960,6 @@ QDomComment QDomNode::toComment() const return QDomComment(); } -/************************************************************** - * - * QDomHandler - * - **************************************************************/ - -QDomHandler::QDomHandler(QDomDocumentPrivate* adoc, QXmlSimpleReader* areader, bool namespaceProcessing) - : errorLine(0), errorColumn(0), doc(adoc), node(adoc), cdata(false), - nsProcessing(namespaceProcessing), locator(nullptr), reader(areader) -{ -} - -QDomHandler::~QDomHandler() -{ -} - -bool QDomHandler::endDocument() -{ - // ### is this really necessary? (rms) - if (node != doc) - return false; - return true; -} - -bool QDomHandler::startDTD(const QString& name, const QString& publicId, const QString& systemId) -{ - doc->doctype()->name = name; - doc->doctype()->publicId = publicId; - doc->doctype()->systemId = systemId; - return true; -} - -bool QDomHandler::startElement(const QString& nsURI, const QString&, const QString& qName, const QXmlAttributes& atts) -{ - // tag name - QDomNodePrivate* n; - if (nsProcessing) { - n = doc->createElementNS(nsURI, qName); - } else { - n = doc->createElement(qName); - } - - if (!n) - return false; - - n->setLocation(locator->lineNumber(), locator->columnNumber()); - - node->appendChild(n); - node = n; - - // attributes - for (int i=0; i<atts.length(); i++) - { - if (nsProcessing) { - ((QDomElementPrivate*)node)->setAttributeNS(atts.uri(i), atts.qName(i), atts.value(i)); - } else { - ((QDomElementPrivate*)node)->setAttribute(atts.qName(i), atts.value(i)); - } - } - - return true; -} - -bool QDomHandler::endElement(const QString&, const QString&, const QString&) -{ - if (!node || node == doc) - return false; - node = node->parent(); - - return true; -} - -bool QDomHandler::characters(const QString& ch) -{ - // No text as child of some document - if (node == doc) - return false; - - QScopedPointer<QDomNodePrivate> n; - if (cdata) { - n.reset(doc->createCDATASection(ch)); - } else if (!entityName.isEmpty()) { - QScopedPointer<QDomEntityPrivate> e(new QDomEntityPrivate(doc, nullptr, entityName, - QString(), QString(), QString())); - e->value = ch; - e->ref.deref(); - doc->doctype()->appendChild(e.data()); - e.take(); - n.reset(doc->createEntityReference(entityName)); - } else { - n.reset(doc->createTextNode(ch)); - } - n->setLocation(locator->lineNumber(), locator->columnNumber()); - node->appendChild(n.data()); - n.take(); - - return true; -} - -bool QDomHandler::processingInstruction(const QString& target, const QString& data) -{ - QDomNodePrivate *n; - n = doc->createProcessingInstruction(target, data); - if (n) { - n->setLocation(locator->lineNumber(), locator->columnNumber()); - node->appendChild(n); - return true; - } - else - return false; -} - -bool QDomHandler::skippedEntity(const QString& name) -{ - // we can only handle inserting entity references into content - if (reader && !reader->d_ptr->skipped_entity_in_content) - return true; - - QDomNodePrivate *n = doc->createEntityReference(name); - n->setLocation(locator->lineNumber(), locator->columnNumber()); - node->appendChild(n); - return true; -} - -bool QDomHandler::fatalError(const QXmlParseException& exception) -{ - errorMsg = exception.message(); - errorLine = exception.lineNumber(); - errorColumn = exception.columnNumber(); - return QXmlDefaultHandler::fatalError(exception); -} - -bool QDomHandler::startCDATA() -{ - cdata = true; - return true; -} - -bool QDomHandler::endCDATA() -{ - cdata = false; - return true; -} - -bool QDomHandler::startEntity(const QString &name) -{ - entityName = name; - return true; -} - -bool QDomHandler::endEntity(const QString &) -{ - entityName.clear(); - return true; -} - -bool QDomHandler::comment(const QString& ch) -{ - QDomNodePrivate *n; - n = doc->createComment(ch); - n->setLocation(locator->lineNumber(), locator->columnNumber()); - node->appendChild(n); - return true; -} - -bool QDomHandler::unparsedEntityDecl(const QString &name, const QString &publicId, const QString &systemId, const QString ¬ationName) -{ - QDomEntityPrivate* e = new QDomEntityPrivate(doc, nullptr, name, - publicId, systemId, notationName); - // keep the refcount balanced: appendChild() does a ref anyway. - e->ref.deref(); - doc->doctype()->appendChild(e); - return true; -} - -bool QDomHandler::externalEntityDecl(const QString &name, const QString &publicId, const QString &systemId) -{ - return unparsedEntityDecl(name, publicId, systemId, QString()); -} - -bool QDomHandler::notationDecl(const QString & name, const QString & publicId, const QString & systemId) -{ - QDomNotationPrivate* n = new QDomNotationPrivate(doc, nullptr, name, publicId, systemId); - // keep the refcount balanced: appendChild() does a ref anyway. - n->ref.deref(); - doc->doctype()->appendChild(n); - return true; -} - -void QDomHandler::setDocumentLocator(QXmlLocator *locator) -{ - this->locator = locator; -} - QT_END_NAMESPACE #endif // QT_NO_DOM diff --git a/src/xml/dom/qdom.h b/src/xml/dom/qdom.h index 2d07e34f3b..9f34290121 100644 --- a/src/xml/dom/qdom.h +++ b/src/xml/dom/qdom.h @@ -91,6 +91,7 @@ class QDomNode; class QDomEntity; class QDomNotation; class QDomCharacterData; +class QXmlStreamReader; class Q_XML_EXPORT QDomImplementation { @@ -338,11 +339,25 @@ public: bool setContent(const QByteArray& text, bool namespaceProcessing, QString *errorMsg=nullptr, int *errorLine=nullptr, int *errorColumn=nullptr ); bool setContent(const QString& text, bool namespaceProcessing, QString *errorMsg=nullptr, int *errorLine=nullptr, int *errorColumn=nullptr ); bool setContent(QIODevice* dev, bool namespaceProcessing, QString *errorMsg=nullptr, int *errorLine=nullptr, int *errorColumn=nullptr ); +#if QT_DEPRECATED_SINCE(5, 15) +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED + QT_DEPRECATED_X("Use other overloads instead") bool setContent(QXmlInputSource *source, bool namespaceProcessing, QString *errorMsg=nullptr, int *errorLine=nullptr, int *errorColumn=nullptr ); +QT_WARNING_POP +#endif bool setContent(const QByteArray& text, QString *errorMsg=nullptr, int *errorLine=nullptr, int *errorColumn=nullptr ); bool setContent(const QString& text, QString *errorMsg=nullptr, int *errorLine=nullptr, int *errorColumn=nullptr ); bool setContent(QIODevice* dev, QString *errorMsg=nullptr, int *errorLine=nullptr, int *errorColumn=nullptr ); +#if QT_DEPRECATED_SINCE(5, 15) +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED + QT_DEPRECATED_X("Use other overloads instead") bool setContent(QXmlInputSource *source, QXmlReader *reader, QString *errorMsg=nullptr, int *errorLine=nullptr, int *errorColumn=nullptr ); +QT_WARNING_POP +#endif + bool setContent(QXmlStreamReader *reader, bool namespaceProcessing, QString *errorMsg = nullptr, + int *errorLine = nullptr, int *errorColumn = nullptr); // Qt extensions QString toString(int = 1) const; diff --git a/src/xml/dom/qdom_p.h b/src/xml/dom/qdom_p.h new file mode 100644 index 0000000000..a9399d9901 --- /dev/null +++ b/src/xml/dom/qdom_p.h @@ -0,0 +1,540 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtXml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QDOM_P_H +#define QDOM_P_H + +#include "qdom.h" + +#include <qglobal.h> +#include <qhash.h> +#include <qstring.h> +#include <qlist.h> +#include <qxml.h> + +QT_BEGIN_NAMESPACE + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience of +// qxml.cpp and qdom.cpp. This header file may change from version to version without +// notice, or even be removed. +// +// We mean it. +// + +/************************************************************** + * + * Private class declerations + * + **************************************************************/ + +class QDomImplementationPrivate +{ +public: + inline QDomImplementationPrivate() {} + + QDomImplementationPrivate *clone(); + QAtomicInt ref; + static QDomImplementation::InvalidDataPolicy invalidDataPolicy; +}; + +class QDomNodePrivate +{ +public: + QDomNodePrivate(QDomDocumentPrivate *, QDomNodePrivate *parent = nullptr); + QDomNodePrivate(QDomNodePrivate *n, bool deep); + virtual ~QDomNodePrivate(); + + QString nodeName() const { return name; } + QString nodeValue() const { return value; } + virtual void setNodeValue(const QString &v) { value = v; } + + QDomDocumentPrivate *ownerDocument(); + void setOwnerDocument(QDomDocumentPrivate *doc); + + virtual QDomNodePrivate *insertBefore(QDomNodePrivate *newChild, QDomNodePrivate *refChild); + virtual QDomNodePrivate *insertAfter(QDomNodePrivate *newChild, QDomNodePrivate *refChild); + virtual QDomNodePrivate *replaceChild(QDomNodePrivate *newChild, QDomNodePrivate *oldChild); + virtual QDomNodePrivate *removeChild(QDomNodePrivate *oldChild); + virtual QDomNodePrivate *appendChild(QDomNodePrivate *newChild); + + QDomNodePrivate *namedItem(const QString &name); + + virtual QDomNodePrivate *cloneNode(bool deep = true); + virtual void normalize(); + virtual void clear(); + + inline QDomNodePrivate *parent() const { return hasParent ? ownerNode : nullptr; } + inline void setParent(QDomNodePrivate *p) + { + ownerNode = p; + hasParent = true; + } + + void setNoParent() + { + ownerNode = hasParent ? (QDomNodePrivate *)ownerDocument() : nullptr; + hasParent = false; + } + + // Dynamic cast + bool isAttr() const { return nodeType() == QDomNode::AttributeNode; } + bool isCDATASection() const { return nodeType() == QDomNode::CDATASectionNode; } + bool isDocumentFragment() const { return nodeType() == QDomNode::DocumentFragmentNode; } + bool isDocument() const { return nodeType() == QDomNode::DocumentNode; } + bool isDocumentType() const { return nodeType() == QDomNode::DocumentTypeNode; } + bool isElement() const { return nodeType() == QDomNode::ElementNode; } + bool isEntityReference() const { return nodeType() == QDomNode::EntityReferenceNode; } + bool isText() const + { + const QDomNode::NodeType nt = nodeType(); + return (nt == QDomNode::TextNode) || (nt == QDomNode::CDATASectionNode); + } + bool isEntity() const { return nodeType() == QDomNode::EntityNode; } + bool isNotation() const { return nodeType() == QDomNode::NotationNode; } + bool isProcessingInstruction() const + { + return nodeType() == QDomNode::ProcessingInstructionNode; + } + bool isCharacterData() const + { + const QDomNode::NodeType nt = nodeType(); + return (nt == QDomNode::CharacterDataNode) || (nt == QDomNode::TextNode) + || (nt == QDomNode::CommentNode); + } + bool isComment() const { return nodeType() == QDomNode::CommentNode; } + + virtual QDomNode::NodeType nodeType() const { return QDomNode::BaseNode; } + + virtual void save(QTextStream &, int, int) const; + + void setLocation(int lineNumber, int columnNumber); + + // Variables + QAtomicInt ref; + QDomNodePrivate *prev; + QDomNodePrivate *next; + QDomNodePrivate *ownerNode; // either the node's parent or the node's owner document + QDomNodePrivate *first; + QDomNodePrivate *last; + + QString name; // this is the local name if prefix != null + QString value; + QString prefix; // set this only for ElementNode and AttributeNode + QString namespaceURI; // set this only for ElementNode and AttributeNode + bool createdWithDom1Interface : 1; + bool hasParent : 1; + + int lineNumber; + int columnNumber; +}; + +class QDomNodeListPrivate +{ +public: + QDomNodeListPrivate(QDomNodePrivate *); + QDomNodeListPrivate(QDomNodePrivate *, const QString &); + QDomNodeListPrivate(QDomNodePrivate *, const QString &, const QString &); + ~QDomNodeListPrivate(); + + bool operator==(const QDomNodeListPrivate &) const; + bool operator!=(const QDomNodeListPrivate &) const; + + void createList(); + QDomNodePrivate *item(int index); + int length() const; + + QAtomicInt ref; + /* + This list contains the children of this node. + */ + QDomNodePrivate *node_impl; + QString tagname; + QString nsURI; + QList<QDomNodePrivate *> list; + long timestamp; +}; + +class QDomNamedNodeMapPrivate +{ +public: + QDomNamedNodeMapPrivate(QDomNodePrivate *); + ~QDomNamedNodeMapPrivate(); + + QDomNodePrivate *namedItem(const QString &name) const; + QDomNodePrivate *namedItemNS(const QString &nsURI, const QString &localName) const; + QDomNodePrivate *setNamedItem(QDomNodePrivate *arg); + QDomNodePrivate *setNamedItemNS(QDomNodePrivate *arg); + QDomNodePrivate *removeNamedItem(const QString &name); + QDomNodePrivate *item(int index) const; + int length() const; + bool contains(const QString &name) const; + bool containsNS(const QString &nsURI, const QString &localName) const; + + /** + * Remove all children from the map. + */ + void clearMap(); + bool isReadOnly() { return readonly; } + void setReadOnly(bool r) { readonly = r; } + bool isAppendToParent() { return appendToParent; } + /** + * If true, then the node will redirect insert/remove calls + * to its parent by calling QDomNodePrivate::appendChild or removeChild. + * In addition the map won't increase or decrease the reference count + * of the nodes it contains. + * + * By default this value is false and the map will handle reference counting + * by itself. + */ + void setAppendToParent(bool b) { appendToParent = b; } + + /** + * Creates a copy of the map. It is a deep copy + * that means that all children are cloned. + */ + QDomNamedNodeMapPrivate *clone(QDomNodePrivate *parent); + + // Variables + QAtomicInt ref; + QMultiHash<QString, QDomNodePrivate *> map; + QDomNodePrivate *parent; + bool readonly; + bool appendToParent; +}; + +class QDomDocumentTypePrivate : public QDomNodePrivate +{ +public: + QDomDocumentTypePrivate(QDomDocumentPrivate *, QDomNodePrivate *parent = nullptr); + QDomDocumentTypePrivate(QDomDocumentTypePrivate *n, bool deep); + ~QDomDocumentTypePrivate(); + void init(); + + // Reimplemented from QDomNodePrivate + QDomNodePrivate *cloneNode(bool deep = true) override; + QDomNodePrivate *insertBefore(QDomNodePrivate *newChild, QDomNodePrivate *refChild) override; + QDomNodePrivate *insertAfter(QDomNodePrivate *newChild, QDomNodePrivate *refChild) override; + QDomNodePrivate *replaceChild(QDomNodePrivate *newChild, QDomNodePrivate *oldChild) override; + QDomNodePrivate *removeChild(QDomNodePrivate *oldChild) override; + QDomNodePrivate *appendChild(QDomNodePrivate *newChild) override; + + QDomNode::NodeType nodeType() const override { return QDomNode::DocumentTypeNode; } + + void save(QTextStream &s, int, int) const override; + + // Variables + QDomNamedNodeMapPrivate *entities; + QDomNamedNodeMapPrivate *notations; + QString publicId; + QString systemId; + QString internalSubset; +}; + +class QDomDocumentFragmentPrivate : public QDomNodePrivate +{ +public: + QDomDocumentFragmentPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent = nullptr); + QDomDocumentFragmentPrivate(QDomNodePrivate *n, bool deep); + + // Reimplemented from QDomNodePrivate + virtual QDomNodePrivate *cloneNode(bool deep = true) override; + QDomNode::NodeType nodeType() const override { return QDomNode::DocumentFragmentNode; } +}; + +class QDomCharacterDataPrivate : public QDomNodePrivate +{ +public: + QDomCharacterDataPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &data); + QDomCharacterDataPrivate(QDomCharacterDataPrivate *n, bool deep); + + int dataLength() const; + QString substringData(unsigned long offset, unsigned long count) const; + void appendData(const QString &arg); + void insertData(unsigned long offset, const QString &arg); + void deleteData(unsigned long offset, unsigned long count); + void replaceData(unsigned long offset, unsigned long count, const QString &arg); + + // Reimplemented from QDomNodePrivate + QDomNode::NodeType nodeType() const override { return QDomNode::CharacterDataNode; } + QDomNodePrivate *cloneNode(bool deep = true) override; +}; + +class QDomTextPrivate : public QDomCharacterDataPrivate +{ +public: + QDomTextPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &val); + QDomTextPrivate(QDomTextPrivate *n, bool deep); + + QDomTextPrivate *splitText(int offset); + + // Reimplemented from QDomNodePrivate + QDomNodePrivate *cloneNode(bool deep = true) override; + QDomNode::NodeType nodeType() const override { return QDomNode::TextNode; } + virtual void save(QTextStream &s, int, int) const override; +}; + +class QDomAttrPrivate : public QDomNodePrivate +{ +public: + QDomAttrPrivate(QDomDocumentPrivate *, QDomNodePrivate *, const QString &name); + QDomAttrPrivate(QDomDocumentPrivate *, QDomNodePrivate *, const QString &nsURI, + const QString &qName); + QDomAttrPrivate(QDomAttrPrivate *n, bool deep); + + bool specified() const; + + // Reimplemented from QDomNodePrivate + void setNodeValue(const QString &v) override; + QDomNodePrivate *cloneNode(bool deep = true) override; + QDomNode::NodeType nodeType() const override { return QDomNode::AttributeNode; } + virtual void save(QTextStream &s, int, int) const override; + + // Variables + bool m_specified; +}; + +class QDomElementPrivate : public QDomNodePrivate +{ +public: + QDomElementPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &name); + QDomElementPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &nsURI, + const QString &qName); + QDomElementPrivate(QDomElementPrivate *n, bool deep); + ~QDomElementPrivate(); + + QString attribute(const QString &name, const QString &defValue) const; + QString attributeNS(const QString &nsURI, const QString &localName, + const QString &defValue) const; + void setAttribute(const QString &name, const QString &value); + void setAttributeNS(const QString &nsURI, const QString &qName, const QString &newValue); + void removeAttribute(const QString &name); + QDomAttrPrivate *attributeNode(const QString &name); + QDomAttrPrivate *attributeNodeNS(const QString &nsURI, const QString &localName); + QDomAttrPrivate *setAttributeNode(QDomAttrPrivate *newAttr); + QDomAttrPrivate *setAttributeNodeNS(QDomAttrPrivate *newAttr); + QDomAttrPrivate *removeAttributeNode(QDomAttrPrivate *oldAttr); + bool hasAttribute(const QString &name); + bool hasAttributeNS(const QString &nsURI, const QString &localName); + + QString text(); + + // Reimplemented from QDomNodePrivate + QDomNamedNodeMapPrivate *attributes() { return m_attr; } + bool hasAttributes() { return (m_attr->length() > 0); } + QDomNode::NodeType nodeType() const override { return QDomNode::ElementNode; } + QDomNodePrivate *cloneNode(bool deep = true) override; + virtual void save(QTextStream &s, int, int) const override; + + // Variables + QDomNamedNodeMapPrivate *m_attr; +}; + +class QDomCommentPrivate : public QDomCharacterDataPrivate +{ +public: + QDomCommentPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &val); + QDomCommentPrivate(QDomCommentPrivate *n, bool deep); + + // Reimplemented from QDomNodePrivate + QDomNodePrivate *cloneNode(bool deep = true) override; + QDomNode::NodeType nodeType() const override { return QDomNode::CommentNode; } + virtual void save(QTextStream &s, int, int) const override; +}; + +class QDomCDATASectionPrivate : public QDomTextPrivate +{ +public: + QDomCDATASectionPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &val); + QDomCDATASectionPrivate(QDomCDATASectionPrivate *n, bool deep); + + // Reimplemented from QDomNodePrivate + QDomNodePrivate *cloneNode(bool deep = true) override; + QDomNode::NodeType nodeType() const override { return QDomNode::CDATASectionNode; } + virtual void save(QTextStream &s, int, int) const override; +}; + +class QDomNotationPrivate : public QDomNodePrivate +{ +public: + QDomNotationPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &name, + const QString &pub, const QString &sys); + QDomNotationPrivate(QDomNotationPrivate *n, bool deep); + + // Reimplemented from QDomNodePrivate + QDomNodePrivate *cloneNode(bool deep = true) override; + QDomNode::NodeType nodeType() const override { return QDomNode::NotationNode; } + virtual void save(QTextStream &s, int, int) const override; + + // Variables + QString m_sys; + QString m_pub; +}; + +class QDomEntityPrivate : public QDomNodePrivate +{ +public: + QDomEntityPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &name, + const QString &pub, const QString &sys, const QString ¬ation); + QDomEntityPrivate(QDomEntityPrivate *n, bool deep); + + // Reimplemented from QDomNodePrivate + QDomNodePrivate *cloneNode(bool deep = true) override; + QDomNode::NodeType nodeType() const override { return QDomNode::EntityNode; } + virtual void save(QTextStream &s, int, int) const override; + + // Variables + QString m_sys; + QString m_pub; + QString m_notationName; +}; + +class QDomEntityReferencePrivate : public QDomNodePrivate +{ +public: + QDomEntityReferencePrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &name); + QDomEntityReferencePrivate(QDomNodePrivate *n, bool deep); + + // Reimplemented from QDomNodePrivate + QDomNodePrivate *cloneNode(bool deep = true) override; + QDomNode::NodeType nodeType() const override { return QDomNode::EntityReferenceNode; } + virtual void save(QTextStream &s, int, int) const override; +}; + +class QDomProcessingInstructionPrivate : public QDomNodePrivate +{ +public: + QDomProcessingInstructionPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, + const QString &target, const QString &data); + QDomProcessingInstructionPrivate(QDomProcessingInstructionPrivate *n, bool deep); + + // Reimplemented from QDomNodePrivate + QDomNodePrivate *cloneNode(bool deep = true) override; + QDomNode::NodeType nodeType() const override { return QDomNode::ProcessingInstructionNode; } + virtual void save(QTextStream &s, int, int) const override; +}; + +class QDomDocumentPrivate : public QDomNodePrivate +{ +public: + QDomDocumentPrivate(); + QDomDocumentPrivate(const QString &name); + QDomDocumentPrivate(QDomDocumentTypePrivate *dt); + QDomDocumentPrivate(QDomDocumentPrivate *n, bool deep); + ~QDomDocumentPrivate(); + +#if QT_DEPRECATED_SINCE(5, 15) +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED + bool setContent(QXmlInputSource *source, bool namespaceProcessing, QString *errorMsg, + int *errorLine, int *errorColumn); + bool setContent(QXmlInputSource *source, QXmlReader *reader, QXmlSimpleReader *simpleReader, + QString *errorMsg, int *errorLine, int *errorColumn); +QT_WARNING_POP +#endif + bool setContent(QXmlStreamReader *reader, bool namespaceProcessing, QString *errorMsg, + int *errorLine, int *errorColumn); + + // Attributes + QDomDocumentTypePrivate *doctype() { return type.data(); } + QDomImplementationPrivate *implementation() { return impl.data(); } + QDomElementPrivate *documentElement(); + + // Factories + QDomElementPrivate *createElement(const QString &tagName); + QDomElementPrivate *createElementNS(const QString &nsURI, const QString &qName); + QDomDocumentFragmentPrivate *createDocumentFragment(); + QDomTextPrivate *createTextNode(const QString &data); + QDomCommentPrivate *createComment(const QString &data); + QDomCDATASectionPrivate *createCDATASection(const QString &data); + QDomProcessingInstructionPrivate *createProcessingInstruction(const QString &target, + const QString &data); + QDomAttrPrivate *createAttribute(const QString &name); + QDomAttrPrivate *createAttributeNS(const QString &nsURI, const QString &qName); + QDomEntityReferencePrivate *createEntityReference(const QString &name); + + QDomNodePrivate *importNode(QDomNodePrivate *importedNode, bool deep); + + // Reimplemented from QDomNodePrivate + QDomNodePrivate *cloneNode(bool deep = true) override; + QDomNode::NodeType nodeType() const override { return QDomNode::DocumentNode; } + void clear() override; + + // Variables + QExplicitlySharedDataPointer<QDomImplementationPrivate> impl; + QExplicitlySharedDataPointer<QDomDocumentTypePrivate> type; + + void saveDocument(QTextStream &stream, const int indent, + QDomNode::EncodingPolicy encUsed) const; + + /* \internal + Counter for the QDomNodeListPrivate timestamps. + + This is a cache optimization, that might in some cases be effective. The + dilemma is that QDomNode::childNodes() returns a list, but the + implementation stores the children in a linked list. Hence, in order to + get the children out through childNodes(), a list must be populated each + time, which is O(N). + + DOM has the requirement of node references being live, see DOM Core + Level 3, 1.1.1 The DOM Structure Model, which means that changes to the + underlying documents must be reflected in node lists. + + This mechanism, nodeListTime, is a caching optimization that reduces the + amount of times the node list is rebuilt, by only doing so when the + document actually changes. However, a change to anywhere in any document + invalidate all lists, since no dependency tracking is done. + + It functions by that all modifying functions(insertBefore() and so on) + increment the count; each QDomNodeListPrivate copies nodeListTime on + construction, and compares its own value to nodeListTime in order to + determine whether it needs to rebuild. + + This is reentrant. The nodeListTime may overflow, but that's ok since we + check for equalness, not whether nodeListTime is smaller than the list's + stored timestamp. + */ + long nodeListTime; +}; + +QT_END_NAMESPACE + +#endif // QDOMHELPERS_P_H diff --git a/src/xml/dom/qdomhelpers.cpp b/src/xml/dom/qdomhelpers.cpp new file mode 100644 index 0000000000..10e37f7c0f --- /dev/null +++ b/src/xml/dom/qdomhelpers.cpp @@ -0,0 +1,663 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtXml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdomhelpers_p.h" +#include "qdom_p.h" +#include "qxmlstream.h" +#include "private/qxml_p.h" + +QT_BEGIN_NAMESPACE + +#if QT_DEPRECATED_SINCE(5, 15) + +/************************************************************** + * + * QDomHandler + * + **************************************************************/ +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED +QDomHandler::QDomHandler(QDomDocumentPrivate *adoc, QXmlSimpleReader *areader, + bool namespaceProcessing) + : cdata(false), reader(areader), domBuilder(adoc, &locator, namespaceProcessing) +{ +} + +QDomHandler::~QDomHandler() {} + +bool QDomHandler::endDocument() +{ + return domBuilder.endDocument(); +} + +bool QDomHandler::startDTD(const QString &name, const QString &publicId, const QString &systemId) +{ + return domBuilder.startDTD(name, publicId, systemId); +} + +bool QDomHandler::startElement(const QString &nsURI, const QString &, const QString &qName, + const QXmlAttributes &atts) +{ + return domBuilder.startElement(nsURI, qName, atts); +} + +bool QDomHandler::endElement(const QString &, const QString &, const QString &) +{ + return domBuilder.endElement(); +} + +bool QDomHandler::characters(const QString &ch) +{ + return domBuilder.characters(ch, cdata); +} + +bool QDomHandler::processingInstruction(const QString &target, const QString &data) +{ + return domBuilder.processingInstruction(target, data); +} + +bool QDomHandler::skippedEntity(const QString &name) +{ + // we can only handle inserting entity references into content + if (reader && !reader->d_ptr->skipped_entity_in_content) + return true; + + return domBuilder.skippedEntity(name); +} + +bool QDomHandler::fatalError(const QXmlParseException &exception) +{ + domBuilder.errorMsg = exception.message(); + domBuilder.errorLine = exception.lineNumber(); + domBuilder.errorColumn = exception.columnNumber(); + return QXmlDefaultHandler::fatalError(exception); +} + +bool QDomHandler::startCDATA() +{ + cdata = true; + return true; +} + +bool QDomHandler::endCDATA() +{ + cdata = false; + return true; +} + +bool QDomHandler::startEntity(const QString &name) +{ + return domBuilder.startEntity(name); +} + +bool QDomHandler::endEntity(const QString &) +{ + return domBuilder.endEntity(); +} + +bool QDomHandler::comment(const QString &ch) +{ + return domBuilder.comment(ch); +} + +bool QDomHandler::unparsedEntityDecl(const QString &name, const QString &publicId, + const QString &systemId, const QString ¬ationName) +{ + return domBuilder.unparsedEntityDecl(name, publicId, systemId, notationName); +} + +bool QDomHandler::externalEntityDecl(const QString &name, const QString &publicId, + const QString &systemId) +{ + return unparsedEntityDecl(name, publicId, systemId, QString()); +} + +bool QDomHandler::notationDecl(const QString &name, const QString &publicId, + const QString &systemId) +{ + return domBuilder.notationDecl(name, publicId, systemId); +} + +void QDomHandler::setDocumentLocator(QXmlLocator *locator) +{ + this->locator.setLocator(locator); +} + +QDomBuilder::ErrorInfo QDomHandler::errorInfo() const +{ + return domBuilder.error(); +} +QT_WARNING_POP + +#endif // QT_DEPRECATED_SINCE(5, 15) + +/************************************************************** + * + * QXmlDocumentLocators + * + **************************************************************/ + +int QDomDocumentLocator::column() const +{ + Q_ASSERT(reader); + return static_cast<int>(reader->columnNumber()); +} + +int QDomDocumentLocator::line() const +{ + Q_ASSERT(reader); + return static_cast<int>(reader->lineNumber()); +} + +#if QT_DEPRECATED_SINCE(5, 15) + +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED +void QSAXDocumentLocator::setLocator(QXmlLocator *l) +{ + locator = l; +} +QT_WARNING_POP + +int QSAXDocumentLocator::column() const +{ + if (!locator) + return 0; + + return static_cast<int>(locator->columnNumber()); +} + +int QSAXDocumentLocator::line() const +{ + if (!locator) + return 0; + + return static_cast<int>(locator->lineNumber()); +} + +#endif // QT_DEPRECATED_SINCE(5, 15) + +/************************************************************** + * + * QDomBuilder + * + **************************************************************/ + +QDomBuilder::QDomBuilder(QDomDocumentPrivate *d, QXmlDocumentLocator *l, bool namespaceProcessing) + : errorLine(0), + errorColumn(0), + doc(d), + node(d), + locator(l), + nsProcessing(namespaceProcessing) +{ +} + +QDomBuilder::~QDomBuilder() {} + +bool QDomBuilder::endDocument() +{ + // ### is this really necessary? (rms) + if (node != doc) + return false; + return true; +} + +bool QDomBuilder::startDTD(const QString &name, const QString &publicId, const QString &systemId) +{ + doc->doctype()->name = name; + doc->doctype()->publicId = publicId; + doc->doctype()->systemId = systemId; + return true; +} + +#if QT_DEPRECATED_SINCE(5, 15) + +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED +bool QDomBuilder::startElement(const QString &nsURI, const QString &qName, + const QXmlAttributes &atts) +{ + // tag name + QDomNodePrivate *n; + if (nsProcessing) { + n = doc->createElementNS(nsURI, qName); + } else { + n = doc->createElement(qName); + } + + if (!n) + return false; + + n->setLocation(locator->line(), locator->column()); + + node->appendChild(n); + node = n; + + // attributes + for (int i = 0; i < atts.length(); i++) { + auto domElement = static_cast<QDomElementPrivate *>(node); + if (nsProcessing) + domElement->setAttributeNS(atts.uri(i), atts.qName(i), atts.value(i)); + else + domElement->setAttribute(atts.qName(i), atts.value(i)); + } + + return true; +} +QT_WARNING_POP + +#endif // QT_DEPRECATED_SINCE(5, 15) + +inline QString stringRefToString(const QStringRef &stringRef) +{ + // Calling QStringRef::toString() on a NULL QStringRef in some cases returns + // an empty string (i.e. QString("")) instead of a NULL string (i.e. QString()). + // QDom implementation differentiates between NULL and empty strings, so + // we need this as workaround to keep the current behavior unchanged. + return stringRef.isNull() ? QString() : stringRef.toString(); +} + +bool QDomBuilder::startElement(const QString &nsURI, const QString &qName, + const QXmlStreamAttributes &atts) +{ + QDomNodePrivate *n = + nsProcessing ? doc->createElementNS(nsURI, qName) : doc->createElement(qName); + if (!n) + return false; + + n->setLocation(locator->line(), locator->column()); + + node->appendChild(n); + node = n; + + // attributes + for (const auto &attr : atts) { + auto domElement = static_cast<QDomElementPrivate *>(node); + if (nsProcessing) { + domElement->setAttributeNS(stringRefToString(attr.namespaceUri()), + stringRefToString(attr.qualifiedName()), + stringRefToString(attr.value())); + } else { + domElement->setAttribute(stringRefToString(attr.qualifiedName()), + stringRefToString(attr.value())); + } + } + + return true; +} + +bool QDomBuilder::endElement() +{ + if (!node || node == doc) + return false; + node = node->parent(); + + return true; +} + +bool QDomBuilder::characters(const QString &characters, bool cdata) +{ + // No text as child of some document + if (node == doc) + return false; + + QScopedPointer<QDomNodePrivate> n; + if (cdata) { + n.reset(doc->createCDATASection(characters)); + } else if (!entityName.isEmpty()) { + QScopedPointer<QDomEntityPrivate> e( + new QDomEntityPrivate(doc, nullptr, entityName, QString(), QString(), QString())); + e->value = characters; + e->ref.deref(); + doc->doctype()->appendChild(e.data()); + e.take(); + n.reset(doc->createEntityReference(entityName)); + } else { + n.reset(doc->createTextNode(characters)); + } + n->setLocation(locator->line(), locator->column()); + node->appendChild(n.data()); + n.take(); + + return true; +} + +bool QDomBuilder::processingInstruction(const QString &target, const QString &data) +{ + QDomNodePrivate *n; + n = doc->createProcessingInstruction(target, data); + if (n) { + n->setLocation(locator->line(), locator->column()); + node->appendChild(n); + return true; + } else + return false; +} + +bool QDomBuilder::skippedEntity(const QString &name) +{ + QDomNodePrivate *n = doc->createEntityReference(name); + n->setLocation(locator->line(), locator->column()); + node->appendChild(n); + return true; +} + +void QDomBuilder::fatalError(const QString &message) +{ + errorMsg = message; + errorLine = static_cast<int>(locator->line()); + errorColumn = static_cast<int>(locator->column()); +} + +QDomBuilder::ErrorInfo QDomBuilder::error() const +{ + return ErrorInfo(errorMsg, errorLine, errorColumn); +} + +bool QDomBuilder::startEntity(const QString &name) +{ + entityName = name; + return true; +} + +bool QDomBuilder::endEntity() +{ + entityName.clear(); + return true; +} + +bool QDomBuilder::comment(const QString &characters) +{ + QDomNodePrivate *n; + n = doc->createComment(characters); + n->setLocation(locator->line(), locator->column()); + node->appendChild(n); + return true; +} + +bool QDomBuilder::unparsedEntityDecl(const QString &name, const QString &publicId, + const QString &systemId, const QString ¬ationName) +{ + QDomEntityPrivate *e = + new QDomEntityPrivate(doc, nullptr, name, publicId, systemId, notationName); + // keep the refcount balanced: appendChild() does a ref anyway. + e->ref.deref(); + doc->doctype()->appendChild(e); + return true; +} + +bool QDomBuilder::externalEntityDecl(const QString &name, const QString &publicId, + const QString &systemId) +{ + return unparsedEntityDecl(name, publicId, systemId, QString()); +} + +bool QDomBuilder::notationDecl(const QString &name, const QString &publicId, + const QString &systemId) +{ + QDomNotationPrivate *n = new QDomNotationPrivate(doc, nullptr, name, publicId, systemId); + // keep the refcount balanced: appendChild() does a ref anyway. + n->ref.deref(); + doc->doctype()->appendChild(n); + return true; +} + +/************************************************************** + * + * QDomParser + * + **************************************************************/ + +QDomParser::QDomParser(QDomDocumentPrivate *d, QXmlStreamReader *r, bool namespaceProcessing) + : reader(r), locator(r), domBuilder(d, &locator, namespaceProcessing) +{ +} + +bool QDomParser::parse() +{ + return parseProlog() && parseBody(); +} + +QDomBuilder::ErrorInfo QDomParser::errorInfo() const +{ + return domBuilder.error(); +} + +bool QDomParser::parseProlog() +{ + Q_ASSERT(reader); + + bool foundDtd = false; + + while (!reader->atEnd()) { + reader->readNext(); + + if (reader->hasError()) { + domBuilder.fatalError(reader->errorString()); + return false; + } + + switch (reader->tokenType()) { + case QXmlStreamReader::StartDocument: + if (!reader->documentVersion().isEmpty()) { + QString value(QLatin1String("version='")); + value += reader->documentVersion(); + value += QLatin1Char('\''); + if (!reader->documentEncoding().isEmpty()) { + value += QLatin1String(" encoding='"); + value += reader->documentEncoding(); + value += QLatin1Char('\''); + } + if (reader->isStandaloneDocument()) { + value += QLatin1String(" standalone='yes'"); + } else { + // TODO: Add standalone='no', if 'standalone' is specified. With the current + // QXmlStreamReader there is no way to figure out if it was specified or not. + // QXmlStreamReader needs to be modified for handling that case correctly. + } + + if (!domBuilder.processingInstruction(QLatin1String("xml"), value)) { + domBuilder.fatalError( + QDomParser::tr("Error occurred while processing XML declaration")); + return false; + } + } + break; + case QXmlStreamReader::DTD: + if (foundDtd) { + domBuilder.fatalError(QDomParser::tr("Multiple DTD sections are not allowed")); + return false; + } + foundDtd = true; + + if (!domBuilder.startDTD(stringRefToString(reader->dtdName()), + stringRefToString(reader->dtdPublicId()), + stringRefToString(reader->dtdSystemId()))) { + domBuilder.fatalError( + QDomParser::tr("Error occurred while processing document type declaration")); + return false; + } + if (!parseMarkupDecl()) + return false; + break; + case QXmlStreamReader::Comment: + if (!domBuilder.comment(reader->text().toString())) { + domBuilder.fatalError(QDomParser::tr("Error occurred while processing comment")); + return false; + } + break; + case QXmlStreamReader::ProcessingInstruction: + if (!domBuilder.processingInstruction(reader->processingInstructionTarget().toString(), + reader->processingInstructionData().toString())) { + domBuilder.fatalError( + QDomParser::tr("Error occurred while processing a processing instruction")); + return false; + } + break; + default: + // If the token is none of the above, prolog processing is done. + return true; + } + } + + return true; +} + +bool QDomParser::parseBody() +{ + Q_ASSERT(reader); + + std::stack<QStringRef> tagStack; + while (!reader->atEnd() && !reader->hasError()) { + switch (reader->tokenType()) { + case QXmlStreamReader::StartElement: + tagStack.push(reader->qualifiedName()); + if (!domBuilder.startElement(stringRefToString(reader->namespaceUri()), + stringRefToString(reader->qualifiedName()), + reader->attributes())) { + domBuilder.fatalError( + QDomParser::tr("Error occurred while processing a start element")); + return false; + } + break; + case QXmlStreamReader::EndElement: + if (tagStack.empty() || reader->qualifiedName() != tagStack.top()) { + domBuilder.fatalError( + QDomParser::tr("Unexpected end element '%1'").arg(reader->name())); + return false; + } + tagStack.pop(); + if (!domBuilder.endElement()) { + domBuilder.fatalError( + QDomParser::tr("Error occurred while processing an end element")); + return false; + } + break; + case QXmlStreamReader::Characters: + if (!reader->isWhitespace()) { // Skip the content consisting of only whitespaces + if (!reader->text().toString().trimmed().isEmpty()) { + if (!domBuilder.characters(reader->text().toString(), reader->isCDATA())) { + domBuilder.fatalError(QDomParser::tr( + "Error occurred while processing the element content")); + return false; + } + } + } + break; + case QXmlStreamReader::Comment: + if (!domBuilder.comment(reader->text().toString())) { + domBuilder.fatalError(QDomParser::tr("Error occurred while processing comments")); + return false; + } + break; + case QXmlStreamReader::ProcessingInstruction: + if (!domBuilder.processingInstruction(reader->processingInstructionTarget().toString(), + reader->processingInstructionData().toString())) { + domBuilder.fatalError( + QDomParser::tr("Error occurred while processing a processing instruction")); + return false; + } + break; + case QXmlStreamReader::EntityReference: + if (!domBuilder.skippedEntity(reader->name().toString())) { + domBuilder.fatalError( + QDomParser::tr("Error occurred while processing an entity reference")); + return false; + } + break; + default: + domBuilder.fatalError(QDomParser::tr("Unexpected token")); + return false; + } + + reader->readNext(); + } + + if (reader->hasError()) { + domBuilder.fatalError(reader->errorString()); + reader->readNext(); + return false; + } + + if (!tagStack.empty()) { + domBuilder.fatalError(QDomParser::tr("Tag mismatch")); + return false; + } + + return true; +} + +bool QDomParser::parseMarkupDecl() +{ + Q_ASSERT(reader); + + const auto entities = reader->entityDeclarations(); + for (const auto &entityDecl : entities) { + // Entity declarations are created only for Extrenal Entities. Internal Entities + // are parsed, and QXmlStreamReader handles the parsing itself and returns the + // parsed result. So we don't need to do anything for the Internal Entities. + if (!entityDecl.publicId().isEmpty() || !entityDecl.systemId().isEmpty()) { + // External Entity + if (!domBuilder.unparsedEntityDecl(stringRefToString(entityDecl.name()), + stringRefToString(entityDecl.publicId()), + stringRefToString(entityDecl.systemId()), + stringRefToString(entityDecl.notationName()))) { + domBuilder.fatalError( + QDomParser::tr("Error occurred while processing entity declaration")); + return false; + } + } + } + + const auto notations = reader->notationDeclarations(); + for (const auto ¬ationDecl : notations) { + if (!domBuilder.notationDecl(stringRefToString(notationDecl.name()), + stringRefToString(notationDecl.publicId()), + stringRefToString(notationDecl.systemId()))) { + domBuilder.fatalError( + QDomParser::tr("Error occurred while processing notation declaration")); + return false; + } + } + + return true; +} + +QT_END_NAMESPACE diff --git a/src/xml/dom/qdomhelpers_p.h b/src/xml/dom/qdomhelpers_p.h new file mode 100644 index 0000000000..4de18f7d4d --- /dev/null +++ b/src/xml/dom/qdomhelpers_p.h @@ -0,0 +1,258 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtXml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QDOMHELPERS_P_H +#define QDOMHELPERS_P_H + +#include <qcoreapplication.h> +#include <qglobal.h> +#include <qxml.h> + +QT_BEGIN_NAMESPACE + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience of +// qxml.cpp and qdom.cpp. This header file may change from version to version without +// notice, or even be removed. +// +// We mean it. +// + +class QDomDocumentPrivate; +class QDomNodePrivate; +class QXmlStreamReader; +class QXmlStreamAttributes; + +/************************************************************** + * + * QXmlDocumentLocators + * + **************************************************************/ + +/* TODO: QXmlDocumentLocator can be removed when the SAX-based + * implementation is removed. Right now it is needed for QDomBuilder + * to work with both QXmlStreamReader and QXmlInputSource (SAX) + * based implementations. + */ +class QXmlDocumentLocator +{ +public: + virtual ~QXmlDocumentLocator() = default; + virtual int column() const = 0; + virtual int line() const = 0; +}; + +class QDomDocumentLocator : public QXmlDocumentLocator +{ +public: + QDomDocumentLocator(QXmlStreamReader *r) : reader(r) {} + ~QDomDocumentLocator() override = default; + + int column() const override; + int line() const override; + +private: + QXmlStreamReader *reader; +}; + +#if QT_DEPRECATED_SINCE(5, 15) + +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED + +class QSAXDocumentLocator : public QXmlDocumentLocator +{ +public: + ~QSAXDocumentLocator() override = default; + + int column() const override; + int line() const override; + + void setLocator(QXmlLocator *l); + +private: + QXmlLocator *locator = nullptr; +}; + +QT_WARNING_POP + +#endif + +/************************************************************** + * + * QDomBuilder + * + **************************************************************/ + +class QDomBuilder +{ +public: + QDomBuilder(QDomDocumentPrivate *d, QXmlDocumentLocator *l, bool namespaceProcessing); + ~QDomBuilder(); + + bool endDocument(); +#if QT_DEPRECATED_SINCE(5, 15) +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED + bool startElement(const QString &nsURI, const QString &qName, const QXmlAttributes &atts); +QT_WARNING_POP +#endif + bool startElement(const QString &nsURI, const QString &qName, const QXmlStreamAttributes &atts); + bool endElement(); + bool characters(const QString &characters, bool cdata = false); + bool processingInstruction(const QString &target, const QString &data); + bool skippedEntity(const QString &name); + bool startEntity(const QString &name); + bool endEntity(); + bool startDTD(const QString &name, const QString &publicId, const QString &systemId); + bool comment(const QString &characters); + bool externalEntityDecl(const QString &name, const QString &publicId, const QString &systemId); + bool notationDecl(const QString &name, const QString &publicId, const QString &systemId); + bool unparsedEntityDecl(const QString &name, const QString &publicId, const QString &systemId, + const QString ¬ationName); + + void fatalError(const QString &message); + + using ErrorInfo = std::tuple<QString, int, int>; + ErrorInfo error() const; + + QString errorMsg; + int errorLine; + int errorColumn; + +private: + QDomDocumentPrivate *doc; + QDomNodePrivate *node; + QXmlDocumentLocator *locator; + QString entityName; + bool nsProcessing; +}; + +#if QT_DEPRECATED_SINCE(5, 15) + +/************************************************************** + * + * QDomHandler + * + **************************************************************/ + +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED + +class QDomHandler : public QXmlDefaultHandler +{ +public: + QDomHandler(QDomDocumentPrivate *d, QXmlSimpleReader *reader, bool namespaceProcessing); + ~QDomHandler() override; + + // content handler + bool endDocument() override; + bool startElement(const QString &nsURI, const QString &localName, const QString &qName, + const QXmlAttributes &atts) override; + bool endElement(const QString &nsURI, const QString &localName, const QString &qName) override; + bool characters(const QString &ch) override; + bool processingInstruction(const QString &target, const QString &data) override; + bool skippedEntity(const QString &name) override; + + // error handler + bool fatalError(const QXmlParseException &exception) override; + + // lexical handler + bool startCDATA() override; + bool endCDATA() override; + bool startEntity(const QString &) override; + bool endEntity(const QString &) override; + bool startDTD(const QString &name, const QString &publicId, const QString &systemId) override; + bool comment(const QString &ch) override; + + // decl handler + bool externalEntityDecl(const QString &name, const QString &publicId, + const QString &systemId) override; + + // DTD handler + bool notationDecl(const QString &name, const QString &publicId, + const QString &systemId) override; + bool unparsedEntityDecl(const QString &name, const QString &publicId, const QString &systemId, + const QString ¬ationName) override; + + void setDocumentLocator(QXmlLocator *locator) override; + + QDomBuilder::ErrorInfo errorInfo() const; + +private: + bool cdata; + QXmlSimpleReader *reader; + QSAXDocumentLocator locator; + QDomBuilder domBuilder; +}; + +QT_WARNING_POP + +#endif // QT_DEPRECATED_SINCE(5, 15) + +/************************************************************** + * + * QDomParser + * + **************************************************************/ + +class QDomParser +{ + Q_DECLARE_TR_FUNCTIONS(QDomParser) +public: + QDomParser(QDomDocumentPrivate *d, QXmlStreamReader *r, bool namespaceProcessing); + + bool parse(); + QDomBuilder::ErrorInfo errorInfo() const; + +private: + bool parseProlog(); + bool parseBody(); + bool parseMarkupDecl(); + + QXmlStreamReader *reader; + QDomDocumentLocator locator; + QDomBuilder domBuilder; +}; + +QT_END_NAMESPACE + +#endif // QDOMHELPERS_P_H diff --git a/src/xml/qtxmlglobal.h b/src/xml/qtxmlglobal.h index ed5de8db87..1ce3008f4a 100644 --- a/src/xml/qtxmlglobal.h +++ b/src/xml/qtxmlglobal.h @@ -3,7 +3,7 @@ ** Copyright (C) 2016 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the QtXml module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/xml/sax/qxml.cpp b/src/xml/sax/qxml.cpp index 1993073cce..0033d042d4 100644 --- a/src/xml/sax/qxml.cpp +++ b/src/xml/sax/qxml.cpp @@ -51,6 +51,7 @@ #include "qstack.h" #include <qdebug.h> +#if QT_DEPRECATED_SINCE(5, 15) #ifdef Q_CC_BOR // borland 6 finds bogus warnings when building this file in uic3 # pragma warn -8080 @@ -284,6 +285,7 @@ class QXmlDefaultHandlerPrivate /*! \class QXmlParseException + \obsolete \reentrant \brief The QXmlParseException class is used to report errors with the QXmlErrorHandler interface. @@ -403,6 +405,7 @@ QString QXmlParseException::systemId() const /*! \class QXmlLocator + \obsolete \reentrant \brief The QXmlLocator class provides the XML handler classes with information about the parsing position within a file. @@ -445,6 +448,9 @@ QXmlLocator::~QXmlLocator() number available. */ +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED + class QXmlSimpleReaderLocator : public QXmlLocator { public: @@ -497,6 +503,7 @@ public: /*! \class QXmlNamespaceSupport + \obsolete \since 4.4 \reentrant \brief The QXmlNamespaceSupport class is a helper class for XML @@ -745,6 +752,7 @@ void QXmlNamespaceSupport::reset() /*! \class QXmlAttributes + \obsolete \reentrant \brief The QXmlAttributes class provides XML attributes. @@ -1028,6 +1036,7 @@ void QXmlAttributes::append(const QString &qName, const QString &uri, const QStr /*! \class QXmlInputSource + \obsolete \reentrant \brief The QXmlInputSource class provides the input data for the QXmlReader subclasses. @@ -1446,6 +1455,7 @@ QString QXmlInputSource::fromRawData(const QByteArray &data, bool beginning) /*! \class QXmlContentHandler + \obsolete \reentrant \brief The QXmlContentHandler class provides an interface to report the logical content of XML data. @@ -1688,6 +1698,7 @@ QString QXmlInputSource::fromRawData(const QByteArray &data, bool beginning) /*! \class QXmlErrorHandler + \obsolete \reentrant \brief The QXmlErrorHandler class provides an interface to report errors in XML data. @@ -1763,6 +1774,7 @@ events are reported. /*! \class QXmlDTDHandler + \obsolete \reentrant \brief The QXmlDTDHandler class provides an interface to report DTD content of XML data. @@ -1830,6 +1842,7 @@ events are reported. /*! \class QXmlEntityResolver + \obsolete \reentrant \brief The QXmlEntityResolver class provides an interface to resolve external entities contained in XML data. @@ -1886,6 +1899,7 @@ events are reported. /*! \class QXmlLexicalHandler + \obsolete \reentrant \brief The QXmlLexicalHandler class provides an interface to report the lexical content of XML data. @@ -2037,6 +2051,7 @@ events are reported. /*! \class QXmlDeclHandler + \obsolete \reentrant \brief The QXmlDeclHandler class provides an interface to report declaration content of XML data. @@ -2124,6 +2139,7 @@ events are reported. /*! \class QXmlDefaultHandler + \obsolete \reentrant \brief The QXmlDefaultHandler class provides a default implementation of all the XML handler classes. @@ -2558,6 +2574,7 @@ void QXmlSimpleReaderPrivate::initIncrementalParsing() /*! \class QXmlReader + \obsolete \reentrant \brief The QXmlReader class provides an interface for XML readers (i.e. parsers). @@ -2597,6 +2614,9 @@ void QXmlSimpleReaderPrivate::initIncrementalParsing() setDeclHandler(). The parse itself is started with a call to parse(). + Note that this class is now deprecated, please use QXmlStreamReader or + QDomDocument for reading XML files. + \sa QXmlSimpleReader */ @@ -2783,6 +2803,7 @@ void QXmlSimpleReaderPrivate::initIncrementalParsing() /*! \class QXmlSimpleReader + \obsolete \nonreentrant \brief The QXmlSimpleReader class provides an implementation of a simple XML parser. @@ -2845,6 +2866,9 @@ void QXmlSimpleReaderPrivate::initIncrementalParsing() QXmlSimpleReader is not reentrant. If you want to use the class in threaded code, lock the code using QXmlSimpleReader with a locking mechanism, such as a QMutex. + + Note that this class is now deprecated, please use QXmlStreamReader or + QDomDocument for reading XML files. */ static inline bool is_S(QChar ch) @@ -5255,7 +5279,10 @@ bool QXmlSimpleReaderPrivate::parsePEReference() } else if (entityRes) { QMap<QString,QXmlSimpleReaderPrivate::ExternParameterEntity>::Iterator it2; it2 = externParameterEntities.find(ref()); +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED QXmlInputSource *ret = nullptr; +QT_WARNING_POP if (it2 != externParameterEntities.end()) { if (!entityRes->resolveEntity((*it2).publicId, (*it2).systemId, ret)) { delete ret; @@ -7610,7 +7637,10 @@ bool QXmlSimpleReaderPrivate::processReference() // Included if validating bool skipIt = true; if (entityRes) { +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED QXmlInputSource *ret = nullptr; +QT_WARNING_POP if (!entityRes->resolveEntity((*itExtern).publicId, (*itExtern).systemId, ret)) { delete ret; reportParseError(entityRes->errorString()); @@ -7850,6 +7880,8 @@ bool QXmlSimpleReaderPrivate::next_eat_ws() This private function initializes the reader. \a i is the input source to read the data from. */ +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED void QXmlSimpleReaderPrivate::init(const QXmlInputSource *i) { lineNr = 0; @@ -7870,6 +7902,7 @@ void QXmlSimpleReaderPrivate::init(const QXmlInputSource *i) standalone = QXmlSimpleReaderPrivate::Unknown; error.clear(); } +QT_WARNING_POP /* This private function initializes the XML data related variables. Especially, @@ -7898,6 +7931,8 @@ bool QXmlSimpleReaderPrivate::entityExist(const QString& e) const } } +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED void QXmlSimpleReaderPrivate::reportParseError(const QString& error) { this->error = error; @@ -7913,6 +7948,7 @@ void QXmlSimpleReaderPrivate::reportParseError(const QString& error) } } } +QT_WARNING_POP /* This private function is called when a parsing function encounters an @@ -8006,3 +8042,5 @@ void QXmlSimpleReaderPrivate::refAddC(QChar ch) refArray[refArrayPos++] = ch; } QT_END_NAMESPACE + +#endif // QT_DEPRECATED_SINCE(5, 15) diff --git a/src/xml/sax/qxml.h b/src/xml/sax/qxml.h index 9be14bd7a9..e19a398ca7 100644 --- a/src/xml/sax/qxml.h +++ b/src/xml/sax/qxml.h @@ -40,6 +40,26 @@ #ifndef QXML_H #define QXML_H +#if 0 +// This is needed because of QTBUG-80347 +#pragma qt_class(QXmlNamespaceSupport) +#pragma qt_class(QXmlAttributes) +#pragma qt_class(QXmlInputSource) +#pragma qt_class(QXmlParseException) +#pragma qt_class(QXmlReader) +#pragma qt_class(QXmlSimpleReader) +#pragma qt_class(QXmlLocator) +#pragma qt_class(QXmlContentHandler) +#pragma qt_class(QXmlErrorHandler) +#pragma qt_class(QXmlDTDHandler) +#pragma qt_class(QXmlEntityResolver) +#pragma qt_class(QXmlLexicalHandler) +#pragma qt_class(QXmlDeclHandler) +#pragma qt_class(QXmlDefaultHandler) +#endif + +#include <QtCore/qglobal.h> + #include <QtXml/qtxmlglobal.h> #include <QtCore/qtextstream.h> #include <QtCore/qfile.h> @@ -48,8 +68,12 @@ #include <QtCore/qlist.h> #include <QtCore/qscopedpointer.h> +#if QT_DEPRECATED_SINCE(5, 15) + QT_BEGIN_NAMESPACE +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED class QXmlNamespaceSupport; class QXmlAttributes; @@ -76,12 +100,11 @@ class QXmlParseExceptionPrivate; class QXmlLocatorPrivate; class QXmlDefaultHandlerPrivate; - // // SAX Namespace Support // -class Q_XML_EXPORT QXmlNamespaceSupport +class QT_DEPRECATED_VERSION(5, 15) Q_XML_EXPORT QXmlNamespaceSupport { public: QXmlNamespaceSupport(); @@ -112,10 +135,15 @@ private: // SAX Attributes // +// Although deprecated warnings are disabled, the intel icc 18 compiler +// still complains during the instantiation of the templated qSwap() call below +// (with the parameter QXmlAttributes::AttributeList) when QXmlAttributes is +// deprecated. This makes the build fail when warnings are treated as errors. +// To workaround this, deprecated only the constructor. class Q_XML_EXPORT QXmlAttributes { public: - QXmlAttributes(); + QT_DEPRECATED_VERSION(5, 15) QXmlAttributes(); QXmlAttributes(const QXmlAttributes &) = default; QXmlAttributes(QXmlAttributes &&) noexcept = default; QXmlAttributes &operator=(const QXmlAttributes &) = default; @@ -158,6 +186,7 @@ private: QXmlAttributesPrivate *d; }; + Q_DECLARE_TYPEINFO(QXmlAttributes::Attribute, Q_MOVABLE_TYPE); Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QXmlAttributes) @@ -165,7 +194,7 @@ Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QXmlAttributes) // SAX Input Source // -class Q_XML_EXPORT QXmlInputSource +class QT_DEPRECATED_VERSION(5, 15) Q_XML_EXPORT QXmlInputSource { public: QXmlInputSource(); @@ -194,7 +223,7 @@ private: // SAX Exception Classes // -class Q_XML_EXPORT QXmlParseException +class QT_DEPRECATED_VERSION(5, 15) Q_XML_EXPORT QXmlParseException { public: explicit QXmlParseException(const QString &name = QString(), int c = -1, int l = -1, @@ -217,7 +246,7 @@ private: // XML Reader // -class Q_XML_EXPORT QXmlReader +class QT_DEPRECATED_VERSION_X(5, 15, "Use QXmlStreamReader") Q_XML_EXPORT QXmlReader { public: virtual ~QXmlReader() {} @@ -243,7 +272,8 @@ public: virtual bool parse(const QXmlInputSource* input) = 0; }; -class Q_XML_EXPORT QXmlSimpleReader : public QXmlReader +class QT_DEPRECATED_VERSION_X(5, 15, "Use QXmlStreamReader") Q_XML_EXPORT QXmlSimpleReader + : public QXmlReader { public: QXmlSimpleReader(); @@ -288,7 +318,7 @@ private: // SAX Locator // -class Q_XML_EXPORT QXmlLocator +class QT_DEPRECATED_VERSION(5, 15) Q_XML_EXPORT QXmlLocator { public: QXmlLocator(); @@ -304,7 +334,7 @@ public: // SAX handler classes // -class Q_XML_EXPORT QXmlContentHandler +class QT_DEPRECATED_VERSION(5, 15) Q_XML_EXPORT QXmlContentHandler { public: virtual ~QXmlContentHandler() {} @@ -322,7 +352,7 @@ public: virtual QString errorString() const = 0; }; -class Q_XML_EXPORT QXmlErrorHandler +class QT_DEPRECATED_VERSION(5, 15) Q_XML_EXPORT QXmlErrorHandler { public: virtual ~QXmlErrorHandler() {} @@ -332,7 +362,7 @@ public: virtual QString errorString() const = 0; }; -class Q_XML_EXPORT QXmlDTDHandler +class QT_DEPRECATED_VERSION(5, 15) Q_XML_EXPORT QXmlDTDHandler { public: virtual ~QXmlDTDHandler() {} @@ -341,7 +371,7 @@ public: virtual QString errorString() const = 0; }; -class Q_XML_EXPORT QXmlEntityResolver +class QT_DEPRECATED_VERSION(5, 15) Q_XML_EXPORT QXmlEntityResolver { public: virtual ~QXmlEntityResolver() {} @@ -349,7 +379,7 @@ public: virtual QString errorString() const = 0; }; -class Q_XML_EXPORT QXmlLexicalHandler +class QT_DEPRECATED_VERSION(5, 15) Q_XML_EXPORT QXmlLexicalHandler { public: virtual ~QXmlLexicalHandler() {} @@ -363,7 +393,7 @@ public: virtual QString errorString() const = 0; }; -class Q_XML_EXPORT QXmlDeclHandler +class QT_DEPRECATED_VERSION(5, 15) Q_XML_EXPORT QXmlDeclHandler { public: virtual ~QXmlDeclHandler() {} @@ -374,8 +404,12 @@ public: // ### Conform to SAX by adding elementDecl }; - -class Q_XML_EXPORT QXmlDefaultHandler : public QXmlContentHandler, public QXmlErrorHandler, public QXmlDTDHandler, public QXmlEntityResolver, public QXmlLexicalHandler, public QXmlDeclHandler +class QT_DEPRECATED_VERSION(5, 15) Q_XML_EXPORT QXmlDefaultHandler : public QXmlContentHandler, + public QXmlErrorHandler, + public QXmlDTDHandler, + public QXmlEntityResolver, + public QXmlLexicalHandler, + public QXmlDeclHandler { public: QXmlDefaultHandler(); @@ -426,6 +460,10 @@ private: inline int QXmlAttributes::count() const { return length(); } +QT_WARNING_POP + QT_END_NAMESPACE +#endif // QT_DEPRECATED_SINCE(5, 15) + #endif // QXML_H diff --git a/src/xml/sax/qxml_p.h b/src/xml/sax/qxml_p.h index eb6135db04..1b614dd886 100644 --- a/src/xml/sax/qxml_p.h +++ b/src/xml/sax/qxml_p.h @@ -46,6 +46,8 @@ #include <stack> +#if QT_DEPRECATED_SINCE(5, 15) + QT_BEGIN_NAMESPACE // @@ -59,6 +61,9 @@ QT_BEGIN_NAMESPACE // We mean it. // +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED + class QXmlSimpleReaderPrivate { public: @@ -313,6 +318,10 @@ Q_DECLARE_TYPEINFO(QXmlSimpleReaderPrivate::XmlRef, Q_MOVABLE_TYPE); Q_DECLARE_TYPEINFO(QXmlSimpleReaderPrivate::ExternParameterEntity, Q_MOVABLE_TYPE); Q_DECLARE_TYPEINFO(QXmlSimpleReaderPrivate::ExternEntity, Q_MOVABLE_TYPE); +QT_WARNING_POP + QT_END_NAMESPACE +#endif // QT_DEPRECATED_SINCE(5, 15) + #endif // QXML_P_H |