\value DefaultConversion No flag is set.
\value ConvertInvalidToNull If this flag is set, each invalid input
character is output as a null character.
- \value IgnoreHeader Ignore any Unicode byte-order mark and don't generate any.
*/
/*!
UErrorCode error = U_ZERO_ERROR;
const int convresult = ucnv_fromUChars(conv, result, maxbytes,
reinterpret_cast<const UChar *>(data), length, &error);
-
return QByteArray(result, convresult);
}
const int maxbytes = UCNV_GET_MAX_BYTES_FOR_STRING(length, ucnv_getMaxCharSize(conv));
QSTACKARRAY(UChar, result, maxbytes);
- int resultoffset = 0;
UErrorCode error = U_ZERO_ERROR;
const int convresult = ucnv_toUChars(conv, result, maxbytes, data, length, &error);
-
- if (d_ptr->flags & QTextConverter::IgnoreHeader) {
- // ICU always generates BOMs when converter is UTF-32/UTF-16 so no check is done to
- // verify that, unless someone makes it an option
- if (qstrnicmp("UTF-32", d_ptr->name.constData(), 6) == 0) {
- resultoffset = 4;
- } else if (qstrnicmp("UTF-16", d_ptr->name.constData(), 6) == 0) {
- resultoffset = 2;
- }
- }
-
- return QString(reinterpret_cast<QChar*>(result) + resultoffset, convresult - resultoffset);
+ return QString(reinterpret_cast<QChar*>(result), convresult);
}
#endif // QT_NO_TEXTCODEC
inline void write(const QString &data);
inline void putString(const QString &ch, bool number = false);
void putNumber(qulonglong number, bool negative);
+ void writeBOM();
// buffers
bool fillReadBuffer(qint64 maxBytes = -1);
// status
QTextStream::TextStatus status;
+ bool generatebom;
+ bool bomwritten;
QLocale locale;
};
#ifndef QT_NO_TEXTCODEC
codec = QTextCodec::codecForLocale();
readConverter = codec->converter();
- readConverter.setFlags(QTextConverter::DefaultConversion);
writeConverter = codec->converter();
- writeConverter.setFlags(QTextConverter::IgnoreHeader);
readConverterSaved.reset();
- readConverterSaved.setFlags(QTextConverter::DefaultConversion);
autoDetectUnicode = true;
#endif
+
+ generatebom = false;
+ bomwritten = false;
}
/*! \internal
codec = QTextCodec::codecForUtfText(buffer, codec);
if (!codec) {
codec = QTextCodec::codecForLocale();
- writeConverter.setFlags(writeConverter.flags() | QTextConverter::IgnoreHeader);
}
}
#if defined (QTEXTSTREAM_DEBUG)
codec = QTextCodec::codecForLocale();
#if defined (QTEXTSTREAM_DEBUG)
qDebug("QTextStreamPrivate::flushWriteBuffer(), using %s codec (%s generating BOM)",
- codec->name().constData(), writeConverter.flags() & QTextConverter::IgnoreHeader ? "not" : "");
+ codec->name().constData(), generatebom ? "not" : "");
#endif
// convert from unicode to raw data
*/
inline void QTextStreamPrivate::write(const QString &data)
{
+ if (generatebom && !bomwritten) {
+ writeBOM();
+ }
+
if (string) {
// ### What about seek()??
string->append(data);
#ifndef QT_NO_TEXTCODEC
// Reset the codec converter states.
d->readConverter.reset();
- d->readConverter.setFlags(QTextConverter::DefaultConversion);
d->writeConverter.reset();
- d->writeConverter.setFlags(QTextConverter::IgnoreHeader);
d->readConverterSaved.reset();
- d->readConverterSaved.setFlags(QTextConverter::DefaultConversion);
#endif
return true;
}
}
/*!
+ \internal
+ */
+void QTextStreamPrivate::writeBOM()
+{
+ Q_ASSERT(generatebom);
+ Q_ASSERT(!bomwritten);
+
+#ifndef QT_NO_TEXTCODEC
+ bomwritten = true;
+ const QByteArray codecname = codec->name();
+ const uchar* bomptr = nullptr;
+ int bomptrsize = 0;
+ if (qstricmp("UTF-32BE", codecname.constData()) == 0) {
+ bomptr = q_utf32be_bom;
+ bomptrsize = sizeof(q_utf32be_bom);
+ } else if (qstricmp("UTF-32LE", codecname.constData()) == 0) {
+ bomptr = q_utf32le_bom;
+ bomptrsize = sizeof(q_utf32le_bom);
+ } else if (qstricmp("UTF-16BE", codecname.constData()) == 0) {
+ bomptr = q_utf16be_bom;
+ bomptrsize = sizeof(q_utf16be_bom);
+ } else if (qstricmp("UTF-16LE", codecname.constData()) == 0) {
+ bomptr = q_utf16le_bom;
+ bomptrsize = sizeof(q_utf16le_bom);
+ } else if (qstricmp("UTF-32", codecname.constData()) == 0) {
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ bomptr = q_utf32le_bom;
+ bomptrsize = sizeof(q_utf32le_bom);
+#else
+ bomptr = q_utf32be_bom;
+ bomptrsize = sizeof(q_utf32be_bom);
+#endif
+ } else if (qstricmp("UTF-16", codecname.constData()) == 0) {
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ bomptr = q_utf16le_bom;
+ bomptrsize = sizeof(q_utf16le_bom);
+#else
+ bomptr = q_utf16be_bom;
+ bomptrsize = sizeof(q_utf16be_bom);
+#endif
+ }
+
+ if (bomptr && bomptrsize) {
+ if (string) {
+ string->append(QString::fromRawData(reinterpret_cast<const QChar*>(bomptr), bomptrsize / sizeof(QChar)));
+ } else {
+ device->write(QByteArray::fromRawData(reinterpret_cast<const char*>(bomptr), bomptrsize));
+ }
+ }
+#endif // QT_NO_TEXTCODEC
+}
+
+/*!
Writes the character \a c to the stream, then returns a reference
to the QTextStream.
{
Q_D(QTextStream);
if (d->writeBuffer.isEmpty()) {
- if (generate)
- d->writeConverter.setFlags(d->writeConverter.flags() & ~QTextConverter::IgnoreHeader);
- else
- d->writeConverter.setFlags(d->writeConverter.flags() | QTextConverter::IgnoreHeader);
+ d->generatebom = generate;
}
}
bool QTextStream::generateByteOrderMark() const
{
Q_D(const QTextStream);
- return (d->writeConverter.flags() & QTextConverter::IgnoreHeader) == 0;
+ return d->generatebom;
}
-
#endif
/*!