diff options
-rw-r--r-- | src/corelib/text/qstring.cpp | 75 | ||||
-rw-r--r-- | src/corelib/text/qstring.h | 40 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qiosscreen.mm | 2 | ||||
-rw-r--r-- | tests/auto/corelib/text/qstring/tst_qstring.cpp | 39 |
4 files changed, 88 insertions, 68 deletions
diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp index 5b654264ac..5721a25106 100644 --- a/src/corelib/text/qstring.cpp +++ b/src/corelib/text/qstring.cpp @@ -5133,30 +5133,36 @@ QList<uint> QtPrivate::convertToUcs4(QStringView string) return qt_convert_to_ucs4(string); } -QString::DataPointer QString::fromLatin1_helper(const char *str, qsizetype size) +/*! + \fn QString QString::fromLatin1(QByteArrayView str) + \overload + \since 6.0 + + Returns a QString initialized with the Latin-1 string \a str. +*/ +QString QString::fromLatin1(QByteArrayView ba) { DataPointer d; - if (!str) { + if (!ba.data()) { // nothing to do - } else if (size == 0 || (!*str && size < 0)) { + } else if (ba.size() == 0) { d = DataPointer::fromRawData(&_empty, 0); } else { - if (size < 0) - size = qstrlen(str); - d = DataPointer(Data::allocate(size), size); - d.data()[size] = '\0'; + d = DataPointer(Data::allocate(ba.size()), ba.size()); + d.data()[ba.size()] = '\0'; char16_t *dst = d.data(); - qt_from_latin1(dst, str, size_t(size)); + + qt_from_latin1(dst, ba.data(), size_t(ba.size())); } - return d; + return QString(std::move(d)); } -/*! \fn QString QString::fromLatin1(const char *str, qsizetype size) +/*! + \fn QString QString::fromLatin1(const char *str, qsizetype size) Returns a QString initialized with the first \a size characters of the Latin-1 string \a str. - If \a size is -1 (default), it is taken to be strlen(\a - str). + If \a size is \c{-1}, \c{strlen(str)} is used instead. \sa toLatin1(), fromUtf8(), fromLocal8Bit() */ @@ -5169,12 +5175,12 @@ QString::DataPointer QString::fromLatin1_helper(const char *str, qsizetype size) Returns a QString initialized with the Latin-1 string \a str. */ -/*! \fn QString QString::fromLocal8Bit(const char *str, qsizetype size) +/*! + \fn QString QString::fromLocal8Bit(const char *str, qsizetype size) Returns a QString initialized with the first \a size characters of the 8-bit string \a str. - If \a size is -1 (default), it is taken to be strlen(\a - str). + If \a size is \c{-1}, \c{strlen(str)} is used instead. On Unix systems this is equivalen to fromUtf8(), on Windows the systems current code page is being used. @@ -5189,24 +5195,29 @@ QString::DataPointer QString::fromLatin1_helper(const char *str, qsizetype size) Returns a QString initialized with the 8-bit string \a str. */ -QString QString::fromLocal8Bit_helper(const char *str, qsizetype size) + +/*! + \fn QString QString::fromLocal8Bit(QByteArrayView str) + \overload + \since 6.0 + + Returns a QString initialized with the 8-bit string \a str. +*/ +QString QString::fromLocal8Bit(QByteArrayView ba) { - if (!str) + if (ba.isNull()) return QString(); - if (size < 0) - size = qstrlen(str); - if (size == 0) + if (ba.isEmpty()) return QString(DataPointer::fromRawData(&_empty, 0)); QStringDecoder toUtf16(QStringDecoder::System, QStringDecoder::Flag::Stateless); - return toUtf16(str, size); + return toUtf16(ba.data(), ba.size()); } /*! \fn QString QString::fromUtf8(const char *str, qsizetype size) Returns a QString initialized with the first \a size bytes of the UTF-8 string \a str. - If \a size is -1 (default), it is taken to be strlen(\a - str). + If \a size is \c{-1}, \c{strlen(str)} is used instead. UTF-8 is a Unicode codec and can represent all characters in a Unicode string like QString. However, invalid sequences are possible with UTF-8 @@ -5238,13 +5249,21 @@ QString QString::fromLocal8Bit_helper(const char *str, qsizetype size) Returns a QString initialized with the UTF-8 string \a str. */ -QString QString::fromUtf8_helper(const char *str, qsizetype size) + +/*! + \fn QString QString::fromUtf8(QByteArrayView str) + \overload + \since 6.0 + + Returns a QString initialized with the UTF-8 string \a str. +*/ +QString QString::fromUtf8(QByteArrayView ba) { - if (!str) + if (ba.isNull()) return QString(); - - Q_ASSERT(size != -1); - return QUtf8::convertToUnicode(str, size); + if (ba.isEmpty()) + return QString(DataPointer::fromRawData(&_empty, 0)); + return QUtf8::convertToUnicode(ba.data(), ba.size()); } /*! diff --git a/src/corelib/text/qstring.h b/src/corelib/text/qstring.h index 0e564b20ed..d12c96632e 100644 --- a/src/corelib/text/qstring.h +++ b/src/corelib/text/qstring.h @@ -669,29 +669,32 @@ public: [[nodiscard]] QList<uint> toUcs4() const; // note - this are all inline so we can benefit from strlen() compile time optimizations - static inline QString fromLatin1(const char *str, qsizetype size = -1) + static QString fromLatin1(QByteArrayView ba); + Q_WEAK_OVERLOAD + static inline QString fromLatin1(const QByteArray &ba) { return fromLatin1(QByteArrayView(ba)); } + static inline QString fromLatin1(const char *str, qsizetype size) { - return QString(fromLatin1_helper(str, (str && size == -1) ? qsizetype(strlen(str)) : size)); + return fromLatin1(QByteArrayView(str, !str || size < 0 ? qstrlen(str) : size)); } - static inline QString fromUtf8(const char *str, qsizetype size = -1) + static QString fromUtf8(QByteArrayView utf8); + Q_WEAK_OVERLOAD + static inline QString fromUtf8(const QByteArray &ba) { return fromUtf8(QByteArrayView(ba)); } + static inline QString fromUtf8(const char *utf8, qsizetype size) { - return fromUtf8_helper(str, (str && size == -1) ? qsizetype(strlen(str)) : size); + return fromUtf8(QByteArrayView(utf8, !utf8 || size < 0 ? qstrlen(utf8) : size)); } #ifdef __cpp_char8_t Q_WEAK_OVERLOAD - static inline QString fromUtf8(const char8_t *str, qsizetype size = -1) + static inline QString fromUtf8(const char8_t *str, qsizetype size) { return fromUtf8(reinterpret_cast<const char *>(str), int(size)); } #endif - static inline QString fromLocal8Bit(const char *str, qsizetype size = -1) + static QString fromLocal8Bit(QByteArrayView ba); + Q_WEAK_OVERLOAD + static inline QString fromLocal8Bit(const QByteArray &ba) { return fromLocal8Bit(QByteArrayView(ba)); } + static inline QString fromLocal8Bit(const char *str, qsizetype size) { - return fromLocal8Bit_helper(str, (str && size == -1) ? qsizetype(strlen(str)) : size); + return fromLocal8Bit(QByteArrayView(str, !str || size < 0 ? qstrlen(str) : size)); } - static inline QString fromLatin1(const QByteArray &str) - { return str.isNull() ? QString() : fromLatin1(str.data(), qstrnlen(str.constData(), str.size())); } - static inline QString fromUtf8(const QByteArray &str) - { return str.isNull() ? QString() : fromUtf8(str.data(), qstrnlen(str.constData(), str.size())); } - static inline QString fromLocal8Bit(const QByteArray &str) - { return str.isNull() ? QString() : fromLocal8Bit(str.data(), qstrnlen(str.constData(), str.size())); } static QString fromUtf16(const char16_t *, qsizetype size = -1); static QString fromUcs4(const char32_t *, qsizetype size = -1); static QString fromRawData(const QChar *, qsizetype size); @@ -964,9 +967,6 @@ private: static QString trimmed_helper(QString &str); static QString simplified_helper(const QString &str); static QString simplified_helper(QString &str); - static DataPointer fromLatin1_helper(const char *str, qsizetype size = -1); - static QString fromUtf8_helper(const char *str, qsizetype size); - static QString fromLocal8Bit_helper(const char *, qsizetype size); static QByteArray toLatin1_helper(const QString &); static QByteArray toLatin1_helper_inplace(QString &); static QByteArray toUtf8_helper(const QString &); @@ -1057,8 +1057,8 @@ QString QAnyStringView::toString() const // // QString inline members // -inline QString::QString(QLatin1String aLatin1) : d(fromLatin1_helper(aLatin1.latin1(), aLatin1.size())) -{ } +inline QString::QString(QLatin1String latin1) +{ *this = QString::fromLatin1(latin1.data(), latin1.size()); } inline const QChar QString::at(qsizetype i) const { Q_ASSERT(size_t(i) < size_t(size())); return QChar(d.data()[i]); } inline const QChar QString::operator[](qsizetype i) const @@ -1304,9 +1304,9 @@ QT_ASCII_CAST_WARN inline bool QLatin1String::operator>=(const QByteArray &s) co { return QString::fromUtf8(s) <= *this; } QT_ASCII_CAST_WARN inline bool QString::operator==(const QByteArray &s) const -{ return QString::compare_helper(constData(), size(), s.constData(), qstrnlen(s.constData(), s.size())) == 0; } +{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) == 0; } QT_ASCII_CAST_WARN inline bool QString::operator!=(const QByteArray &s) const -{ return QString::compare_helper(constData(), size(), s.constData(), qstrnlen(s.constData(), s.size())) != 0; } +{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) != 0; } QT_ASCII_CAST_WARN inline bool QString::operator<(const QByteArray &s) const { return QString::compare_helper(constData(), size(), s.constData(), s.size()) < 0; } QT_ASCII_CAST_WARN inline bool QString::operator>(const QByteArray &s) const diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 411f6ebf81..c7dbe43124 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -245,7 +245,7 @@ static QString deviceModelIdentifier() char value[size]; sysctlbyname(key, &value, &size, NULL, 0); - return QString::fromLatin1(value); + return QString::fromLatin1(QByteArrayView(value, qsizetype(size))); #endif } diff --git a/tests/auto/corelib/text/qstring/tst_qstring.cpp b/tests/auto/corelib/text/qstring/tst_qstring.cpp index 6e1b47a839..31f362888c 100644 --- a/tests/auto/corelib/text/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/text/qstring/tst_qstring.cpp @@ -1102,7 +1102,7 @@ void tst_QString::constructorQByteArray_data() ba1[5] = 'e'; ba1[6] = 'f'; - QTest::newRow( "2" ) << ba1 << QString("abc"); + QTest::newRow( "2" ) << ba1 << QString::fromUtf16(u"abc\0def", 7); QTest::newRow( "3" ) << QByteArray::fromRawData("abcd", 3) << QString("abc"); QTest::newRow( "4" ) << QByteArray("\xc3\xa9") << QString("\xc3\xa9"); @@ -1115,23 +1115,28 @@ void tst_QString::constructorQByteArray() QFETCH(QByteArray, src); QFETCH(QString, expected); - QString str1(src); - QCOMPARE(str1.length(), expected.length()); - QCOMPARE( str1, expected ); - QString strBA(src); QCOMPARE( strBA, expected ); // test operator= too + strBA.clear(); + strBA = src; + QCOMPARE( strBA, expected ); + + // test constructor/operator=(const char *) if (src.constData()[src.length()] == '\0') { + qsizetype zero = expected.indexOf(QLatin1Char('\0')); + if (zero < 0) + zero = expected.length(); + + QString str1(src.constData()); + QCOMPARE(str1.length(), zero); + QCOMPARE(str1, expected.left(zero)); + str1.clear(); str1 = src.constData(); - QCOMPARE( str1, expected ); + QCOMPARE(str1, expected.left(zero)); } - - strBA.clear(); - strBA = src; - QCOMPARE( strBA, expected ); } void tst_QString::STL() @@ -2522,7 +2527,7 @@ void tst_QString::append_bytearray_special_cases() } QFETCH( QByteArray, ba ); - if (ba.constData()[ba.length()] == '\0') { + if (!ba.contains('\0') && ba.constData()[ba.length()] == '\0') { QFETCH( QString, str ); str.append(ba.constData()); @@ -2571,7 +2576,7 @@ void tst_QString::operator_pluseq_bytearray_special_cases() } QFETCH( QByteArray, ba ); - if (ba.constData()[ba.length()] == '\0') { + if (!ba.contains('\0') && ba.constData()[ba.length()] == '\0') { QFETCH( QString, str ); str += ba.constData(); @@ -2592,7 +2597,7 @@ void tst_QString::operator_eqeq_bytearray() QVERIFY(expected == src); QVERIFY(!(expected != src)); - if (src.constData()[src.length()] == '\0') { + if (!src.contains('\0') && src.constData()[src.length()] == '\0') { QVERIFY(expected == src.constData()); QVERIFY(!(expected != src.constData())); } @@ -2653,7 +2658,7 @@ void tst_QString::prepend_bytearray_special_cases_data() // byte array with only a 0 ba.resize( 1 ); ba[0] = 0; - QTest::newRow( "emptyString" ) << QString("foobar ") << ba << QString("foobar "); + QTest::newRow( "emptyString" ) << QString("foobar ") << ba << QStringView::fromArray(u"\0foobar ").chopped(1).toString(); // empty byte array ba.resize( 0 ); @@ -2685,7 +2690,7 @@ void tst_QString::prepend_bytearray_special_cases() } QFETCH( QByteArray, ba ); - if (ba.constData()[ba.length()] == '\0') { + if (!ba.contains('\0') && ba.constData()[ba.length()] == '\0') { QFETCH( QString, str ); str.prepend(ba.constData()); @@ -4136,9 +4141,7 @@ void tst_QString::fromUtf8_data() QTest::newRow("null-1") << QByteArray() << QString() << -1; QTest::newRow("null0") << QByteArray() << QString() << 0; - QTest::newRow("null5") << QByteArray() << QString() << 5; QTest::newRow("empty-1") << QByteArray("\0abcd", 5) << QString() << -1; - QTest::newRow("empty0") << QByteArray() << QString() << 0; QTest::newRow("empty5") << QByteArray("\0abcd", 5) << QString::fromLatin1("\0abcd", 5) << 5; QTest::newRow("other-1") << QByteArray("ab\0cd", 5) << QString::fromLatin1("ab") << -1; QTest::newRow("other5") << QByteArray("ab\0cd", 5) << QString::fromLatin1("ab\0cd", 5) << 5; @@ -4474,8 +4477,6 @@ void tst_QString::fromLatin1() a = QString::fromLatin1(0, 0); QVERIFY(a.isNull()); - a = QString::fromLatin1(0, 5); - QVERIFY(a.isNull()); a = QString::fromLatin1("\0abcd", 0); QVERIFY(!a.isNull()); QVERIFY(a.isEmpty()); |