From c0f041fcdf9573c0777fd19a0ce012fedf83fec4 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Wed, 8 Jan 2020 14:17:09 +0100 Subject: Refactor QLocale's data access to be less verbose Add QLocaleData::DataRange and methods returning it, to package each of the m_*_idx, m_*_size pairs of data members, to simplify access to these data. This extends the experiment started in QCalendarLocale, which is now adapted to use the new DataRange also. Two static functions of qlocale.cpp are replaced by methods of DataRange, saving considerable duplication of long member names in callers. Change-Id: Iad9899ba72f00522594b55a0402baec47491999c Reviewed-by: Thiago Macieira Reviewed-by: Lars Knoll --- src/corelib/text/qlocale.cpp | 221 +++++++++++----------------------- src/corelib/text/qlocale_p.h | 71 ++++++++++- src/corelib/time/qcalendarbackend_p.h | 16 ++- 3 files changed, 146 insertions(+), 162 deletions(-) (limited to 'src') diff --git a/src/corelib/text/qlocale.cpp b/src/corelib/text/qlocale.cpp index 146ece23a6..995b1e55a6 100644 --- a/src/corelib/text/qlocale.cpp +++ b/src/corelib/text/qlocale.cpp @@ -791,28 +791,6 @@ const QLocaleData *QLocaleData::c() return c_data; } -static inline QString getLocaleData(const ushort *data, int size) -{ - return size > 0 ? QString::fromRawData(reinterpret_cast(data), size) : QString(); -} - -static QString getLocaleListData(const ushort *data, int size, int index) -{ - static const ushort separator = ';'; - while (index && size > 0) { - while (*data != separator) - ++data, --size; - --index; - ++data; - --size; - } - const ushort *end = data; - while (size > 0 && *end != separator) - ++end, --size; - return getLocaleData(data, end - data); -} - - #ifndef QT_NO_DATASTREAM QDataStream &operator<<(QDataStream &ds, const QLocale &l) { @@ -1130,31 +1108,24 @@ QString QLocale::createSeparatedList(const QStringList &list) const #endif const int size = list.size(); - if (size == 1) { + if (size < 1) + return QString(); + + if (size == 1) return list.at(0); - } else if (size == 2) { - QString format = getLocaleData( - list_pattern_part_data + d->m_data->m_list_pattern_part_two_idx, - d->m_data->m_list_pattern_part_two_size); - return format.arg(list.at(0), list.at(1)); - } else if (size > 2) { - QString formatStart = getLocaleData( - list_pattern_part_data + d->m_data->m_list_pattern_part_start_idx, - d->m_data->m_list_pattern_part_start_size); - QString formatMid = getLocaleData( - list_pattern_part_data + d->m_data->m_list_pattern_part_mid_idx, - d->m_data->m_list_pattern_part_mid_size); - QString formatEnd = getLocaleData( - list_pattern_part_data + d->m_data->m_list_pattern_part_end_idx, - d->m_data->m_list_pattern_part_end_size); - QString result = formatStart.arg(list.at(0), list.at(1)); - for (int i = 2; i < size - 1; ++i) - result = formatMid.arg(result, list.at(i)); - result = formatEnd.arg(result, list.at(size - 1)); - return result; - } - return QString(); + if (size == 2) + return d->m_data->pairListPattern().getData( + list_pattern_part_data).arg(list.at(0), list.at(1)); + + QStringView formatStart = d->m_data->startListPattern().viewData(list_pattern_part_data); + QStringView formatMid = d->m_data->midListPattern().viewData(list_pattern_part_data); + QStringView formatEnd = d->m_data->endListPattern().viewData(list_pattern_part_data); + QString result = formatStart.arg(list.at(0), list.at(1)); + for (int i = 2; i < size - 1; ++i) + result = formatMid.arg(result, list.at(i)); + result = formatEnd.arg(result, list.at(size - 1)); + return result; } /*! @@ -2251,18 +2222,10 @@ QString QLocale::dateFormat(FormatType format) const } #endif - quint32 idx, size; - switch (format) { - case LongFormat: - idx = d->m_data->m_long_date_format_idx; - size = d->m_data->m_long_date_format_size; - break; - default: - idx = d->m_data->m_short_date_format_idx; - size = d->m_data->m_short_date_format_size; - break; - } - return getLocaleData(date_format_data + idx, size); + return (format == LongFormat + ? d->m_data->longDateFormat() + : d->m_data->shortDateFormat() + ).getData(date_format_data); } /*! @@ -2289,18 +2252,10 @@ QString QLocale::timeFormat(FormatType format) const } #endif - quint32 idx, size; - switch (format) { - case LongFormat: - idx = d->m_data->m_long_time_format_idx; - size = d->m_data->m_long_time_format_size; - break; - default: - idx = d->m_data->m_short_time_format_idx; - size = d->m_data->m_short_time_format_size; - break; - } - return getLocaleData(time_format_data + idx, size); + return (format == LongFormat + ? d->m_data->longTimeFormat() + : d->m_data->shortTimeFormat() + ).getData(time_format_data); } /*! @@ -2869,24 +2824,21 @@ static QString rawMonthName(const QCalendarLocale &localeData, const ushort *monthsData, int month, QLocale::FormatType type) { - quint32 idx, size; + QLocaleData::DataRange range; switch (type) { case QLocale::LongFormat: - idx = localeData.m_long.index; - size = localeData.m_long.size; + range = localeData.m_long; break; case QLocale::ShortFormat: - idx = localeData.m_short.index; - size = localeData.m_short.size; + range = localeData.m_short; break; case QLocale::NarrowFormat: - idx = localeData.m_narrow.index; - size = localeData.m_narrow.size; + range = localeData.m_narrow; break; default: return QString(); } - return getLocaleListData(monthsData + idx, size, month - 1); + return range.getListEntry(monthsData, month - 1); } /*! @@ -2897,24 +2849,21 @@ static QString rawStandaloneMonthName(const QCalendarLocale &localeData, const ushort *monthsData, int month, QLocale::FormatType type) { - quint32 idx, size; + QLocaleData::DataRange range; switch (type) { case QLocale::LongFormat: - idx = localeData.m_standalone_long.index; - size = localeData.m_standalone_long.size; + range = localeData.m_standalone_long; break; case QLocale::ShortFormat: - idx = localeData.m_standalone_short.index; - size = localeData.m_standalone_short.size; + range = localeData.m_standalone_short; break; case QLocale::NarrowFormat: - idx = localeData.m_standalone_narrow.index; - size = localeData.m_standalone_narrow.size; + range = localeData.m_standalone_narrow; break; default: return QString(); } - QString name = getLocaleListData(monthsData + idx, size, month - 1); + QString name = range.getListEntry(monthsData, month - 1); return name.isEmpty() ? rawMonthName(localeData, monthsData, month, type) : name; } @@ -2925,24 +2874,21 @@ static QString rawStandaloneMonthName(const QCalendarLocale &localeData, static QString rawWeekDayName(const QLocaleData *data, const int day, QLocale::FormatType type) { - quint32 idx, size; + QLocaleData::DataRange range; switch (type) { case QLocale::LongFormat: - idx = data->m_long_day_names_idx; - size = data->m_long_day_names_size; + range = data->longDayNames(); break; case QLocale::ShortFormat: - idx = data->m_short_day_names_idx; - size = data->m_short_day_names_size; + range = data->shortDayNames(); break; case QLocale::NarrowFormat: - idx = data->m_narrow_day_names_idx; - size = data->m_narrow_day_names_size; + range = data->narrowDayNames(); break; default: return QString(); } - return getLocaleListData(days_data + idx, size, day == 7 ? 0 : day); + return range.getListEntry(days_data, day == 7 ? 0 : day); } /*! @@ -2952,24 +2898,21 @@ static QString rawWeekDayName(const QLocaleData *data, const int day, static QString rawStandaloneWeekDayName(const QLocaleData *data, const int day, QLocale::FormatType type) { - quint32 idx, size; + QLocaleData::DataRange range; switch (type) { case QLocale::LongFormat: - idx = data->m_standalone_long_day_names_idx; - size = data->m_standalone_long_day_names_size; + range =data->longDayNamesStandalone(); break; case QLocale::ShortFormat: - idx = data->m_standalone_short_day_names_idx; - size = data->m_standalone_short_day_names_size; + range = data->shortDayNamesStandalone(); break; case QLocale::NarrowFormat: - idx = data->m_standalone_narrow_day_names_idx; - size = data->m_standalone_narrow_day_names_size; + range = data->narrowDayNamesStandalone(); break; default: return QString(); } - QString name = getLocaleListData(days_data + idx, size, day == 7 ? 0 : day); + QString name = range.getListEntry(days_data, day == 7 ? 0 : day); if (name.isEmpty()) return rawWeekDayName(data, day, type); return name; @@ -3253,7 +3196,7 @@ QString QLocale::amText() const return res.toString(); } #endif - return getLocaleData(am_data + d->m_data->m_am_idx, d->m_data->m_am_size); + return d->m_data->anteMeridiem().getData(am_data); } /*! @@ -3273,7 +3216,7 @@ QString QLocale::pmText() const return res.toString(); } #endif - return getLocaleData(pm_data + d->m_data->m_pm_idx, d->m_data->m_pm_size); + return d->m_data->postMeridiem().getData(pm_data); } // Another intrusion from QCalendar, using some of the tools above: @@ -4215,23 +4158,16 @@ QString QLocale::currencySymbol(QLocale::CurrencySymbolFormat format) const return res.toString(); } #endif - quint32 idx, size; switch (format) { case CurrencySymbol: - idx = d->m_data->m_currency_symbol_idx; - size = d->m_data->m_currency_symbol_size; - return getLocaleData(currency_symbol_data + idx, size); + return d->m_data->currencySymbol().getData(currency_symbol_data); case CurrencyDisplayName: - idx = d->m_data->m_currency_display_name_idx; - size = d->m_data->m_currency_display_name_size; - return getLocaleListData(currency_display_name_data + idx, size, 0); + return d->m_data->currencyDisplayName().getListEntry(currency_display_name_data, 0); case CurrencyIsoCode: { - int len = 0; - const QLocaleData *data = this->d->m_data; - for (; len < 3; ++len) - if (!data->m_currency_iso_code[len]) - break; - return len ? QString::fromLatin1(data->m_currency_iso_code, len) : QString(); + const char *code = d->m_data->m_currency_iso_code; + if (int len = qstrnlen(code, 3)) + return QString::fromLatin1(code, len); + break; } } return QString(); @@ -4257,19 +4193,16 @@ QString QLocale::toCurrencyString(qlonglong value, const QString &symbol) const } #endif const QLocalePrivate *d = this->d; - quint8 idx = d->m_data->m_currency_format_idx; - quint8 size = d->m_data->m_currency_format_size; - if (d->m_data->m_currency_negative_format_size && value < 0) { - idx = d->m_data->m_currency_negative_format_idx; - size = d->m_data->m_currency_negative_format_size; + QLocaleData::DataRange range = d->m_data->currencyFormatNegative(); + if (!range.size || value >= 0) + range = d->m_data->currencyFormat(); + else value = -value; - } QString str = toString(value); QString sym = symbol.isNull() ? currencySymbol() : symbol; if (sym.isEmpty()) sym = currencySymbol(QLocale::CurrencyIsoCode); - QString format = getLocaleData(currency_format_data + idx, size); - return format.arg(str, sym); + return range.getData(currency_format_data).arg(str, sym); } /*! @@ -4287,15 +4220,11 @@ QString QLocale::toCurrencyString(qulonglong value, const QString &symbol) const return res.toString(); } #endif - const QLocaleData *data = this->d->m_data; - quint8 idx = data->m_currency_format_idx; - quint8 size = data->m_currency_format_size; QString str = toString(value); QString sym = symbol.isNull() ? currencySymbol() : symbol; if (sym.isEmpty()) sym = currencySymbol(QLocale::CurrencyIsoCode); - QString format = getLocaleData(currency_format_data + idx, size); - return format.arg(str, sym); + return d->m_data->currencyFormat().getData(currency_format_data).arg(str, sym); } #if QT_VERSION < QT_VERSION_CHECK(6,0,0) @@ -4330,20 +4259,16 @@ QString QLocale::toCurrencyString(double value, const QString &symbol, int preci return res.toString(); } #endif - const QLocaleData *data = this->d->m_data; - quint8 idx = data->m_currency_format_idx; - quint8 size = data->m_currency_format_size; - if (data->m_currency_negative_format_size && value < 0) { - idx = data->m_currency_negative_format_idx; - size = data->m_currency_negative_format_size; + QLocaleData::DataRange range = d->m_data->currencyFormatNegative(); + if (!range.size || value >= 0) + range = d->m_data->currencyFormat(); + else value = -value; - } QString str = toString(value, 'f', precision == -1 ? d->m_data->m_currency_digits : precision); QString sym = symbol.isNull() ? currencySymbol() : symbol; if (sym.isEmpty()) sym = currencySymbol(QLocale::CurrencyIsoCode); - QString format = getLocaleData(currency_format_data + idx, size); - return format.arg(str, sym); + return range.getData(currency_format_data).arg(str, sym); } /*! @@ -4418,17 +4343,11 @@ QString QLocale::formattedDataSize(qint64 bytes, int precision, DataSizeFormats Q_ASSERT(power <= 6 && power >= 0); QString unit; if (power > 0) { - quint16 index, size; - if (format & DataSizeSIQuantifiers) { - index = d->m_data->m_byte_si_quantified_idx; - size = d->m_data->m_byte_si_quantified_size; - } else { - index = d->m_data->m_byte_iec_quantified_idx; - size = d->m_data->m_byte_iec_quantified_size; - } - unit = getLocaleListData(byte_unit_data + index, size, power - 1); + QLocaleData::DataRange range = (format & DataSizeSIQuantifiers) + ? d->m_data->byteAmountSI() : d->m_data->byteAmountIEC(); + unit = range.getListEntry(byte_unit_data, power - 1); } else { - unit = getLocaleData(byte_unit_data + d->m_data->m_byte_idx, d->m_data->m_byte_size); + unit = d->m_data->byteCount().getData(byte_unit_data); } return number + QLatin1Char(' ') + unit; @@ -4554,8 +4473,7 @@ QString QLocale::nativeLanguageName() const return res.toString(); } #endif - return getLocaleData(endonyms_data + d->m_data->m_language_endonym_idx, - d->m_data->m_language_endonym_size); + return d->m_data->endonymLanguage().getData(endonyms_data); } /*! @@ -4575,8 +4493,7 @@ QString QLocale::nativeCountryName() const return res.toString(); } #endif - return getLocaleData(endonyms_data + d->m_data->m_country_endonym_idx, - d->m_data->m_country_endonym_size); + return d->m_data->endonymCountry().getData(endonyms_data); } #ifndef QT_NO_DEBUG_STREAM diff --git a/src/corelib/text/qlocale_p.h b/src/corelib/text/qlocale_p.h index 938d7bbb6a..271234266b 100644 --- a/src/corelib/text/qlocale_p.h +++ b/src/corelib/text/qlocale_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2019 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Copyright (C) 2016 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** @@ -288,6 +288,75 @@ public: Q_CORE_EXPORT bool validateChars(QStringView str, NumberMode numMode, QByteArray *buff, int decDigits = -1, QLocale::NumberOptions number_options = QLocale::DefaultNumberOptions) const; + struct DataRange + { + quint16 offset; + quint16 size; + QString getData(const ushort *table) const + { + return size > 0 + ? QString::fromRawData(reinterpret_cast(table + offset), size) + : QString(); + } + QStringView viewData(const ushort *table) const + { + return { reinterpret_cast(table + offset), size }; + } + QString getListEntry(const ushort *table, int index) const + { + return listEntry(table, index).getData(table); + } + QStringView viewListEntry(const ushort *table, int index) const + { + return listEntry(table, index).viewData(table); + } + private: + DataRange listEntry(const ushort *table, int index) const + { + const ushort separator = ';'; + quint16 i = 0; + while (index > 0 && i < size) { + if (table[offset + i] == separator) + index--; + i++; + } + quint16 end = i; + while (end < size && table[offset + end] != separator) + end++; + return { quint16(offset + i), quint16(end - i) }; + } + }; +#define rangeGetter(name, stem) \ + DataRange name() const { return { m_ ## stem ## _idx, m_ ## stem ## _size }; } + + rangeGetter(startListPattern, list_pattern_part_start) + rangeGetter(midListPattern, list_pattern_part_mid) + rangeGetter(endListPattern, list_pattern_part_end) + rangeGetter(pairListPattern, list_pattern_part_two) + rangeGetter(shortDateFormat, short_date_format) + rangeGetter(longDateFormat, long_date_format) + rangeGetter(shortTimeFormat, short_time_format) + rangeGetter(longTimeFormat, long_time_format) + rangeGetter(narrowDayNamesStandalone, standalone_narrow_day_names) + rangeGetter(shortDayNamesStandalone, standalone_short_day_names) + rangeGetter(longDayNamesStandalone, standalone_long_day_names) + rangeGetter(narrowDayNames, narrow_day_names) + rangeGetter(shortDayNames, short_day_names) + rangeGetter(longDayNames, long_day_names) + rangeGetter(anteMeridiem, am) + rangeGetter(postMeridiem, pm) + rangeGetter(byteCount, byte) + rangeGetter(byteAmountSI, byte_si_quantified) + rangeGetter(byteAmountIEC, byte_iec_quantified) + rangeGetter(currencySymbol, currency_symbol) + rangeGetter(currencyDisplayName, currency_display_name) + rangeGetter(currencyFormat, currency_format) + rangeGetter(currencyFormatNegative, currency_negative_format) + rangeGetter(endonymLanguage, language_endonym) + rangeGetter(endonymCountry, country_endonym) + +#undef rangeGetter + public: quint16 m_language_id, m_script_id, m_country_id; diff --git a/src/corelib/time/qcalendarbackend_p.h b/src/corelib/time/qcalendarbackend_p.h index 21506e9e2c..843e42c584 100644 --- a/src/corelib/time/qcalendarbackend_p.h +++ b/src/corelib/time/qcalendarbackend_p.h @@ -56,23 +56,21 @@ #include #include #include +#include QT_BEGIN_NAMESPACE // Locale-related parts, mostly handled in ../text/qlocale.cpp -struct QLocaleDataEntry { - quint16 index, size; -}; struct QCalendarLocale { quint16 m_language_id, m_script_id, m_country_id; // Month name indexes: - QLocaleDataEntry m_standalone_short; - QLocaleDataEntry m_standalone_long; - QLocaleDataEntry m_standalone_narrow; - QLocaleDataEntry m_short; - QLocaleDataEntry m_long; - QLocaleDataEntry m_narrow; + QLocaleData::DataRange m_standalone_short; + QLocaleData::DataRange m_standalone_long; + QLocaleData::DataRange m_standalone_narrow; + QLocaleData::DataRange m_short; + QLocaleData::DataRange m_long; + QLocaleData::DataRange m_narrow; }; // Partial implementation, of methods with common forms, in qcalendar.cpp -- cgit v1.2.3