From dbb54805f63f9ed68d84fe090d608872f16170d2 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 22 Nov 2018 12:00:53 +0100 Subject: Deprecate reverse iteration on QHash MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit std::unordered_map only supports forward iteration for good reasons. Align our API with this by deprecating reverse iteration and the operator+/-() for iterators. [ChangeLog][QtCore][QHash] Reverse iteration over QHash is now deprecated. [ChangeLog][Potentially Binary-Incompatible Changes] QHash's iterator category was changed from bidirectional iterator to forward iterator. This may cause trouble if a library uses the iterator category to alter functionality through tag dispatching. This only applies when compiling the library or application with QT_DISABLE_DEPRECATED_BEFORE=0x050F00 and the other with a lower value. Change-Id: I0fb6d017cabdef1bc508e62f76dc2fa73cd3652d Reviewed-by: MÃ¥rten Nordheim Reviewed-by: Lars Knoll --- src/xml/dom/qdom.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/xml/dom') diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp index e3bf97d1a6..c71256457a 100644 --- a/src/xml/dom/qdom.cpp +++ b/src/xml/dom/qdom.cpp @@ -2648,7 +2648,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 -- cgit v1.2.3 From fa2c9a27e2a4b6ce59823f2f3c6c53a57e7c037f Mon Sep 17 00:00:00 2001 From: Sona Kurazyan Date: Thu, 24 Oct 2019 11:10:56 +0200 Subject: Move out the reusable part of QDomHandler to a new class QDomHandler implements methods for building the DOM tree. These methods can be reused also in the new QXmlStreamReader-based implementation. They are moved to a new QDomBuilder class and QDomHandler become a wrapper around it. Task-number: QTBUG-76178 Change-Id: I01956c209ae253b69c23f20d90a5befe7b5329a0 Reviewed-by: Kai Koehne --- src/xml/dom/qdom.cpp | 6 +- src/xml/dom/qdomhelpers.cpp | 238 +++++++++++++++++++++++++++++++++----------- src/xml/dom/qdomhelpers_p.h | 90 +++++++++++++++-- 3 files changed, 265 insertions(+), 69 deletions(-) (limited to 'src/xml/dom') diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp index c71256457a..75b7f8988c 100644 --- a/src/xml/dom/qdom.cpp +++ b/src/xml/dom/qdom.cpp @@ -5728,11 +5728,11 @@ 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 = hnd.errorLine; + *errorLine = std::get<1>(hnd.errorInfo()); if (errorColumn) - *errorColumn = hnd.errorColumn; + *errorColumn = std::get<2>(hnd.errorInfo()); return false; } diff --git a/src/xml/dom/qdomhelpers.cpp b/src/xml/dom/qdomhelpers.cpp index 74d2c8c124..bda6f8ef87 100644 --- a/src/xml/dom/qdomhelpers.cpp +++ b/src/xml/dom/qdomhelpers.cpp @@ -51,20 +51,161 @@ QT_BEGIN_NAMESPACE QDomHandler::QDomHandler(QDomDocumentPrivate *adoc, QXmlSimpleReader *areader, bool namespaceProcessing) - : errorLine(0), - errorColumn(0), - doc(adoc), - node(adoc), - cdata(false), - nsProcessing(namespaceProcessing), - locator(nullptr), - reader(areader) + : 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(); +} + +/************************************************************** + * + * QXmlDocumentLocators + * + **************************************************************/ + +void QSAXDocumentLocator::setLocator(QXmlLocator *l) +{ + locator = l; +} + +int QSAXDocumentLocator::column() const +{ + if (!locator) + return 0; + + return static_cast(locator->columnNumber()); +} + +int QSAXDocumentLocator::line() const +{ + if (!locator) + return 0; + + return static_cast(locator->lineNumber()); +} + +/************************************************************** + * + * 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) @@ -72,7 +213,7 @@ bool QDomHandler::endDocument() return true; } -bool QDomHandler::startDTD(const QString &name, const QString &publicId, const QString &systemId) +bool QDomBuilder::startDTD(const QString &name, const QString &publicId, const QString &systemId) { doc->doctype()->name = name; doc->doctype()->publicId = publicId; @@ -80,7 +221,7 @@ bool QDomHandler::startDTD(const QString &name, const QString &publicId, const Q return true; } -bool QDomHandler::startElement(const QString &nsURI, const QString &, const QString &qName, +bool QDomBuilder::startElement(const QString &nsURI, const QString &qName, const QXmlAttributes &atts) { // tag name @@ -94,24 +235,24 @@ bool QDomHandler::startElement(const QString &nsURI, const QString &, const QStr if (!n) return false; - n->setLocation(locator->lineNumber(), locator->columnNumber()); + n->setLocation(locator->line(), locator->column()); 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)); - } + auto domElement = static_cast(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; } -bool QDomHandler::endElement(const QString &, const QString &, const QString &) +bool QDomBuilder::endElement() { if (!node || node == doc) return false; @@ -120,7 +261,7 @@ bool QDomHandler::endElement(const QString &, const QString &, const QString &) return true; } -bool QDomHandler::characters(const QString &ch) +bool QDomBuilder::characters(const QString &characters, bool cdata) { // No text as child of some document if (node == doc) @@ -128,91 +269,79 @@ bool QDomHandler::characters(const QString &ch) QScopedPointer n; if (cdata) { - n.reset(doc->createCDATASection(ch)); + n.reset(doc->createCDATASection(characters)); } else if (!entityName.isEmpty()) { QScopedPointer e( new QDomEntityPrivate(doc, nullptr, entityName, QString(), QString(), QString())); - e->value = ch; + e->value = characters; e->ref.deref(); doc->doctype()->appendChild(e.data()); e.take(); n.reset(doc->createEntityReference(entityName)); } else { - n.reset(doc->createTextNode(ch)); + n.reset(doc->createTextNode(characters)); } - n->setLocation(locator->lineNumber(), locator->columnNumber()); + n->setLocation(locator->line(), locator->column()); node->appendChild(n.data()); n.take(); return true; } -bool QDomHandler::processingInstruction(const QString &target, const QString &data) +bool QDomBuilder::processingInstruction(const QString &target, const QString &data) { QDomNodePrivate *n; n = doc->createProcessingInstruction(target, data); if (n) { - n->setLocation(locator->lineNumber(), locator->columnNumber()); + n->setLocation(locator->line(), locator->column()); node->appendChild(n); return true; } else return false; } -bool QDomHandler::skippedEntity(const QString &name) +bool QDomBuilder::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()); + n->setLocation(locator->line(), locator->column()); 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() +void QDomBuilder::fatalError(const QString &message) { - cdata = true; - return true; + errorMsg = message; + errorLine = static_cast(locator->line()); + errorColumn = static_cast(locator->column()); } -bool QDomHandler::endCDATA() +QDomBuilder::ErrorInfo QDomBuilder::error() const { - cdata = false; - return true; + return ErrorInfo(errorMsg, errorLine, errorColumn); } -bool QDomHandler::startEntity(const QString &name) +bool QDomBuilder::startEntity(const QString &name) { entityName = name; return true; } -bool QDomHandler::endEntity(const QString &) +bool QDomBuilder::endEntity() { entityName.clear(); return true; } -bool QDomHandler::comment(const QString &ch) +bool QDomBuilder::comment(const QString &characters) { QDomNodePrivate *n; - n = doc->createComment(ch); - n->setLocation(locator->lineNumber(), locator->columnNumber()); + n = doc->createComment(characters); + n->setLocation(locator->line(), locator->column()); node->appendChild(n); return true; } -bool QDomHandler::unparsedEntityDecl(const QString &name, const QString &publicId, +bool QDomBuilder::unparsedEntityDecl(const QString &name, const QString &publicId, const QString &systemId, const QString ¬ationName) { QDomEntityPrivate *e = @@ -223,13 +352,13 @@ bool QDomHandler::unparsedEntityDecl(const QString &name, const QString &publicI return true; } -bool QDomHandler::externalEntityDecl(const QString &name, const QString &publicId, +bool QDomBuilder::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, +bool QDomBuilder::notationDecl(const QString &name, const QString &publicId, const QString &systemId) { QDomNotationPrivate *n = new QDomNotationPrivate(doc, nullptr, name, publicId, systemId); @@ -239,9 +368,4 @@ bool QDomHandler::notationDecl(const QString &name, const QString &publicId, return true; } -void QDomHandler::setDocumentLocator(QXmlLocator *locator) -{ - this->locator = locator; -} - QT_END_NAMESPACE diff --git a/src/xml/dom/qdomhelpers_p.h b/src/xml/dom/qdomhelpers_p.h index ee81f1f9ce..7647de65d2 100644 --- a/src/xml/dom/qdomhelpers_p.h +++ b/src/xml/dom/qdomhelpers_p.h @@ -58,6 +58,83 @@ QT_BEGIN_NAMESPACE class QDomDocumentPrivate; class QDomNodePrivate; +/************************************************************** + * + * 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 QSAXDocumentLocator : public QXmlDocumentLocator +{ +public: + ~QSAXDocumentLocator() override = default; + + int column() const override; + int line() const override; + + void setLocator(QXmlLocator *l); + +private: + QXmlLocator *locator = nullptr; +}; + +/************************************************************** + * + * QDomBuilder + * + **************************************************************/ + +class QDomBuilder +{ +public: + QDomBuilder(QDomDocumentPrivate *d, QXmlDocumentLocator *l, bool namespaceProcessing); + ~QDomBuilder(); + + bool endDocument(); + bool startElement(const QString &nsURI, const QString &qName, const QXmlAttributes &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; + ErrorInfo error() const; + + QString errorMsg; + int errorLine; + int errorColumn; + +private: + QDomDocumentPrivate *doc; + QDomNodePrivate *node; + QXmlDocumentLocator *locator; + QString entityName; + bool nsProcessing; +}; + /************************************************************** * * QDomHandler @@ -68,7 +145,7 @@ class QDomHandler : public QXmlDefaultHandler { public: QDomHandler(QDomDocumentPrivate *d, QXmlSimpleReader *reader, bool namespaceProcessing); - ~QDomHandler(); + ~QDomHandler() override; // content handler bool endDocument() override; @@ -102,18 +179,13 @@ public: void setDocumentLocator(QXmlLocator *locator) override; - QString errorMsg; - int errorLine; - int errorColumn; + QDomBuilder::ErrorInfo errorInfo() const; private: - QDomDocumentPrivate *doc; - QDomNodePrivate *node; - QString entityName; bool cdata; - bool nsProcessing; - QXmlLocator *locator; QXmlSimpleReader *reader; + QSAXDocumentLocator locator; + QDomBuilder domBuilder; }; QT_END_NAMESPACE -- cgit v1.2.3 From d7cb21ac085117f879a8aa1d7727b2ca52d3353d Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Fri, 15 Nov 2019 21:46:32 +0100 Subject: QDom: use QLocale::C when converting a double to a xml attribute QDomElement::setAttribute(QString, double) did not use QString::setNum() but qsnprintf(). This is wrong because qsnprintf() is using the current locale instead QLocale::C. It was also inconsistent to QDomElement::setAttributeNS() which was already using QString::setNum(). Also fix the documentation which stated that all QDomElement::setAttribute() format the values according the current locale. Fixes: QTBUG-80068 Change-Id: Iabb0b39c0d0723060527542c283a5435f26f31ca Reviewed-by: Thiago Macieira --- src/xml/dom/qdom.cpp | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'src/xml/dom') diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp index 8d232237bf..04151c3f31 100644 --- a/src/xml/dom/qdom.cpp +++ b/src/xml/dom/qdom.cpp @@ -4818,20 +4818,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 +4845,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 +4859,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 +4873,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); } -- cgit v1.2.3