diff options
Diffstat (limited to 'src/corelib/text/qlocale_p.h')
-rw-r--r-- | src/corelib/text/qlocale_p.h | 189 |
1 files changed, 121 insertions, 68 deletions
diff --git a/src/corelib/text/qlocale_p.h b/src/corelib/text/qlocale_p.h index 7e26e86fdf..42d434eac4 100644 --- a/src/corelib/text/qlocale_p.h +++ b/src/corelib/text/qlocale_p.h @@ -221,21 +221,19 @@ public: typedef QVarLengthArray<char, 256> CharBuff; - static QString doubleToString(const QChar zero, const QChar plus, - const QChar minus, const QChar exponent, - const QChar group, const QChar decimal, - double d, int precision, - DoubleForm form, + static QString doubleToString(const QString &zero, const QString &plus, + const QString &minus, const QString &exponent, + const QString &group, const QString &decimal, + double d, int precision, DoubleForm form, int width, unsigned flags); - static QString longLongToString(const QChar zero, const QChar group, - const QChar plus, const QChar minus, + static QString longLongToString(const QString &zero, const QString &group, + const QString &plus, const QString &minus, qint64 l, int precision, int base, int width, unsigned flags); - static QString unsLongLongToString(const QChar zero, const QChar group, - const QChar plus, + static QString unsLongLongToString(const QString &zero, const QString &group, + const QString &plus, quint64 l, int precision, - int base, int width, - unsigned flags); + int base, int width, unsigned flags); QString doubleToString(double d, int precision = -1, @@ -282,48 +280,105 @@ public: bool numberToCLocale(QStringView s, QLocale::NumberOptions number_options, CharBuff *result) const; - inline char digitToCLocale(QChar c) const; + inline char numericToCLocale(QStringView in) const; // this function is used in QIntValidator (QtGui) Q_CORE_EXPORT bool validateChars(QStringView str, NumberMode numMode, QByteArray *buff, int decDigits = -1, QLocale::NumberOptions number_options = QLocale::DefaultNumberOptions) const; + QString decimalPoint() const; + QString groupSeparator() const; + QString listSeparator() const; + QString percentSign() const; + QString zeroDigit() const; + uint zeroUcs() const; + QString positiveSign() const; + QString negativeSign() const; + QString exponentSeparator() const; + + struct DataRange + { + quint16 offset; + quint16 size; + QString getData(const char16_t *table) const + { + return size > 0 + ? QString::fromRawData(reinterpret_cast<const QChar *>(table + offset), size) + : QString(); + } + QStringView viewData(const char16_t *table) const + { + return { reinterpret_cast<const QChar *>(table + offset), size }; + } + QString getListEntry(const char16_t *table, int index) const + { + return listEntry(table, index).getData(table); + } + QStringView viewListEntry(const char16_t *table, int index) const + { + return listEntry(table, index).viewData(table); + } + uint ucsFirst(const char16_t *table) const + { + if (size && !QChar::isSurrogate(table[offset])) + return table[offset]; + if (size > 1 && QChar::isHighSurrogate(table[offset])) + return QChar::surrogateToUcs4(table[offset], table[offset + 1]); + return 0; + } + private: + DataRange listEntry(const char16_t *table, int index) const + { + const char16_t 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 ForEachQLocaleRange(X) \ + X(startListPattern) X(midListPattern) X(endListPattern) X(pairListPattern) X(listDelimit) \ + X(decimalSeparator) X(groupDelim) X(percent) X(zero) X(minus) X(plus) X(exponential) \ + X(quoteStart) X(quoteEnd) X(quoteStartAlternate) X(quoteEndAlternate) \ + X(longDateFormat) X(shortDateFormat) X(longTimeFormat) X(shortTimeFormat) \ + X(longDayNamesStandalone) X(longDayNames) \ + X(shortDayNamesStandalone) X(shortDayNames) \ + X(narrowDayNamesStandalone) X(narrowDayNames) \ + X(anteMeridiem) X(postMeridiem) \ + X(byteCount) X(byteAmountSI) X(byteAmountIEC) \ + X(currencySymbol) X(currencyDisplayName) \ + X(currencyFormat) X(currencyFormatNegative) \ + X(endonymLanguage) X(endonymCountry) + +#define rangeGetter(name) \ + DataRange name() const { return { m_ ## name ## _idx, m_ ## name ## _size }; } + ForEachQLocaleRange(rangeGetter) +#undef rangeGetter + public: quint16 m_language_id, m_script_id, m_country_id; - // FIXME QTBUG-69324: not all unicode code-points map to single-token UTF-16 :-( - char16_t m_decimal, m_group, m_list, m_percent, m_zero, m_minus, m_plus, m_exponential; - char16_t m_quotation_start, m_quotation_end; - char16_t m_alternate_quotation_start, m_alternate_quotation_end; - - quint16 m_list_pattern_part_start_idx, m_list_pattern_part_start_size; - quint16 m_list_pattern_part_mid_idx, m_list_pattern_part_mid_size; - quint16 m_list_pattern_part_end_idx, m_list_pattern_part_end_size; - quint16 m_list_pattern_part_two_idx, m_list_pattern_part_two_size; - quint16 m_short_date_format_idx, m_short_date_format_size; - quint16 m_long_date_format_idx, m_long_date_format_size; - quint16 m_short_time_format_idx, m_short_time_format_size; - quint16 m_long_time_format_idx, m_long_time_format_size; - quint16 m_standalone_short_day_names_idx, m_standalone_short_day_names_size; - quint16 m_standalone_long_day_names_idx, m_standalone_long_day_names_size; - quint16 m_standalone_narrow_day_names_idx, m_standalone_narrow_day_names_size; - quint16 m_short_day_names_idx, m_short_day_names_size; - quint16 m_long_day_names_idx, m_long_day_names_size; - quint16 m_narrow_day_names_idx, m_narrow_day_names_size; - quint16 m_am_idx, m_am_size; - quint16 m_pm_idx, m_pm_size; - quint16 m_byte_idx, m_byte_size; - quint16 m_byte_si_quantified_idx, m_byte_si_quantified_size; - quint16 m_byte_iec_quantified_idx, m_byte_iec_quantified_size; + // Offsets, then sizes, for each range: +#define rangeIndex(name) quint16 m_ ## name ## _idx; + ForEachQLocaleRange(rangeIndex) +#undef rangeIndex +#define Size(name) quint8 m_ ## name ## _size; + ForEachQLocaleRange(Size) +#undef Size + +#undef ForEachQLocaleRange + + // Strays: char m_currency_iso_code[3]; - quint16 m_currency_symbol_idx, m_currency_symbol_size; - quint16 m_currency_display_name_idx, m_currency_display_name_size; - quint8 m_currency_format_idx, m_currency_format_size; - quint8 m_currency_negative_format_idx, m_currency_negative_format_size; - quint16 m_language_endonym_idx, m_language_endonym_size; - quint16 m_country_endonym_idx, m_country_endonym_size; quint16 m_currency_digits : 2; - quint16 m_currency_rounding : 3; + quint16 m_currency_rounding : 3; // (not yet used !) quint16 m_first_day_of_week : 3; quint16 m_weekend_start : 3; quint16 m_weekend_end : 3; @@ -347,15 +402,6 @@ public: static QLocalePrivate *get(QLocale &l) { return l.d; } static const QLocalePrivate *get(const QLocale &l) { return l.d; } - QChar decimal() const { return QChar(m_data->m_decimal); } - QChar group() const { return QChar(m_data->m_group); } - QChar list() const { return QChar(m_data->m_list); } - QChar percent() const { return QChar(m_data->m_percent); } - QChar zero() const { return QChar(m_data->m_zero); } - QChar plus() const { return QChar(m_data->m_plus); } - QChar minus() const { return QChar(m_data->m_minus); } - QChar exponential() const { return QChar(m_data->m_exponential); } - quint16 languageId() const { return m_data->m_language_id; } quint16 countryId() const { return m_data->m_country_id; } @@ -395,37 +441,44 @@ inline QLocalePrivate *QSharedDataPointer<QLocalePrivate>::clone() return QLocalePrivate::create(d->m_data, d->m_data_offset, d->m_numberOptions); } -inline char QLocaleData::digitToCLocale(QChar in) const +inline char QLocaleData::numericToCLocale(QStringView in) const { - const ushort tenUnicode = m_zero + 10; - - if (in.unicode() >= m_zero && in.unicode() < tenUnicode) - return '0' + in.unicode() - m_zero; + Q_ASSERT(in.size() == 1 || (in.size() == 2 && in.at(0).isHighSurrogate())); - if (in.unicode() >= '0' && in.unicode() <= '9') - return in.toLatin1(); - - if (in == m_plus || in == QLatin1Char('+')) + if (in == positiveSign() || in == u"+") return '+'; - if (in == m_minus || in == QLatin1Char('-') || in == QChar(0x2212)) + if (in == negativeSign() || in == u"-" || in == u"\x2212") return '-'; - if (in == m_decimal) + if (in == decimalPoint()) return '.'; - if (in == m_group) - return ','; - - if (in == m_exponential || in == QChar(QChar::toUpper(m_exponential))) + if (in.compare(exponentSeparator(), Qt::CaseInsensitive) == 0) return 'e'; + const QString group = groupSeparator(); + if (in == group) + return ','; + // In several languages group() is a non-breaking space (U+00A0) or its thin // version (U+202f), which look like spaces. People (and thus some of our // tests) use a regular space instead and complain if it doesn't work. - if ((m_group == 0xA0 || m_group == 0x202f) && in.unicode() == ' ') + // Should this be extended generally to any case where group is a space ? + if ((group == u"\xa0" || group == u"\x202f") && in == u" ") return ','; + const uint zeroUcs4 = zeroUcs(); + const uint tenUcs4 = zeroUcs4 + 10; + const uint inUcs4 = in.size() == 2 + ? QChar::surrogateToUcs4(in.at(0), in.at(1)) : in.at(0).unicode(); + + if (zeroUcs4 <= inUcs4 && inUcs4 < tenUcs4) + return '0' + inUcs4 - zeroUcs4; + + if ('0' <= inUcs4 && inUcs4 <= '9') + return inUcs4; + return 0; } |