From 035d93a6e1cbde76d34866ffd9b39633572e6236 Mon Sep 17 00:00:00 2001 From: Jan Arve Saether Date: Tue, 20 Nov 2012 11:11:44 +0100 Subject: Fix regression in QXmlStreamWriter with codec set to UTF-16 Actually, this broke using QXmlStreamWriter with any codec where characters in the ASCII range have a different encoding than the ASCII standard. This was a regression from 558fe9383ba0aecbec09cc411c0ebab132aac137 Task-number: QTBUG-23310 Change-Id: I75bd013e9d5de53da564a76c2f06e95ff35303a8 Reviewed-by: Oswald Buddenhagen --- src/corelib/xml/qxmlstream.cpp | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) (limited to 'src/corelib/xml') diff --git a/src/corelib/xml/qxmlstream.cpp b/src/corelib/xml/qxmlstream.cpp index 46c0e5d297..2345cb1881 100644 --- a/src/corelib/xml/qxmlstream.cpp +++ b/src/corelib/xml/qxmlstream.cpp @@ -2980,6 +2980,7 @@ public: uint wroteSomething :1; uint hasError :1; uint autoFormatting :1; + uint isCodecASCIICompatible :1; QByteArray autoFormattingIndent; NamespaceDeclaration emptyNamespace; int lastNamespaceDeclaration; @@ -2988,6 +2989,7 @@ public: QTextCodec *codec; QTextEncoder *encoder; #endif + void checkIfASCIICompatibleCodec(); NamespaceDeclaration &findNamespace(const QString &namespaceUri, bool writeDeclaration = false, bool noDefault = false); void writeNamespaceDeclaration(const NamespaceDeclaration &namespaceDeclaration); @@ -3009,6 +3011,7 @@ QXmlStreamWriterPrivate::QXmlStreamWriterPrivate(QXmlStreamWriter *q) codec = QTextCodec::codecForMib(106); // utf8 encoder = codec->makeEncoder(QTextCodec::IgnoreHeader); // no byte order mark for utf8 #endif + checkIfASCIICompatibleCodec(); inStartElement = inEmptyElement = false; wroteSomething = false; hasError = false; @@ -3018,6 +3021,18 @@ QXmlStreamWriterPrivate::QXmlStreamWriterPrivate(QXmlStreamWriter *q) namespacePrefixCount = 0; } +void QXmlStreamWriterPrivate::checkIfASCIICompatibleCodec() +{ +#ifndef QT_NO_TEXTCODEC + Q_ASSERT(encoder); + // assumes ASCII-compatibility for all 8-bit encodings + const QByteArray bytes = encoder->fromUnicode(QStringLiteral(" ")); + isCodecASCIICompatible = (bytes.count() == 1); +#else + isCodecASCIICompatible = true; +#endif +} + void QXmlStreamWriterPrivate::write(const QStringRef &s) { if (device) { @@ -3086,18 +3101,20 @@ void QXmlStreamWriterPrivate::writeEscaped(const QString &s, bool escapeWhitespa write(escaped); } -// ASCII only! +// Converts from ASCII to output encoding void QXmlStreamWriterPrivate::write(const char *s, int len) { if (device) { if (hasError) return; - if (device->write(s, len) != len) - hasError = true; - } else if (stringDevice) { - stringDevice->append(QString::fromLatin1(s, len)); - } else - qWarning("QXmlStreamWriter: No device"); + if (isCodecASCIICompatible) { + if (device->write(s, len) != len) + hasError = true; + return; + } + } + + write(QString::fromLatin1(s, len)); } void QXmlStreamWriterPrivate::writeNamespaceDeclaration(const NamespaceDeclaration &namespaceDeclaration) { @@ -3279,6 +3296,7 @@ void QXmlStreamWriter::setCodec(QTextCodec *codec) d->codec = codec; delete d->encoder; d->encoder = codec->makeEncoder(QTextCodec::IgnoreHeader); // no byte order mark for utf8 + d->checkIfASCIICompatibleCodec(); } } -- cgit v1.2.3