summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <[email protected]>2020-04-29 15:56:24 +0200
committerLars Knoll <[email protected]>2020-05-14 07:50:29 +0200
commit124d587bb95f35c853ab3458bdeb1519d369cdf1 (patch)
tree54ec10e28aa7671ad3358b9ae9ecb01d18de3b83
parent4ff09cdd47a1f21321a56017743401a7c6b91ad3 (diff)
Document the string converter classes
Document QStringConverter, QStringDecoder and QStringEncoder. In addition, do some touches to the API, renaming one enum value, add a flags argument to one constructor and make some members private. Change-Id: I8f99dc3d98fb8860cf6fa46301e34b7eb400511b Reviewed-by: Thiago Macieira <[email protected]>
-rw-r--r--src/corelib/codecs/qtextcodec.h2
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_text_qstringconverter.cpp83
-rw-r--r--src/corelib/text/qstring.cpp4
-rw-r--r--src/corelib/text/qstringconverter.cpp415
-rw-r--r--src/corelib/text/qstringconverter.h38
-rw-r--r--tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp2
-rw-r--r--tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp20
7 files changed, 513 insertions, 51 deletions
diff --git a/src/corelib/codecs/qtextcodec.h b/src/corelib/codecs/qtextcodec.h
index 17dbd08a3ba..dfca8ac8b84 100644
--- a/src/corelib/codecs/qtextcodec.h
+++ b/src/corelib/codecs/qtextcodec.h
@@ -62,7 +62,7 @@ public:
static constexpr Flag ConvertInvalidToNull = Flag::ConvertInvalidToNull;
static constexpr Flag DefaultConversion = Flag::WriteBom;
- static constexpr Flag IgnoreHeader = Flag::DontSkipInitialBom;
+ static constexpr Flag IgnoreHeader = Flag::ConvertInitialBom;
static QTextCodec* codecForName(const QByteArray &name);
static QTextCodec* codecForName(const char *name) { return codecForName(QByteArray(name)); }
diff --git a/src/corelib/doc/snippets/code/src_corelib_text_qstringconverter.cpp b/src/corelib/doc/snippets/code/src_corelib_text_qstringconverter.cpp
new file mode 100644
index 00000000000..97d28d54285
--- /dev/null
+++ b/src/corelib/doc/snippets/code/src_corelib_text_qstringconverter.cpp
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//! [0]
+QByteArray encodedString = "...";
+auto toUtf16 = QStringDecoder(QStringDecoder::Utf8);
+QString string = toUtf16(encodedString);
+//! [0]
+
+
+//! [1]
+QString string = "...";
+auto fromUtf16 = QStringEncoder(QStringEncoder::Utf8);
+QByteArray encodedString = fromUtf16(encodedString);
+//! [1]
+
+
+//! [2]
+auto toUtf16 = QStringDecoder(QStringDecoder::Utf8);
+
+QString string;
+while (new_data_available()) {
+ QByteArray chunk = get_new_data();
+ string += toUtf16(chunk);
+}
+//! [2]
+
+//! [3]
+auto fromUtf16 = QStringEncoder(QStringEncoder::Utf8);
+
+QByteArray encoded;
+while (new_data_available()) {
+ QString chunk = get_new_data();
+ encoded += fromUtf16(chunk);
+}
+//! [3]
diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp
index 7753ce5f005..857aa601c17 100644
--- a/src/corelib/text/qstring.cpp
+++ b/src/corelib/text/qstring.cpp
@@ -5206,7 +5206,7 @@ static QByteArray qt_convert_to_local_8bit(QStringView string)
{
if (string.isNull())
return QByteArray();
- QStringEncoder fromUtf16(QStringEncoder::Locale, QStringEncoder::Flag::Stateless);
+ QStringEncoder fromUtf16(QStringEncoder::System, QStringEncoder::Flag::Stateless);
return fromUtf16(string);
}
@@ -5392,7 +5392,7 @@ QString QString::fromLocal8Bit_helper(const char *str, int size)
QString::DataPointer empty = { pair.first, pair.second, 0 };
return QString(empty);
}
- QStringDecoder toUtf16(QStringDecoder::Locale, QStringDecoder::Flag::Stateless);
+ QStringDecoder toUtf16(QStringDecoder::System, QStringDecoder::Flag::Stateless);
return toUtf16(str, size);
}
diff --git a/src/corelib/text/qstringconverter.cpp b/src/corelib/text/qstringconverter.cpp
index bc81b06c0ea..f4a51ef93da 100644
--- a/src/corelib/text/qstringconverter.cpp
+++ b/src/corelib/text/qstringconverter.cpp
@@ -582,7 +582,7 @@ QChar *QUtf8::convertToUnicode(QChar *out, const char *chars, qsizetype len, QSt
{
Q_ASSERT(state);
- bool headerdone = state->internalState & HeaderDone || state->flags & QStringConverter::Flag::DontSkipInitialBom;
+ bool headerdone = state->internalState & HeaderDone || state->flags & QStringConverter::Flag::ConvertInitialBom;
ushort replacement = QChar::ReplacementCharacter;
if (state->flags & QStringConverter::Flag::ConvertInvalidToNull)
@@ -840,7 +840,7 @@ QChar *QUtf16::convertToUnicode(QChar *out, const char *chars, qsizetype len, QS
}
bool headerdone = state && state->internalState & HeaderDone;
- if (state->flags & QStringConverter::Flag::DontSkipInitialBom)
+ if (state->flags & QStringConverter::Flag::ConvertInitialBom)
headerdone = true;
if (!headerdone || state->remainingChars) {
@@ -1016,7 +1016,7 @@ QChar *QUtf32::convertToUnicode(QChar *out, const char *chars, qsizetype len, QS
}
bool headerdone = state->internalState & HeaderDone;
- if (state->flags & QStringConverter::Flag::DontSkipInitialBom)
+ if (state->flags & QStringConverter::Flag::ConvertInitialBom)
headerdone = true;
int num = state->remainingChars;
@@ -1288,26 +1288,6 @@ QByteArray QLocal8Bit::convertFromUnicode(const QChar *ch, qsizetype uclen, QStr
}
#endif
-/*!
- \enum QStringConverter::Flag
-
- \value Default Default conversion rules apply.
- \value ConvertInvalidToNull If this flag is set, each invalid input
- character is output as a null character. If it is not set,
- invalid input characters are represented as QChar::ReplacementCharacter
- if the output encoding can represent that character, otherwise as a question mark.
- \value WriteBom When converting from a QString to an output encoding, write a QChar::ByteOrderMark as the first
- character if the output encoding supports this. This is the case for UTF-8, UTF-16 and UTF-32
- encodings.
- \value DontSkipInitialBom When converting from an input encoding to a QString the QTextDecoder usually skips an
- leading QChar::ByteOrderMark. When this flag is set, the byte order mark will not be
- skipped, but inserted at the start of the created QString.
-
- \value Stateless Ignore possible converter states between different function calls
- to encode or decode strings.
-*/
-
-
void QStringConverter::State::clear()
{
if (clearFn)
@@ -1440,6 +1420,132 @@ static qsizetype toUtf32Len(qsizetype l) { return 4*(l + 1); }
static qsizetype fromLatin1Len(qsizetype l) { return l + 1; }
static qsizetype toLatin1Len(qsizetype l) { return l + 1; }
+
+
+/*!
+ \class QStringConverterBase
+ \internal
+
+ Just a common base class for QStringConverter and QTextCodec
+*/
+
+/*!
+ \class QStringConverter
+ \inmodule QtCore
+ \brief The QStringConverter class provides a base class for encoding and decoding text.
+ \reentrant
+ \ingroup i18n
+
+ Qt uses UTF-16 to store, draw and manipulate strings. In many
+ situations you may wish to deal with data that uses a different
+ encoding. Most text data transferred over files and network connections is encoded
+ in UTF-8.
+
+ The QStringConverter class is a base class for the \l {QStringEncoder} and
+ \l {QStringDecoder} classes that help with converting between different
+ text encodings. QStringDecoder can decode a string from an encoded representation
+ into UTF-16, the format Qt uses internally. QStringEncoder does the opposite
+ operation, encoding UTF-16 encoded data (usually in the form of a QString) to
+ the requested encoding.
+
+ The supported encodings are:
+
+ \list
+ \li UTF-8
+ \li UTF-16
+ \li UTF-16BE
+ \li UTF-16LE
+ \li UTF-32
+ \li UTF-32BE
+ \li UTF-32LE
+ \li ISO-8859-1 (Latin-1)
+ \li The system encoding
+ \endlist
+
+ \l {QStringConverter}s can be used as follows to convert some encoded
+ string to and from UTF-16.
+
+ Suppose you have some string encoded in UTF-8, and
+ want to convert it to a QString. The simple way
+ to do it is to use a \l {QStringDecoder} like this:
+
+ \snippet code/src_corelib_text_qstringconverter.cpp 0
+
+ After this, \c string holds the text in decoded form.
+ Converting a string from Unicode to the local encoding is just as
+ easy using the \l {QStringEncoder} class:
+
+ \snippet code/src_corelib_text_qstringconverter.cpp 1
+
+ To read or write text files in various encodings, use QTextStream and
+ its \l{QTextStream::setEncoding()}{setEncoding()} function.
+
+ Some care must be taken when trying to convert the data in chunks,
+ for example, when receiving it over a network. In such cases it is
+ possible that a multi-byte character will be split over two
+ chunks. At best this might result in the loss of a character and
+ at worst cause the entire conversion to fail.
+
+ Both QStringEncoder and QStringDecoder make this easy, by tracking
+ this in an internal state. So simply calling the encoder or decoder
+ again with the next chunk of data will automatically continue encoding
+ or decoding the data correctly:
+
+ \snippet code/src_corelib_text_qstringconverter.cpp 2
+
+ The QStringDecoder object maintains state between chunks and therefore
+ works correctly even if a multi-byte character is split between
+ chunks.
+
+ QStringConverter objects can't be copied because of their internal state, but
+ can be moved.
+
+ \sa QTextStream, QStringDecoder, QStringEncoder
+*/
+
+/*!
+ \enum QStringConverter::Flag
+
+ \value Default Default conversion rules apply.
+ \value ConvertInvalidToNull If this flag is set, each invalid input
+ character is output as a null character. If it is not set,
+ invalid input characters are represented as QChar::ReplacementCharacter
+ if the output encoding can represent that character, otherwise as a question mark.
+ \value WriteBom When converting from a QString to an output encoding, write a QChar::ByteOrderMark as the first
+ character if the output encoding supports this. This is the case for UTF-8, UTF-16 and UTF-32
+ encodings.
+ \value ConvertInitialBom When converting from an input encoding to a QString the QStringDecoder usually skips an
+ leading QChar::ByteOrderMark. When this flag is set, the byte order mark will not be
+ skipped, but converted to utf-16 and inserted at the start of the created QString.
+ \value Stateless Ignore possible converter states between different function calls
+ to encode or decode strings. This will also cause the QStringConverter to raise an error if an incomplete
+ sequence of data is encountered.
+*/
+
+/*!
+ \enum QStringConverter::Encoding
+ \value Utf8 Create a converter to or from UTF-8
+ \value Utf16 Create a converter to or from UTF-16. When decoding, the byte order will get automatically
+ detected by a leading byte order mark. If none exists or when encoding, the system byte order will
+ be assumed.
+ \value Utf16BE Create a converter to or from big endian UTF-16.
+ \value Utf16LE Create a converter to or from litte endian UTF-16.
+ \value Utf32 Create a converter to or from UTF-32. When decoding, the byte order will get automatically
+ detected by a leading byte order mark. If none exists or when encoding, the system byte order will
+ be assumed.
+ \value Utf32BE Create a converter to or from big endian UTF-32.
+ \value Utf32LE Create a converter to or from litte endian UTF-32.
+ \value Latin1 Create a converter to or from ISO-8859-1 (Latin1).
+ \value System Create a converter to or from the underlying encoding of the
+ operating systems locale. This is always assumed to be UTF-8 for Unix based
+ systems. On Windows, this converts to and from the locale code page.
+*/
+
+/*!
+ \struct QStringConverter::Interface
+ \internal
+*/
+
const QStringConverter::Interface QStringConverter::encodingInterfaces[QStringConverter::LastEncoding + 1] =
{
{ "UTF-8", QUtf8::convertToUnicode, fromUtf8Len, QUtf8::convertFromUnicode, toUtf8Len },
@@ -1473,14 +1579,66 @@ static bool nameMatch(const char *a, const char *b)
return !*a && !*b;
}
-QStringConverter::QStringConverter(const char *name)
- : iface(nullptr)
+
+/*!
+ \fn constexpr QStringConverter::QStringConverter()
+ \internal
+*/
+
+/*!
+ \fn constexpr QStringConverter::QStringConverter(Encoding, Flags)
+ \internal
+*/
+
+/*!
+ \internal
+*/
+QStringConverter::QStringConverter(const char *name, Flags f)
+ : iface(nullptr), state(f)
{
auto e = encodingForName(name);
if (e)
iface = encodingInterfaces + int(e.value());
}
+/*!
+ \fn bool QStringConverter::isValid() const
+
+ Returns true if this is a valid string converter that can be used for encoding or
+ decoding text.
+
+ Default constructed string converters or converters constructed with an unsupported
+ name are not valid.
+*/
+
+/*!
+ \fn void QStringConverter::resetState()
+
+ Resets the internal state of the converter, clearing potential errors or partial
+ conversions.
+*/
+
+/*!
+ \fn bool QStringConverter::hasError() const
+
+ Returns true if a conversion could not correctly convert a character. This could for example
+ get triggered by an invalid UTF-8 sequence or when a character can't get converted due to
+ limitations in the target encoding.
+*/
+
+/*!
+ \fn const char *QStringConverter::name() const
+
+ Returns the canonical name of the encoding this QStringConverter can encode or decode.
+ Returns a nullptr if the converter is not valid.
+
+ \sa isValid()
+*/
+
+/*!
+ Returns an optional encoding for \a name. The optional is empty if the name could
+ not get converted to a valid encoding.
+*/
std::optional<QStringConverter::Encoding> QStringConverter::encodingForName(const char *name)
{
for (int i = 0; i < LastEncoding + 1; ++i) {
@@ -1492,6 +1650,13 @@ std::optional<QStringConverter::Encoding> QStringConverter::encodingForName(cons
return std::nullopt;
}
+/*!
+ Returns the encoding for the content of \a buf if it can be determined.
+ \a expectedFirstCharacter can be passed as an additional hint to help determine
+ the encoding.
+
+ The returned optional is empty, if the encoding is unclear.
+ */
std::optional<QStringConverter::Encoding> QStringConverter::encodingForData(const char *buf, qsizetype arraySize, char16_t expectedFirstCharacter)
{
if (arraySize > 3) {
@@ -1584,4 +1749,204 @@ const char *QStringConverter::nameForEncoding(QStringConverter::Encoding e)
return encodingInterfaces[int(e)].name;
}
+/*!
+ \class QStringEncoder
+ \inmodule QtCore
+ \brief The QStringEncoder class provides a state-based encoder for text.
+ \reentrant
+ \ingroup i18n
+
+ A text encoder converts text from Qt's internal representation into an encoded
+ text format using a specific encoding.
+
+ Converting a string from Unicode to the local encoding can be achieved
+ using the following code:
+
+ \snippet code/src_corelib_text_qstringconverter.cpp 1
+
+ The encoder remembers any state that is required between calls, so converting
+ data received in chunks, for example, when receiving it over a network, is just as
+ easy, by calling the encoder whenever new data is available:
+
+ \snippet code/src_corelib_text_qstringconverter.cpp 3
+
+ The QStringEncoder object maintains state between chunks and therefore
+ works correctly even if a UTF-16 surrogate character is split between
+ chunks.
+
+ QStringEncoder objects can't be copied because of their internal state, but
+ can be moved.
+
+ \sa QStringConverter, QStringDecoder
+*/
+
+/*!
+ \fn constexpr QStringEncoder::QStringEncoder(const Interface *i)
+ \internal
+*/
+
+/*!
+ \fn constexpr QStringEncoder::QStringEncoder()
+
+ Default constructs an encoder. The default encoder is not valid,
+ and can't be used for converting text.
+*/
+
+/*!
+ \fn constexpr QStringEncoder::QStringEncoder(Encoding encoding, Flags flags = Flag::Default)
+
+ Creates an encoder object using \a encoding and \a flags.
+*/
+
+/*!
+ \fn constexpr QStringEncoder::QStringEncoder(const char *name, Flags flags = Flag::Default)
+
+ Creates an encoder object using \a name and \a flags.
+ If \a name is not the name of a known encoding an invalid converter will get created.
+
+ \sa isValid()
+*/
+
+/*!
+ \fn QByteArray QStringEncoder::operator()(const QString &in)
+
+ Converts \a in and returns the data as a byte array.
+*/
+
+/*!
+ \fn QByteArray QStringEncoder::operator()(const QStringView in)
+ \overload
+
+ Converts \a in and returns the data as a byte array.
+*/
+
+/*!
+ \fn QByteArray QStringEncoder::operator()(const QChar *in, qsizetype length)
+ \overload
+
+ Converts \a length QChars from \a in and returns the data as a byte array.
+*/
+
+/*!
+ \fn qsizetype QStringEncoder::requiredSpace(qsizetype inputLength) const
+
+ Returns the maximum amount of characters required to be able to process
+ \a inputLength decoded data.
+
+ \sa appendToBuffer
+*/
+
+/*!
+ \fn char *QStringEncoder::appendToBuffer(char *out, const QChar *in, qsizetype length)
+
+ Encodes \a length QChars from \a in and writes the encoded result into the buffer
+ starting at \a out. Returns a pointer to the end of data written.
+
+ \a out needs to be large enough to be able to hold all the decoded data. Use
+ \l{requiredSpace} to determine the maximum size requirements to be able to encode
+ a QChar buffer of \a length.
+
+ \sa requiredSpace
+*/
+
+/*!
+ \class QStringDecoder
+ \inmodule QtCore
+ \brief The QStringDecoder class provides a state-based decoder for text.
+ \reentrant
+ \ingroup i18n
+
+ A text decoder converts text an encoded text format that uses a specific encoding
+ into Qt's internal representation.
+
+ Converting encoded data into a QString can be achieved
+ using the following code:
+
+ \snippet code/src_corelib_text_qstringconverter.cpp 0
+
+ The decoder remembers any state that is required between calls, so converting
+ data received in chunks, for example, when receiving it over a network, is just as
+ easy, by calling the decoder whenever new data is available:
+
+ \snippet code/src_corelib_text_qstringconverter.cpp 2
+
+ The QStringDecoder object maintains state between chunks and therefore
+ works correctly even if chunks are split in the middle of a multi-byte character
+ sequence.
+
+ QStringDecoder objects can't be copied because of their internal state, but
+ can be moved.
+
+ \sa QStringConverter, QStringEncoder
+*/
+
+/*!
+ \fn constexpr QStringDecoder::QStringDecoder(const Interface *i)
+ \internal
+*/
+
+/*!
+ \fn constexpr QStringDecoder::QStringDecoder()
+
+ Default constructs an decoder. The default decoder is not valid,
+ and can't be used for converting text.
+*/
+
+/*!
+ \fn constexpr QStringDecoder::QStringDecoder(Encoding encoding, Flags flags = Flag::Default)
+
+ Creates an decoder object using \a encoding and \a flags.
+*/
+
+/*!
+ \fn constexpr QStringDecoder::QStringDecoder(const char *name, Flags flags = Flag::Default)
+
+ Creates an decoder object using \a name and \a flags.
+ If \a name is not the name of a known encoding an invalid converter will get created.
+
+ \sa isValid()
+*/
+
+/*!
+ \fn QByteArray QStringDecoder::operator()(const QString &in)
+
+ Converts \a in and returns the data as a QString.
+*/
+
+/*!
+ \fn QByteArray QStringDecoder::operator()(const QStringView in)
+ \overload
+
+ Converts \a in and returns the data as a QString.
+*/
+
+/*!
+ \fn QByteArray QStringDecoder::operator()(const QChar *in, qsizetype length)
+ \overload
+
+ Converts \a length QChars from \a in and returns the data as a QString.
+*/
+
+/*!
+ \fn qsizetype QStringDecoder::requiredSpace(qsizetype inputLength) const
+
+ Returns the maximum amount of UTF-16 code units required to be able to process
+ \a inputLength encoded data.
+
+ \sa appendToBuffer
+*/
+
+/*!
+ \fn QChar *QStringDecoder::appendToBuffer(QChar *out, const char *in, qsizetype length)
+
+ Decodes \a length bytes from \a in and writes the decoded result into the buffer
+ starting at \a out. Returns a pointer to the end of data written.
+
+ \a out needs to be large enough to be able to hold all the decoded data. Use
+ \l{requiredSpace} to determine the maximum size requirements to decode an encoded
+ data buffer of \a length.
+
+ \sa requiredSpace
+*/
+
QT_END_NAMESPACE
diff --git a/src/corelib/text/qstringconverter.h b/src/corelib/text/qstringconverter.h
index 989773e113b..3d089f46a4c 100644
--- a/src/corelib/text/qstringconverter.h
+++ b/src/corelib/text/qstringconverter.h
@@ -64,7 +64,7 @@ public:
Stateless = 0x1,
ConvertInvalidToNull = 0x2,
WriteBom = 0x4,
- DontSkipInitialBom = 0x8
+ ConvertInitialBom = 0x8
};
Q_DECLARE_FLAGS(Flags, Flag)
@@ -123,9 +123,21 @@ public:
Utf32LE,
Utf32BE,
Latin1,
- Locale,
- LastEncoding = Locale
+ System,
+ LastEncoding = System
};
+#ifdef Q_QDOC
+ // document the flags here
+ enum class Flag {
+ Default = 0,
+ Stateless = 0x1,
+ ConvertInvalidToNull = 0x2,
+ WriteBom = 0x4,
+ ConvertInitialBom = 0x8
+ };
+ Q_DECLARE_FLAGS(Flags, Flag)
+#endif
+
protected:
struct Interface
@@ -150,7 +162,7 @@ protected:
QSTRINGCONVERTER_CONSTEXPR QStringConverter(const Interface *i)
: iface(i)
{}
- Q_CORE_EXPORT QStringConverter(const char *name);
+ Q_CORE_EXPORT QStringConverter(const char *name, Flags f);
public:
@@ -190,8 +202,8 @@ public:
QSTRINGCONVERTER_CONSTEXPR QStringEncoder(Encoding encoding, Flags flags = Flag::Default)
: QStringConverter(encoding, flags)
{}
- QStringEncoder(const char *name)
- : QStringConverter(name)
+ QStringEncoder(const char *name, Flags flags = Flag::Default)
+ : QStringConverter(name, flags)
{}
#if defined(QT_USE_FAST_OPERATOR_PLUS) || defined(QT_USE_QSTRINGBUILDER)
@@ -221,8 +233,9 @@ public:
qsizetype requiredSpace(qsizetype inputLength) const
{ return iface->fromUtf16Len(inputLength); }
- char *decodeIntoBuffer(char *out, const QChar *in, qsizetype length)
+ char *appendToBuffer(char *out, const QChar *in, qsizetype length)
{ return iface->fromUtf16(out, QStringView(in, length), &state); }
+private:
QByteArray encode(QStringView in)
{
QByteArray result(iface->fromUtf16Len(in.size()), Qt::Uninitialized);
@@ -256,8 +269,8 @@ public:
QSTRINGCONVERTER_CONSTEXPR QStringDecoder()
: QStringConverter()
{}
- QStringDecoder(const char *name)
- : QStringConverter(name)
+ QStringDecoder(const char *name, Flags f = Flag::Default)
+ : QStringConverter(name, f)
{}
#if defined(QT_USE_FAST_OPERATOR_PLUS) || defined(QT_USE_QSTRINGBUILDER)
@@ -285,8 +298,9 @@ public:
qsizetype requiredSpace(qsizetype inputLength) const
{ return iface->toUtf16Len(inputLength); }
- QChar *decodeIntoBuffer(QChar *out, const char *in, qsizetype length)
+ QChar *appendToBuffer(QChar *out, const char *in, qsizetype length)
{ return iface->toUtf16(out, in, length, &state); }
+private:
QString decode(const char *in, qsizetype length)
{
QString result(iface->toUtf16Len(length), Qt::Uninitialized);
@@ -310,7 +324,7 @@ struct QConcatenable<QStringDecoder::EncodedData<T>>
static qsizetype size(const QStringDecoder::EncodedData<T> &s) { return s.decoder->requiredSpace(s.data.length()); }
static inline void appendTo(const QStringDecoder::EncodedData<T> &s, QChar *&out)
{
- out = s.decoder->decodeIntoBuffer(out, s.data.data(), s.data.length());
+ out = s.decoder->appendToBuffer(out, s.data.data(), s.data.length());
}
};
@@ -324,7 +338,7 @@ struct QConcatenable<QStringEncoder::DecodedData<T>>
static qsizetype size(const QStringEncoder::DecodedData<T> &s) { return s.encoder->requiredSpace(s.data.length()); }
static inline void appendTo(const QStringEncoder::DecodedData<T> &s, char *&out)
{
- out = s.decoder->decodeIntoBuffer(out, s.data.data(), s.data.length());
+ out = s.decoder->appendToBuffer(out, s.data.data(), s.data.length());
}
};
diff --git a/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp b/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp
index a79d1af3141..ab2e2175ea6 100644
--- a/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp
+++ b/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp
@@ -1792,7 +1792,7 @@ void tst_QTextStream::utf8IncompleteAtBufferBoundary()
if (!useLocale)
in.setEncoding(QStringConverter::Utf8);
else
- in.setEncoding(QStringConverter::Locale);
+ in.setEncoding(QStringConverter::System);
int i = 0;
do {
diff --git a/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp b/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp
index 78595bc17b7..e95bce6915b 100644
--- a/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp
+++ b/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp
@@ -1432,12 +1432,12 @@ void tst_QStringConverter::utfHeaders_data()
<< QString::fromLatin1("hello");
QTest::newRow("utf8 bom ignore header")
<< QStringConverter::Utf8
- << QStringConverter::Flag::DontSkipInitialBom
+ << QStringConverter::Flag::ConvertInitialBom
<< QByteArray("\xef\xbb\xbfhello")
<< (QString(QChar(0xfeff)) + QString::fromLatin1("hello"));
QTest::newRow("utf8 nobom ignore header")
<< QStringConverter::Utf8
- << QStringConverter::Flag::DontSkipInitialBom
+ << QStringConverter::Flag::ConvertInitialBom
<< QByteArray("hello")
<< QString::fromLatin1("hello");
@@ -1459,7 +1459,7 @@ void tst_QStringConverter::utfHeaders_data()
<< QString::fromLatin1("hel");
QTest::newRow("utf16 bom be ignore header")
<< QStringConverter::Utf16
- << QStringConverter::Flag::DontSkipInitialBom
+ << QStringConverter::Flag::ConvertInitialBom
<< QByteArray("\xfe\xff\0h\0e\0l", 8)
<< (QString(QChar(0xfeff)) + QString::fromLatin1("hel"));
} else {
@@ -1470,7 +1470,7 @@ void tst_QStringConverter::utfHeaders_data()
<< QString::fromLatin1("hel");
QTest::newRow("utf16 bom le ignore header")
<< QStringConverter::Utf16
- << QStringConverter::Flag::DontSkipInitialBom
+ << QStringConverter::Flag::ConvertInitialBom
<< QByteArray("\xff\xfeh\0e\0l\0", 8)
<< (QString(QChar(0xfeff)) + QString::fromLatin1("hel"));
}
@@ -1487,7 +1487,7 @@ void tst_QStringConverter::utfHeaders_data()
<< QString::fromLatin1("hel");
QTest::newRow("utf16-be bom be ignore header")
<< QStringConverter::Utf16BE
- << QStringConverter::Flag::DontSkipInitialBom
+ << QStringConverter::Flag::ConvertInitialBom
<< QByteArray("\xfe\xff\0h\0e\0l", 8)
<< (QString(QChar(0xfeff)) + QString::fromLatin1("hel"));
@@ -1503,7 +1503,7 @@ void tst_QStringConverter::utfHeaders_data()
<< QString::fromLatin1("hel");
QTest::newRow("utf16-le bom le ignore header")
<< QStringConverter::Utf16LE
- << QStringConverter::Flag::DontSkipInitialBom
+ << QStringConverter::Flag::ConvertInitialBom
<< QByteArray("\xff\xfeh\0e\0l\0", 8)
<< (QString(QChar(0xfeff)) + QString::fromLatin1("hel"));
@@ -1525,7 +1525,7 @@ void tst_QStringConverter::utfHeaders_data()
<< QString::fromLatin1("hel");
QTest::newRow("utf32 bom be ignore header")
<< QStringConverter::Utf32
- << QStringConverter::Flag::DontSkipInitialBom
+ << QStringConverter::Flag::ConvertInitialBom
<< QByteArray("\0\0\xfe\xff\0\0\0h\0\0\0e\0\0\0l", 16)
<< (QString(QChar(0xfeff)) + QString::fromLatin1("hel"));
} else {
@@ -1536,7 +1536,7 @@ void tst_QStringConverter::utfHeaders_data()
<< QString::fromLatin1("hel");
QTest::newRow("utf32 bom le ignore header")
<< QStringConverter::Utf32
- << QStringConverter::Flag::DontSkipInitialBom
+ << QStringConverter::Flag::ConvertInitialBom
<< QByteArray("\xff\xfe\0\0h\0\0\0e\0\0\0l\0\0\0", 16)
<< (QString(QChar(0xfeff)) + QString::fromLatin1("hel"));
}
@@ -1553,7 +1553,7 @@ void tst_QStringConverter::utfHeaders_data()
<< QString::fromLatin1("hel");
QTest::newRow("utf32-be bom be ignore header")
<< QStringConverter::Utf32BE
- << QStringConverter::Flag::DontSkipInitialBom
+ << QStringConverter::Flag::ConvertInitialBom
<< QByteArray("\0\0\xfe\xff\0\0\0h\0\0\0e\0\0\0l", 16)
<< (QString(QChar(0xfeff)) + QString::fromLatin1("hel"));
@@ -1569,7 +1569,7 @@ void tst_QStringConverter::utfHeaders_data()
<< QString::fromLatin1("hel");
QTest::newRow("utf32-le bom le ignore header")
<< QStringConverter::Utf32LE
- << QStringConverter::Flag::DontSkipInitialBom
+ << QStringConverter::Flag::ConvertInitialBom
<< QByteArray("\xff\xfe\0\0h\0\0\0e\0\0\0l\0\0\0", 16)
<< (QString(QChar(0xfeff)) + QString::fromLatin1("hel"));
}