Speed up and fix QByteArray::setNum()

Going through QLocale and QString is not really needed.

This also makes the result of the conversion of negative numbers
in bases other than 10 independent of the architecture and
implements the documented behavior of treating them as
unsigned types.

Change-Id: Ibc231dc5241deb5cbadd9796484a8b5f79c29410
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
bb10
hjk 2012-12-20 13:20:43 +01:00 committed by The Qt Project
parent 8094c8fe18
commit 03a666760c
3 changed files with 54 additions and 15 deletions

View File

@ -3585,7 +3585,8 @@ QByteArray QByteArray::toBase64() const
Sets the byte array to the printed value of \a n in base \a base (10
by default) and returns a reference to the byte array. The \a base can
be any value between 2 and 36.
be any value between 2 and 36. For bases other than 10, n is treated
as an unsigned integer.
Example:
\snippet code/src_corelib_tools_qbytearray.cpp 40
@ -3623,7 +3624,7 @@ QByteArray QByteArray::toBase64() const
\sa toLongLong()
*/
QByteArray &QByteArray::setNum(qlonglong n, int base)
static char *qulltoa2(char *p, qulonglong n, int base)
{
#if defined(QT_CHECK_RANGE)
if (base < 2 || base > 36) {
@ -3631,8 +3632,31 @@ QByteArray &QByteArray::setNum(qlonglong n, int base)
base = 10;
}
#endif
QLocale locale(QLocale::C);
*this = locale.d->longLongToString(n, -1, base).toLatin1();
const char b = 'a' - 10;
do {
const int c = n % base;
n /= base;
*--p = c + (c < 10 ? '0' : b);
} while (n);
return p;
}
QByteArray &QByteArray::setNum(qlonglong n, int base)
{
const int buffsize = 66; // big enough for MAX_ULLONG in base 2
char buff[buffsize];
char *p;
if (n < 0 && base == 10) {
p = qulltoa2(buff + buffsize, qulonglong(-(1 + n)) + 1, base);
*--p = '-';
} else {
p = qulltoa2(buff + buffsize, qulonglong(n), base);
}
clear();
append(p, buffsize - (p - buff));
return *this;
}
@ -3644,14 +3668,12 @@ QByteArray &QByteArray::setNum(qlonglong n, int base)
QByteArray &QByteArray::setNum(qulonglong n, int base)
{
#if defined(QT_CHECK_RANGE)
if (base < 2 || base > 36) {
qWarning("QByteArray::setNum: Invalid base %d", base);
base = 10;
}
#endif
QLocale locale(QLocale::C);
*this = locale.d->unsLongLongToString(n, -1, base).toLatin1();
const int buffsize = 66; // big enough for MAX_ULLONG in base 2
char buff[buffsize];
char *p = qulltoa2(buff + buffsize, n, base);
clear();
append(p, buffsize - (p - buff));
return *this;
}

View File

@ -581,11 +581,11 @@ inline QByteArray &QByteArray::replace(const char *before, const char *after)
{ return replace(before, qstrlen(before), after, qstrlen(after)); }
inline QByteArray &QByteArray::setNum(short n, int base)
{ return setNum(qlonglong(n), base); }
{ return base == 10 ? setNum(qlonglong(n), base) : setNum(qulonglong(ushort(n)), base); }
inline QByteArray &QByteArray::setNum(ushort n, int base)
{ return setNum(qulonglong(n), base); }
inline QByteArray &QByteArray::setNum(int n, int base)
{ return setNum(qlonglong(n), base); }
{ return base == 10 ? setNum(qlonglong(n), base) : setNum(qulonglong(uint(n)), base); }
inline QByteArray &QByteArray::setNum(uint n, int base)
{ return setNum(qulonglong(n), base); }
inline QByteArray &QByteArray::setNum(float n, char f, int prec)

View File

@ -401,7 +401,24 @@ void tst_QByteArray::rightJustified()
void tst_QByteArray::setNum()
{
QByteArray a;
QCOMPARE(a.setNum(123), QByteArray("123"));
QCOMPARE(a.setNum(-1), QByteArray("-1"));
QCOMPARE(a.setNum(0), QByteArray("0"));
QCOMPARE(a.setNum(0, 2), QByteArray("0"));
QCOMPARE(a.setNum(0, 36), QByteArray("0"));
QCOMPARE(a.setNum(1), QByteArray("1"));
QCOMPARE(a.setNum(35, 36), QByteArray("z"));
QCOMPARE(a.setNum(37, 2), QByteArray("100101"));
QCOMPARE(a.setNum(37, 36), QByteArray("11"));
// Negative numbers are only properly supported for base 10.
QCOMPARE(a.setNum(short(-1), 16), QByteArray("ffff"));
QCOMPARE(a.setNum(int(-1), 16), QByteArray("ffffffff"));
QCOMPARE(a.setNum(qlonglong(-1), 16), QByteArray("ffffffffffffffff"));
QCOMPARE(a.setNum(short(-1), 10), QByteArray("-1"));
QCOMPARE(a.setNum(int(-1), 10), QByteArray("-1"));
QCOMPARE(a.setNum(qlonglong(-1), 10), QByteArray("-1"));
QCOMPARE(a.setNum(-123), QByteArray("-123"));
QCOMPARE(a.setNum(0x123,16), QByteArray("123"));
QCOMPARE(a.setNum((short)123), QByteArray("123"));