diff options
-rw-r--r-- | src/corelib/text/qlocale.cpp | 221 | ||||
-rw-r--r-- | src/corelib/text/qlocale_p.h | 71 | ||||
-rw-r--r-- | src/corelib/time/qcalendarbackend_p.h | 16 |
3 files changed, 146 insertions, 162 deletions
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<const QChar *>(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<const QChar *>(table + offset), size) + : QString(); + } + QStringView viewData(const ushort *table) const + { + return { reinterpret_cast<const QChar *>(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 <QtCore/qstringlist.h> #include <QtCore/qstring.h> #include <QtCore/qmap.h> +#include <QtCore/private/qlocale_p.h> 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 |