summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/xml/qxmlstream.cpp32
-rw-r--r--tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp22
2 files changed, 47 insertions, 7 deletions
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();
}
}
diff --git a/tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp b/tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp
index ea2cafdbc3..694a2f2952 100644
--- a/tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp
+++ b/tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp
@@ -558,6 +558,7 @@ private slots:
void hasAttribute() const;
void writeWithCodec() const;
void writeWithUtf8Codec() const;
+ void writeWithUtf16Codec() const;
void writeWithStandalone() const;
void entitiesAndWhitespace_1() const;
void entitiesAndWhitespace_2() const;
@@ -1279,6 +1280,27 @@ void tst_QXmlStream::writeWithUtf8Codec() const
QVERIFY(outarray.startsWith(begin));
}
+void tst_QXmlStream::writeWithUtf16Codec() const
+{
+ QByteArray outarray;
+ QXmlStreamWriter writer(&outarray);
+
+ QTextCodec *codec = QTextCodec::codecForMib(1014); // utf-16LE
+ QVERIFY(codec);
+ writer.setCodec(codec);
+
+ writer.writeStartDocument("1.0");
+ static const char begin[] = "<?xml version=\"1.0\" encoding=\"UTF-16"; // skip potential "LE" suffix
+ const int count = sizeof(begin) - 1; // don't include 0 terminator
+ QByteArray begin_UTF16;
+ begin_UTF16.reserve(2*(count));
+ for (int i = 0; i < count; ++i) {
+ begin_UTF16.append(begin[i]);
+ begin_UTF16.append((char)'\0');
+ }
+ QVERIFY(outarray.startsWith(begin_UTF16));
+}
+
void tst_QXmlStream::writeWithStandalone() const
{
{