Rework QLocalePrivate::bytearrayToU?LongLong()
Change it to take a QByteArrayView instead of a plain char *; all its callers do know the size and propagating it enables the implementation to call strntou?ll() rather than strtou?ll(), thereby escaping the need for '\0'-termination. Fixes: QTBUG-74286 Change-Id: Ie9394786e9fcf25c1d1be2421805f47c018d13bb Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
parent
7d33779a79
commit
88b54cc22a
@ -3507,18 +3507,18 @@ bool QByteArray::isNull() const
|
|||||||
return d->isNull();
|
return d->isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
static qlonglong toIntegral_helper(const char *data, bool *ok, int base, qlonglong)
|
static qlonglong toIntegral_helper(QByteArrayView data, bool *ok, int base, qlonglong)
|
||||||
{
|
{
|
||||||
return QLocaleData::bytearrayToLongLong(data, base, ok);
|
return QLocaleData::bytearrayToLongLong(data, base, ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
static qulonglong toIntegral_helper(const char *data, bool *ok, int base, qulonglong)
|
static qulonglong toIntegral_helper(QByteArrayView data, bool *ok, int base, qulonglong)
|
||||||
{
|
{
|
||||||
return QLocaleData::bytearrayToUnsLongLong(data, base, ok);
|
return QLocaleData::bytearrayToUnsLongLong(data, base, ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> static inline
|
template <typename T> static inline
|
||||||
T toIntegral_helper(const char *data, bool *ok, int base)
|
T toIntegral_helper(QByteArrayView data, bool *ok, int base)
|
||||||
{
|
{
|
||||||
using Int64 = typename std::conditional<std::is_unsigned<T>::value, qulonglong, qlonglong>::type;
|
using Int64 = typename std::conditional<std::is_unsigned<T>::value, qulonglong, qlonglong>::type;
|
||||||
|
|
||||||
@ -3528,7 +3528,7 @@ T toIntegral_helper(const char *data, bool *ok, int base)
|
|||||||
base = 10;
|
base = 10;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (!data) {
|
if (data.isEmpty()) {
|
||||||
if (ok)
|
if (ok)
|
||||||
*ok = false;
|
*ok = false;
|
||||||
return 0;
|
return 0;
|
||||||
@ -3568,7 +3568,7 @@ T toIntegral_helper(const char *data, bool *ok, int base)
|
|||||||
|
|
||||||
qlonglong QByteArray::toLongLong(bool *ok, int base) const
|
qlonglong QByteArray::toLongLong(bool *ok, int base) const
|
||||||
{
|
{
|
||||||
return toIntegral_helper<qlonglong>(nulTerminated().constData(), ok, base);
|
return toIntegral_helper<qlonglong>(*this, ok, base);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -3595,7 +3595,7 @@ qlonglong QByteArray::toLongLong(bool *ok, int base) const
|
|||||||
|
|
||||||
qulonglong QByteArray::toULongLong(bool *ok, int base) const
|
qulonglong QByteArray::toULongLong(bool *ok, int base) const
|
||||||
{
|
{
|
||||||
return toIntegral_helper<qulonglong>(nulTerminated().constData(), ok, base);
|
return toIntegral_helper<qulonglong>(*this, ok, base);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -3624,7 +3624,7 @@ qulonglong QByteArray::toULongLong(bool *ok, int base) const
|
|||||||
|
|
||||||
int QByteArray::toInt(bool *ok, int base) const
|
int QByteArray::toInt(bool *ok, int base) const
|
||||||
{
|
{
|
||||||
return toIntegral_helper<int>(nulTerminated().constData(), ok, base);
|
return toIntegral_helper<int>(*this, ok, base);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -3651,7 +3651,7 @@ int QByteArray::toInt(bool *ok, int base) const
|
|||||||
|
|
||||||
uint QByteArray::toUInt(bool *ok, int base) const
|
uint QByteArray::toUInt(bool *ok, int base) const
|
||||||
{
|
{
|
||||||
return toIntegral_helper<uint>(nulTerminated().constData(), ok, base);
|
return toIntegral_helper<uint>(*this, ok, base);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -3681,7 +3681,7 @@ uint QByteArray::toUInt(bool *ok, int base) const
|
|||||||
*/
|
*/
|
||||||
long QByteArray::toLong(bool *ok, int base) const
|
long QByteArray::toLong(bool *ok, int base) const
|
||||||
{
|
{
|
||||||
return toIntegral_helper<long>(nulTerminated().constData(), ok, base);
|
return toIntegral_helper<long>(*this, ok, base);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -3709,7 +3709,7 @@ long QByteArray::toLong(bool *ok, int base) const
|
|||||||
*/
|
*/
|
||||||
ulong QByteArray::toULong(bool *ok, int base) const
|
ulong QByteArray::toULong(bool *ok, int base) const
|
||||||
{
|
{
|
||||||
return toIntegral_helper<ulong>(nulTerminated().constData(), ok, base);
|
return toIntegral_helper<ulong>(*this, ok, base);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -3736,7 +3736,7 @@ ulong QByteArray::toULong(bool *ok, int base) const
|
|||||||
|
|
||||||
short QByteArray::toShort(bool *ok, int base) const
|
short QByteArray::toShort(bool *ok, int base) const
|
||||||
{
|
{
|
||||||
return toIntegral_helper<short>(nulTerminated().constData(), ok, base);
|
return toIntegral_helper<short>(*this, ok, base);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -3763,7 +3763,7 @@ short QByteArray::toShort(bool *ok, int base) const
|
|||||||
|
|
||||||
ushort QByteArray::toUShort(bool *ok, int base) const
|
ushort QByteArray::toUShort(bool *ok, int base) const
|
||||||
{
|
{
|
||||||
return toIntegral_helper<ushort>(nulTerminated().constData(), ok, base);
|
return toIntegral_helper<ushort>(*this, ok, base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3997,7 +3997,7 @@ qlonglong QLocaleData::stringToLongLong(QStringView str, int base, bool *ok,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bytearrayToLongLong(buff.constData(), base, ok);
|
return bytearrayToLongLong(QByteArrayView(buff.constData(), buff.size()), base, ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
qulonglong QLocaleData::stringToUnsLongLong(QStringView str, int base, bool *ok,
|
qulonglong QLocaleData::stringToUnsLongLong(QStringView str, int base, bool *ok,
|
||||||
@ -4010,34 +4010,34 @@ qulonglong QLocaleData::stringToUnsLongLong(QStringView str, int base, bool *ok,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bytearrayToUnsLongLong(buff.constData(), base, ok);
|
return bytearrayToUnsLongLong(QByteArrayView(buff.constData(), buff.size()), base, ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
qlonglong QLocaleData::bytearrayToLongLong(const char *num, int base, bool *ok)
|
qlonglong QLocaleData::bytearrayToLongLong(QByteArrayView num, int base, bool *ok)
|
||||||
{
|
{
|
||||||
|
if (num.isEmpty() || num.at(0) == '\0') {
|
||||||
|
if (ok != nullptr)
|
||||||
|
*ok = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool _ok;
|
bool _ok;
|
||||||
const char *endptr;
|
const char *endptr;
|
||||||
|
const qlonglong l = qstrntoll(num.data(), num.size(), &endptr, base, &_ok);
|
||||||
|
|
||||||
if (*num == '\0') {
|
if (!_ok || endptr == num.data()) {
|
||||||
if (ok != nullptr)
|
if (ok != nullptr)
|
||||||
*ok = false;
|
*ok = false;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
qlonglong l = qstrtoll(num, &endptr, base, &_ok);
|
const char *const stop = num.end();
|
||||||
|
if (endptr < stop && *endptr != '\0') {
|
||||||
if (!_ok) {
|
while (endptr < stop && ascii_isspace(*endptr))
|
||||||
if (ok != nullptr)
|
|
||||||
*ok = false;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*endptr != '\0') {
|
|
||||||
while (ascii_isspace(*endptr))
|
|
||||||
++endptr;
|
++endptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*endptr != '\0') {
|
if (endptr < stop && *endptr != '\0') {
|
||||||
// we stopped at a non-digit character after converting some digits
|
// we stopped at a non-digit character after converting some digits
|
||||||
if (ok != nullptr)
|
if (ok != nullptr)
|
||||||
*ok = false;
|
*ok = false;
|
||||||
@ -4049,24 +4049,31 @@ qlonglong QLocaleData::bytearrayToLongLong(const char *num, int base, bool *ok)
|
|||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
qulonglong QLocaleData::bytearrayToUnsLongLong(const char *num, int base, bool *ok)
|
qulonglong QLocaleData::bytearrayToUnsLongLong(QByteArrayView num, int base, bool *ok)
|
||||||
{
|
{
|
||||||
bool _ok;
|
if (num.isEmpty() || num.at(0) == '\0') {
|
||||||
const char *endptr;
|
|
||||||
qulonglong l = qstrtoull(num, &endptr, base, &_ok);
|
|
||||||
|
|
||||||
if (!_ok) {
|
|
||||||
if (ok != nullptr)
|
if (ok != nullptr)
|
||||||
*ok = false;
|
*ok = false;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*endptr != '\0') {
|
bool _ok;
|
||||||
while (ascii_isspace(*endptr))
|
const char *endptr;
|
||||||
|
const qulonglong l = qstrntoull(num.data(), num.size(), &endptr, base, &_ok);
|
||||||
|
|
||||||
|
if (!_ok || endptr == num.data()) {
|
||||||
|
if (ok != nullptr)
|
||||||
|
*ok = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *const stop = num.end();
|
||||||
|
if (endptr < stop && *endptr != '\0') {
|
||||||
|
while (endptr < stop && ascii_isspace(*endptr))
|
||||||
++endptr;
|
++endptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*endptr != '\0') {
|
if (endptr < stop && *endptr != '\0') {
|
||||||
if (ok != nullptr)
|
if (ok != nullptr)
|
||||||
*ok = false;
|
*ok = false;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2020 The Qt Company Ltd.
|
** Copyright (C) 2021 The Qt Company Ltd.
|
||||||
** Copyright (C) 2016 Intel Corporation.
|
** Copyright (C) 2016 Intel Corporation.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
@ -276,8 +276,8 @@ public:
|
|||||||
quint64 stringToUnsLongLong(QStringView str, int base, bool *ok, QLocale::NumberOptions options) const;
|
quint64 stringToUnsLongLong(QStringView str, int base, bool *ok, QLocale::NumberOptions options) const;
|
||||||
|
|
||||||
// this function is used in QIntValidator (QtGui)
|
// this function is used in QIntValidator (QtGui)
|
||||||
Q_CORE_EXPORT static qint64 bytearrayToLongLong(const char *num, int base, bool *ok);
|
Q_CORE_EXPORT static qint64 bytearrayToLongLong(QByteArrayView num, int base, bool *ok);
|
||||||
static quint64 bytearrayToUnsLongLong(const char *num, int base, bool *ok);
|
static quint64 bytearrayToUnsLongLong(QByteArrayView num, int base, bool *ok);
|
||||||
|
|
||||||
bool numberToCLocale(QStringView s, QLocale::NumberOptions number_options,
|
bool numberToCLocale(QStringView s, QLocale::NumberOptions number_options,
|
||||||
CharBuff *result) const;
|
CharBuff *result) const;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2016 The Qt Company Ltd.
|
** Copyright (C) 2021 The Qt Company Ltd.
|
||||||
** Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
|
** Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
@ -421,7 +421,7 @@ QValidator::State QIntValidator::validate(QString & input, int&) const
|
|||||||
return Intermediate;
|
return Intermediate;
|
||||||
|
|
||||||
bool ok;
|
bool ok;
|
||||||
qlonglong entered = QLocaleData::bytearrayToLongLong(buff.constData(), 10, &ok);
|
qlonglong entered = QLocaleData::bytearrayToLongLong(buff, 10, &ok);
|
||||||
if (!ok)
|
if (!ok)
|
||||||
return Invalid;
|
return Invalid;
|
||||||
|
|
||||||
@ -456,7 +456,7 @@ void QIntValidator::fixup(QString &input) const
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bool ok;
|
bool ok;
|
||||||
qlonglong entered = QLocaleData::bytearrayToLongLong(buff.constData(), 10, &ok);
|
qlonglong entered = QLocaleData::bytearrayToLongLong(buff, 10, &ok);
|
||||||
if (ok)
|
if (ok)
|
||||||
input = locale().toString(entered);
|
input = locale().toString(entered);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user