summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools
diff options
context:
space:
mode:
authorDenis Dzyubenko <denis.dzyubenko@nokia.com>2010-01-20 13:56:37 (GMT)
committerDenis Dzyubenko <denis.dzyubenko@nokia.com>2010-03-17 20:49:11 (GMT)
commit0d3c62150f2fa2c06f7676336076be4622059cc3 (patch)
tree942db968fe8737631913e15116bb9554f1f22936 /src/corelib/tools
parent41ab4760d0cac439d9dbe26f95cd6327039fbb8e (diff)
downloadQt-0d3c62150f2fa2c06f7676336076be4622059cc3.zip
Qt-0d3c62150f2fa2c06f7676336076be4622059cc3.tar.gz
Qt-0d3c62150f2fa2c06f7676336076be4622059cc3.tar.bz2
Optimized QLocale to access system locale on demand.
Changed the initialization of the system locale to make construction of the QLocale object as lightweight as possible. So now the default contructor just creates a QLocale and QSystemLocale objects, but doesn't try to fill the cache in the latter with data from the system and postpones it until it is actually requested (most applications create QLocale objects on the stack and might not even use the data from the system locale, so we don't need to initialize system locale right away). This is an improved version of an already reverted change 8911ed8bfe7f918b93c758f9b5d93274b37739e6, 8911ed8bfe7f918b93c758f9b5d93274b37739e6 and 8911ed8bfe7f918b93c758f9b5d93274b37739e6. Reviewed-by: Thiago Macieira
Diffstat (limited to 'src/corelib/tools')
-rw-r--r--src/corelib/tools/qlocale.cpp214
-rw-r--r--src/corelib/tools/qlocale.h1
-rw-r--r--src/corelib/tools/qlocale_p.h18
3 files changed, 179 insertions, 54 deletions
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index 1966a79..e36497c 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -1274,11 +1274,25 @@ QLocale QSystemLocale::fallbackLocale() const
*/
QVariant QSystemLocale::query(QueryType type, QVariant /* in */) const
{
- if (type == MeasurementSystem) {
+ switch (type) {
+ case MeasurementSystem:
return QVariant(unixGetSystemMeasurementSystem());
- } else {
- return QVariant();
+ case LanguageId:
+ case CountryId: {
+ QString locale = QLatin1String(envVarLocale());
+ QLocale::Language lang;
+ QLocale::Country cntry;
+ getLangAndCountry(locale, lang, cntry);
+ if (type == LanguageId)
+ return lang;
+ if (cntry == QLocale::AnyCountry)
+ return fallbackLocale().country();
+ return cntry;
+ }
+ default:
+ break;
}
+ return QVariant();
}
#elif !defined(Q_OS_SYMBIAN)
@@ -1310,12 +1324,10 @@ QVariant QSystemLocale::query(QueryType /* type */, QVariant /* in */) const
#endif
-#ifndef QT_NO_SYSTEMLOCALE
static QSystemLocale *_systemLocale = 0;
Q_GLOBAL_STATIC_WITH_ARGS(QSystemLocale, QSystemLocale_globalSystemLocale, (true))
static QLocalePrivate *system_lp = 0;
Q_GLOBAL_STATIC(QLocalePrivate, globalLocalePrivate)
-#endif
/******************************************************************************
** Default system locale behavior
@@ -1388,7 +1400,8 @@ QSystemLocale::QSystemLocale()
/*! \internal */
QSystemLocale::QSystemLocale(bool)
-{ }
+{
+}
/*!
Deletes the object.
@@ -1410,16 +1423,42 @@ static const QSystemLocale *systemLocale()
return QSystemLocale_globalSystemLocale();
}
+static const QLocalePrivate *maybeSystemPrivate();
+bool QLocalePrivate::isUninitializedSystemLocale() const
+{
+ return this == maybeSystemPrivate() && m_language_id == 0;
+}
+
+QVariant QLocalePrivate::querySystemLocale(int type, const QVariant &in) const
+{
+ QVariant res = systemLocale()->query(QSystemLocale::QueryType(type), in);
+ if (res.isNull() && isUninitializedSystemLocale()) {
+ // if we were not able to get data from the system, initialize the
+ // system locale private data (which is essentially equals to this)
+ // with a fallback locale.
+ QLocalePrivate *system_private = globalLocalePrivate();
+ *system_private = *systemLocale()->fallbackLocale().d();
+ // internal cache is not initialized with values from the system, mark
+ // it as not fully initialized system locale.
+ system_private->m_language_id = 0;
+ }
+ return res;
+}
+
+// retrieves data from the system locale and caches them locally.
void QLocalePrivate::updateSystemPrivate()
{
const QSystemLocale *sys_locale = systemLocale();
if (!system_lp)
- system_lp = globalLocalePrivate();
+ return;
+
+ // copy over the information from the fallback locale and modify
*system_lp = *sys_locale->fallbackLocale().d();
QVariant res = sys_locale->query(QSystemLocale::LanguageId, QVariant());
if (!res.isNull())
system_lp->m_language_id = res.toInt();
+
res = sys_locale->query(QSystemLocale::CountryId, QVariant());
if (!res.isNull())
system_lp->m_country_id = res.toInt();
@@ -1446,19 +1485,29 @@ void QLocalePrivate::updateSystemPrivate()
}
#endif
+// returns the private data for the system locale. Cached data will not be
+// initialized until the updateSystemPrivate is called.
static const QLocalePrivate *systemPrivate()
{
#ifndef QT_NO_SYSTEMLOCALE
- // copy over the information from the fallback locale and modify
- if (!system_lp || system_lp->m_language_id == 0)
- QLocalePrivate::updateSystemPrivate();
-
+ if (!system_lp) {
+ system_lp = globalLocalePrivate();
+ // mark the locale as uninitialized system locale
+ system_lp->m_language_id = 0;
+ }
return system_lp;
#else
return locale_data;
#endif
}
+#ifndef QT_NO_SYSTEMLOCALE
+static const QLocalePrivate *maybeSystemPrivate()
+{
+ return system_lp;
+}
+#endif
+
static const QLocalePrivate *defaultPrivate()
{
if (!default_lp)
@@ -2283,7 +2332,12 @@ void QLocale::setDefault(const QLocale &locale)
*/
QLocale::Language QLocale::language() const
{
- return Language(d()->languageId());
+ const QLocalePrivate *dd = d();
+#ifndef QT_NO_SYSTEMLOCALE
+ if (dd->isUninitializedSystemLocale())
+ QLocalePrivate::updateSystemPrivate();
+#endif
+ return Language(dd->languageId());
}
/*!
@@ -2293,7 +2347,12 @@ QLocale::Language QLocale::language() const
*/
QLocale::Country QLocale::country() const
{
- return Country(d()->countryId());
+ const QLocalePrivate *dd = d();
+#ifndef QT_NO_SYSTEMLOCALE
+ if (dd->isUninitializedSystemLocale())
+ QLocalePrivate::updateSystemPrivate();
+#endif
+ return Country(dd->countryId());
}
/*!
@@ -2631,8 +2690,8 @@ QString QLocale::toString(const QDate &date, FormatType format) const
return QString();
#ifndef QT_NO_SYSTEMLOCALE
- if (d() == systemPrivate()) {
- QVariant res = systemLocale()->query(format == LongFormat
+ if (d() == maybeSystemPrivate()) {
+ QVariant res = d()->querySystemLocale(format == LongFormat
? QSystemLocale::DateToStringLong : QSystemLocale::DateToStringShort,
date);
if (!res.isNull())
@@ -2726,8 +2785,8 @@ QString QLocale::toString(const QDateTime &dateTime, FormatType format) const
return QString();
#ifndef QT_NO_SYSTEMLOCALE
- if (d() == systemPrivate()) {
- QVariant res = systemLocale()->query(format == LongFormat
+ if (d() == maybeSystemPrivate()) {
+ QVariant res = d()->querySystemLocale(format == LongFormat
? QSystemLocale::DateTimeToStringLong
: QSystemLocale::DateTimeToStringShort,
dateTime);
@@ -2752,8 +2811,8 @@ QString QLocale::toString(const QTime &time, FormatType format) const
return QString();
#ifndef QT_NO_SYSTEMLOCALE
- if (d() == systemPrivate()) {
- QVariant res = systemLocale()->query(format == LongFormat
+ if (d() == maybeSystemPrivate()) {
+ QVariant res = d()->querySystemLocale(format == LongFormat
? QSystemLocale::TimeToStringLong : QSystemLocale::TimeToStringShort,
time);
if (!res.isNull())
@@ -2779,8 +2838,8 @@ QString QLocale::toString(const QTime &time, FormatType format) const
QString QLocale::dateFormat(FormatType format) const
{
#ifndef QT_NO_SYSTEMLOCALE
- if (d() == systemPrivate()) {
- QVariant res = systemLocale()->query(format == LongFormat
+ if (d() == maybeSystemPrivate()) {
+ QVariant res = d()->querySystemLocale(format == LongFormat
? QSystemLocale::DateFormatLong : QSystemLocale::DateFormatShort,
QVariant());
if (!res.isNull())
@@ -2816,8 +2875,8 @@ QString QLocale::dateFormat(FormatType format) const
QString QLocale::timeFormat(FormatType format) const
{
#ifndef QT_NO_SYSTEMLOCALE
- if (d() == systemPrivate()) {
- QVariant res = systemLocale()->query(format == LongFormat
+ if (d() == maybeSystemPrivate()) {
+ QVariant res = d()->querySystemLocale(format == LongFormat
? QSystemLocale::TimeFormatLong : QSystemLocale::TimeFormatShort,
QVariant());
if (!res.isNull())
@@ -2853,8 +2912,8 @@ QString QLocale::timeFormat(FormatType format) const
QString QLocale::dateTimeFormat(FormatType format) const
{
#ifndef QT_NO_SYSTEMLOCALE
- if (d() == systemPrivate()) {
- QVariant res = systemLocale()->query(format == LongFormat
+ if (d() == maybeSystemPrivate()) {
+ QVariant res = d()->querySystemLocale(format == LongFormat
? QSystemLocale::DateTimeFormatLong
: QSystemLocale::DateTimeFormatShort,
QVariant());
@@ -3021,7 +3080,12 @@ QDateTime QLocale::toDateTime(const QString &string, const QString &format) cons
*/
QChar QLocale::decimalPoint() const
{
- return d()->decimal();
+ const QLocalePrivate *dd = d();
+#ifndef QT_NO_SYSTEMLOCALE
+ if (dd->isUninitializedSystemLocale())
+ QLocalePrivate::updateSystemPrivate();
+#endif
+ return dd->decimal();
}
/*!
@@ -3031,7 +3095,12 @@ QChar QLocale::decimalPoint() const
*/
QChar QLocale::groupSeparator() const
{
- return d()->group();
+ const QLocalePrivate *dd = d();
+#ifndef QT_NO_SYSTEMLOCALE
+ if (dd->isUninitializedSystemLocale())
+ QLocalePrivate::updateSystemPrivate();
+#endif
+ return dd->group();
}
/*!
@@ -3041,7 +3110,12 @@ QChar QLocale::groupSeparator() const
*/
QChar QLocale::percent() const
{
- return d()->percent();
+ const QLocalePrivate *dd = d();
+#ifndef QT_NO_SYSTEMLOCALE
+ if (dd->isUninitializedSystemLocale())
+ QLocalePrivate::updateSystemPrivate();
+#endif
+ return dd->percent();
}
/*!
@@ -3051,7 +3125,12 @@ QChar QLocale::percent() const
*/
QChar QLocale::zeroDigit() const
{
- return d()->zero();
+ const QLocalePrivate *dd = d();
+#ifndef QT_NO_SYSTEMLOCALE
+ if (dd->isUninitializedSystemLocale())
+ QLocalePrivate::updateSystemPrivate();
+#endif
+ return dd->zero();
}
/*!
@@ -3061,7 +3140,12 @@ QChar QLocale::zeroDigit() const
*/
QChar QLocale::negativeSign() const
{
- return d()->minus();
+ const QLocalePrivate *dd = d();
+#ifndef QT_NO_SYSTEMLOCALE
+ if (dd->isUninitializedSystemLocale())
+ QLocalePrivate::updateSystemPrivate();
+#endif
+ return dd->minus();
}
/*!
@@ -3071,7 +3155,12 @@ QChar QLocale::negativeSign() const
*/
QChar QLocale::positiveSign() const
{
- return d()->plus();
+ const QLocalePrivate *dd = d();
+#ifndef QT_NO_SYSTEMLOCALE
+ if (dd->isUninitializedSystemLocale())
+ QLocalePrivate::updateSystemPrivate();
+#endif
+ return dd->plus();
}
/*!
@@ -3081,7 +3170,12 @@ QChar QLocale::positiveSign() const
*/
QChar QLocale::exponential() const
{
- return d()->exponential();
+ const QLocalePrivate *dd = d();
+#ifndef QT_NO_SYSTEMLOCALE
+ if (dd->isUninitializedSystemLocale())
+ QLocalePrivate::updateSystemPrivate();
+#endif
+ return dd->exponential();
}
static bool qIsUpper(char c)
@@ -3200,8 +3294,8 @@ QString QLocale::monthName(int month, FormatType type) const
return QString();
#ifndef QT_NO_SYSTEMLOCALE
- if (d() == systemPrivate()) {
- QVariant res = systemLocale()->query(type == LongFormat
+ if (d() == maybeSystemPrivate()) {
+ QVariant res = d()->querySystemLocale(type == LongFormat
? QSystemLocale::MonthNameLong : QSystemLocale::MonthNameShort,
month);
if (!res.isNull())
@@ -3246,8 +3340,8 @@ QString QLocale::standaloneMonthName(int month, FormatType type) const
return QString();
#ifndef QT_NO_SYSTEMLOCALE
- if (d() == systemPrivate()) {
- QVariant res = systemLocale()->query(type == LongFormat
+ if (d() == maybeSystemPrivate()) {
+ QVariant res = d()->querySystemLocale(type == LongFormat
? QSystemLocale::MonthNameLong : QSystemLocale::MonthNameShort,
month);
if (!res.isNull())
@@ -3293,8 +3387,8 @@ QString QLocale::dayName(int day, FormatType type) const
return QString();
#ifndef QT_NO_SYSTEMLOCALE
- if (d() == systemPrivate()) {
- QVariant res = systemLocale()->query(type == LongFormat
+ if (d() == maybeSystemPrivate()) {
+ QVariant res = d()->querySystemLocale(type == LongFormat
? QSystemLocale::DayNameLong : QSystemLocale::DayNameShort,
day);
if (!res.isNull())
@@ -3342,8 +3436,8 @@ QString QLocale::standaloneDayName(int day, FormatType type) const
return QString();
#ifndef QT_NO_SYSTEMLOCALE
- if (d() == systemPrivate()) {
- QVariant res = systemLocale()->query(type == LongFormat
+ if (d() == maybeSystemPrivate()) {
+ QVariant res = d()->querySystemLocale(type == LongFormat
? QSystemLocale::DayNameLong : QSystemLocale::DayNameShort,
day);
if (!res.isNull())
@@ -3387,8 +3481,8 @@ QLocale::MeasurementSystem QLocale::measurementSystem() const
bool found = false;
#ifndef QT_NO_SYSTEMLOCALE
- if (d() == systemPrivate()) {
- QVariant res = systemLocale()->query(QSystemLocale::MeasurementSystem, QVariant());
+ if (d() == maybeSystemPrivate()) {
+ QVariant res = d()->querySystemLocale(QSystemLocale::MeasurementSystem, QVariant());
if (!res.isNull()) {
meas = MeasurementSystem(res.toInt());
found = true;
@@ -3415,8 +3509,8 @@ QLocale::MeasurementSystem QLocale::measurementSystem() const
QString QLocale::amText() const
{
#ifndef QT_NO_SYSTEMLOCALE
- if (d() == systemPrivate()) {
- QVariant res = systemLocale()->query(QSystemLocale::AMText, QVariant());
+ if (d() == maybeSystemPrivate()) {
+ QVariant res = d()->querySystemLocale(QSystemLocale::AMText, QVariant());
if (!res.isNull())
return res.toString();
}
@@ -3435,8 +3529,8 @@ QString QLocale::amText() const
QString QLocale::pmText() const
{
#ifndef QT_NO_SYSTEMLOCALE
- if (d() == systemPrivate()) {
- QVariant res = systemLocale()->query(QSystemLocale::PMText, QVariant());
+ if (d() == maybeSystemPrivate()) {
+ QVariant res = d()->querySystemLocale(QSystemLocale::PMText, QVariant());
if (!res.isNull())
return res.toString();
}
@@ -3851,6 +3945,10 @@ QString QLocalePrivate::doubleToString(double d,
int width,
unsigned flags) const
{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (isUninitializedSystemLocale())
+ QLocalePrivate::updateSystemPrivate();
+#endif
if (precision == -1)
precision = 6;
if (width == -1)
@@ -4001,6 +4099,10 @@ QString QLocalePrivate::longLongToString(qlonglong l, int precision,
int base, int width,
unsigned flags) const
{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (isUninitializedSystemLocale())
+ QLocalePrivate::updateSystemPrivate();
+#endif
bool precision_not_specified = false;
if (precision == -1) {
precision_not_specified = true;
@@ -4086,6 +4188,10 @@ QString QLocalePrivate::unsLongLongToString(qulonglong l, int precision,
int base, int width,
unsigned flags) const
{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (isUninitializedSystemLocale())
+ QLocalePrivate::updateSystemPrivate();
+#endif
bool precision_not_specified = false;
if (precision == -1) {
precision_not_specified = true;
@@ -4288,6 +4394,10 @@ bool QLocalePrivate::numberToCLocale(const QString &num,
bool QLocalePrivate::validateChars(const QString &str, NumberMode numMode, QByteArray *buff,
int decDigits) const
{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (isUninitializedSystemLocale())
+ QLocalePrivate::updateSystemPrivate();
+#endif
buff->clear();
buff->reserve(str.length());
@@ -4381,6 +4491,10 @@ bool QLocalePrivate::validateChars(const QString &str, NumberMode numMode, QByte
double QLocalePrivate::stringToDouble(const QString &number, bool *ok,
GroupSeparatorMode group_sep_mode) const
{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (isUninitializedSystemLocale())
+ QLocalePrivate::updateSystemPrivate();
+#endif
CharBuff buff;
if (!numberToCLocale(group().unicode() == 0xa0 ? number.trimmed() : number,
group_sep_mode, &buff)) {
@@ -4394,6 +4508,10 @@ double QLocalePrivate::stringToDouble(const QString &number, bool *ok,
qlonglong QLocalePrivate::stringToLongLong(const QString &number, int base,
bool *ok, GroupSeparatorMode group_sep_mode) const
{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (isUninitializedSystemLocale())
+ QLocalePrivate::updateSystemPrivate();
+#endif
CharBuff buff;
if (!numberToCLocale(group().unicode() == 0xa0 ? number.trimmed() : number,
group_sep_mode, &buff)) {
@@ -4408,6 +4526,10 @@ qlonglong QLocalePrivate::stringToLongLong(const QString &number, int base,
qulonglong QLocalePrivate::stringToUnsLongLong(const QString &number, int base,
bool *ok, GroupSeparatorMode group_sep_mode) const
{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (isUninitializedSystemLocale())
+ QLocalePrivate::updateSystemPrivate();
+#endif
CharBuff buff;
if (!numberToCLocale(group().unicode() == 0xa0 ? number.trimmed() : number,
group_sep_mode, &buff)) {
diff --git a/src/corelib/tools/qlocale.h b/src/corelib/tools/qlocale.h
index e854c84..9b7b214 100644
--- a/src/corelib/tools/qlocale.h
+++ b/src/corelib/tools/qlocale.h
@@ -638,6 +638,7 @@ public:
;
private:
friend struct QLocalePrivate;
+
// ### We now use this field to pack an index into locale_data and NumberOptions.
// ### Qt 5: change to a QLocaleData *d; uint numberOptions.
union {
diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h
index ecf79e9..003ae8c 100644
--- a/src/corelib/tools/qlocale_p.h
+++ b/src/corelib/tools/qlocale_p.h
@@ -63,14 +63,14 @@ QT_BEGIN_NAMESPACE
struct Q_CORE_EXPORT QLocalePrivate
{
public:
- QChar decimal() const { return QChar(m_decimal); }
- QChar group() const { return QChar(m_group); }
- QChar list() const { return QChar(m_list); }
- QChar percent() const { return QChar(m_percent); }
- QChar zero() const { return QChar(m_zero); }
- QChar plus() const { return QChar(m_plus); }
- QChar minus() const { return QChar(m_minus); }
- QChar exponential() const { return QChar(m_exponential); }
+ QChar decimal() const { Q_ASSERT(m_decimal); return QChar(m_decimal); }
+ QChar group() const { Q_ASSERT(m_group); return QChar(m_group); }
+ QChar list() const { Q_ASSERT(m_list); return QChar(m_list); }
+ QChar percent() const { Q_ASSERT(m_percent); return QChar(m_percent); }
+ QChar zero() const { Q_ASSERT(m_zero); return QChar(m_zero); }
+ QChar plus() const { Q_ASSERT(m_plus); return QChar(m_plus); }
+ QChar minus() const { Q_ASSERT(m_minus); return QChar(m_minus); }
+ QChar exponential() const { Q_ASSERT(m_exponential); return QChar(m_exponential); }
quint32 languageId() const { return m_language_id; }
quint32 countryId() const { return m_country_id; }
@@ -132,6 +132,8 @@ public:
CharBuff *result) const;
inline char digitToCLocale(const QChar &c) const;
+ inline bool isUninitializedSystemLocale() const;
+ QVariant querySystemLocale(int type, const QVariant &in) const;
static void updateSystemPrivate();
enum NumberMode { IntegerMode, DoubleStandardMode, DoubleScientificMode };