QString::vasprintf: avoid allocating memory just to parse a number

Port parse_field_width from constructing a QString and
then calling toInt() on it to use qstrtoull().

Not only do we not allocate memory anymore, we even
don't need to copy the digits out of the format
string - qstrtoull() does it all for us.

In order to preserve behavior with the previous code,
which consumed all digits before performing error
checking on them, we also consume all digits, even if
qstrtoull() would have returned the start of the range
as the end pointer.

Change-Id: Ief941ce3a8ea43d2e5475d9eab77d7d0d7abc450
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
This commit is contained in:
Marc Mutz 2015-11-04 13:59:10 +01:00
parent e17629e32d
commit 110e82f5e9

View File

@ -40,6 +40,7 @@
#include <qtextcodec.h>
#endif
#include <private/qutfcodec_p.h>
#include <private/qlocale_tools_p.h>
#include "qsimd_p.h"
#include <qnumeric.h>
#include <qdatastream.h>
@ -5885,13 +5886,17 @@ static uint parse_flag_characters(const char * &c) Q_DECL_NOTHROW
static int parse_field_width(const char * &c)
{
QString width_str;
while (*c != '\0' && qIsDigit(*c))
width_str.append(QLatin1Char(*c++));
Q_ASSERT(qIsDigit(*c));
// can't be negative - started with a digit
// contains at least one digit
return width_str.toInt();
const char *endp;
bool ok;
const qulonglong result = qstrtoull(c, &endp, 10, &ok);
c = endp;
while (qIsDigit(*c)) // preserve Qt 5.5 behavior of consuming all digits, no matter how many
++c;
return ok && result < qulonglong(std::numeric_limits<int>::max()) ? int(result) : 0;
}
/*!