?? qlocale.cpp
字號:
/******************************************************************************** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.**** This file is part of the QtCore module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qplatformdefs.h"#include "qdatastream.h"#include "qstring.h"#include "qlocale.h"#include "qlocale_p.h"#include "qnamespace.h"#include "qdatetime.h"#include "qstringlist.h"#include "qvariant.h"#if defined(Q_WS_WIN)# include "qt_windows.h"# include <time.h>#endif#if !defined(QWS) && defined(Q_OS_MAC)# include "private/qcore_mac_p.h"#endif#include "private/qnumeric_p.h"#include <ctype.h>#include <float.h>#include <limits.h>#include <math.h>#include <stdlib.h>#include <qdebug.h>#if defined(Q_OS_LINUX) && !defined(__UCLIBC__)# include <fenv.h>#endif#if !defined(QT_QLOCALE_NEEDS_VOLATILE)# if defined(Q_CC_GNU)# if __GNUC__ == 4 && __GNUC_MINOR__ == 0# define QT_QLOCALE_NEEDS_VOLATILE# elif defined(Q_OS_WIN)# define QT_QLOCALE_NEEDS_VOLATILE# endif# endif#endif#if defined(QT_QLOCALE_NEEDS_VOLATILE)# define NEEDS_VOLATILE volatile#else# define NEEDS_VOLATILE#endif// Sizes as defined by the ISO C99 standard - fallback#ifndef LLONG_MAX# define LLONG_MAX Q_INT64_C(0x7fffffffffffffff)#endif#ifndef LLONG_MIN# define LLONG_MIN (-LLONG_MAX - Q_INT64_C(1))#endif#ifndef ULLONG_MAX# define ULLONG_MAX Q_UINT64_C(0xffffffffffffffff)#endif#define CONVERSION_BUFF_SIZE 255#ifndef QT_QLOCALE_USES_FCVTstatic char *qdtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **digits_str);static char *_qdtoa( NEEDS_VOLATILE double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **digits_str);static double qstrtod(const char *s00, char const **se, bool *ok);#endifstatic qlonglong qstrtoll(const char *nptr, const char **endptr, register int base, bool *ok);static qulonglong qstrtoull(const char *nptr, const char **endptr, register int base, bool *ok);/******************************************************************************** Helpers for accessing Qt locale database*/#include "qlocale_data_p.h"static QLocale::Language codeToLanguage(const QChar *code){ ushort uc1 = code[0].unicode(); ushort uc2 = code[1].unicode(); const unsigned char *c = language_code_list; for (; *c != 0; c += 2) { if (uc1 == c[0] && uc2 == c[1]) return QLocale::Language((c - language_code_list)/2); } return QLocale::C;}static QLocale::Country codeToCountry(const QChar *code){ ushort uc1 = code[0].unicode(); ushort uc2 = code[1].unicode(); const unsigned char *c = country_code_list; for (; *c != 0; c += 2) { if (uc1 == c[0] && uc2 == c[1]) return QLocale::Country((c - country_code_list)/2); } return QLocale::AnyCountry;}static QString languageToCode(QLocale::Language language){ if (language == QLocale::C) return QLatin1String("C"); QString code; code.resize(2); const unsigned char *c = language_code_list + 2*(uint(language)); code[0] = ushort(c[0]); code[1] = ushort(c[1]); return code;}static QString countryToCode(QLocale::Country country){ if (country == QLocale::AnyCountry) return QString(); QString code; code.resize(2); const unsigned char *c = country_code_list + 2*(uint(country)); code[0] = ushort(c[0]); code[1] = ushort(c[1]); return code;}static const QLocalePrivate *findLocale(QLocale::Language language, QLocale::Country country){ unsigned language_id = language; unsigned country_id = country; uint idx = locale_index[language_id]; const QLocalePrivate *d = locale_data + idx; if (idx == 0) // default language has no associated country return d; if (country == QLocale::AnyCountry) return d; Q_ASSERT(d->languageId() == language_id); while (d->languageId() == language_id && d->countryId() != country_id) ++d; if (d->countryId() == country_id && d->languageId() == language_id) return d; return locale_data + idx;}static void getLangAndCountry(const QString &name, QLocale::Language &lang, QLocale::Country &cntry){ lang = QLocale::C; cntry = QLocale::AnyCountry; uint l = name.length(); do { if (l < 2) break; const QChar *uc = name.unicode(); if (l > 2 && uc[2] != QLatin1Char('_') && uc[2] != QLatin1Char('.') && uc[2] != QLatin1Char('@')) break; QChar lang_code[2]; lang_code[0] = uc[0]; lang_code[1] = uc[1]; // CLDR has changed the code for Bokmal from "no" to "nb". We want to support // both, but we have no alias mechanism in the database. if (lang_code[0] == QLatin1Char('n') && lang_code[1] == QLatin1Char('b')) lang_code[1] = QLatin1Char('o'); lang = codeToLanguage(lang_code); if (lang == QLocale::C) break; if (l == 2 || uc[2] == QLatin1Char('.') || uc[2] == QLatin1Char('@')) break; // we have uc[2] == '_' if (l < 5) break; if (l > 5 && uc[5] != QLatin1Char('.') && uc[5] != QLatin1Char('@')) break; cntry = codeToCountry(uc + 3); } while (false);}static const QLocalePrivate *findLocale(const QString &name){ QLocale::Language lang; QLocale::Country cntry; getLangAndCountry(name, lang, cntry); return findLocale(lang, cntry);}static QString readEscapedFormatString(const QString &format, int *idx){ int &i = *idx; Q_ASSERT(format.at(i).unicode() == '\''); ++i; if (i == format.size()) return QString(); if (format.at(i).unicode() == '\'') { // "''" outside of a quoted stirng ++i; return QLatin1String("'"); } QString result; while (i < format.size()) { if (format.at(i).unicode() == '\'') { if (i + 1 < format.size() && format.at(i + 1).unicode() == '\'') { // "''" inside of a quoted string result.append(QLatin1Char('\'')); i += 2; } else { break; } } else { result.append(format.at(i++)); } } if (i < format.size()) ++i; return result;}static int repeatCount(const QString &s, int i){ QChar c = s.at(i); int j = i + 1; while (j < s.size() && s.at(j) == c) ++j; return j - i;}static const QLocalePrivate *default_lp = 0;#ifndef QT_NO_SYSTEMLOCALEstatic QByteArray envVarLocale(){ static QByteArray lang = 0;#ifdef Q_OS_UNIX lang = qgetenv("LC_ALL"); if (lang.isNull()) lang = qgetenv("LC_NUMERIC"); if (lang.isNull())#endif lang = qgetenv("LANG"); return lang;}#if defined(Q_OS_WIN)/******************************************************************************** Wrappers for Windows locale system functions*/static const char *winLangCodeToIsoName(int code);static QString winIso639LangName(LCID id = LOCALE_USER_DEFAULT);static QString winIso3116CtryName(LCID id = LOCALE_USER_DEFAULT);static QString getWinLocaleInfo(LCTYPE type){ int cnt = 0; LCID id = GetThreadLocale(); QT_WA({ cnt = GetLocaleInfoW(id, type, 0, 0)*2; } , { cnt = GetLocaleInfoA(id, type, 0, 0); }); if (cnt == 0) { qWarning("QLocale: empty windows locale info (%d)", (int)type); return QString(); } QByteArray buff(cnt, 0); QT_WA({ cnt = GetLocaleInfoW(id, type, reinterpret_cast<wchar_t*>(buff.data()), buff.size()/2); } , { cnt = GetLocaleInfoA(id, type, buff.data(), buff.size()); }); if (cnt == 0) { qWarning("QLocale: empty windows locale info (%d)", (int)type); return QString(); } QString result; QT_WA({ result = QString::fromUtf16(reinterpret_cast<ushort*>(buff.data())); } , { result = QString::fromLocal8Bit(buff.data()); }); return result;}QByteArray getWinLocaleName(LCID id = LOCALE_USER_DEFAULT){ QByteArray result; if (id == LOCALE_USER_DEFAULT) { result = envVarLocale(); if ( !result.isEmpty() ) { long id = 0; bool ok = false; id = qstrtoll(result.data(), 0, 0, &ok); if ( !ok || id == 0 || id < INT_MIN || id > INT_MAX ) return result; else return winLangCodeToIsoName( (int)id ); } } if (QSysInfo::WindowsVersion == QSysInfo::WV_95) { result = winLangCodeToIsoName(id != LOCALE_USER_DEFAULT ? id : GetThreadLocale()); } else { if (id == LOCALE_USER_DEFAULT) id = GetThreadLocale(); QString resultuage = winIso639LangName(id); QString country = winIso3116CtryName(id); result += resultuage.toLatin1(); if (!country.isEmpty()) { result += '_'; result += country.toLatin1(); } } return result;}Q_CORE_EXPORT QLocale qt_localeFromLCID(LCID id){ return QLocale(getWinLocaleName(id));}static QString winToQtFormat(const QString &sys_fmt){ QString result; int i = 0; while (i < sys_fmt.size()) { if (sys_fmt.at(i).unicode() == '\'') { QString text = readEscapedFormatString(sys_fmt, &i); if (text == QLatin1String("'")) result += QLatin1String("''"); else result += QChar('\'') + text + QChar('\''); continue; } QChar c = sys_fmt.at(i); int repeat = repeatCount(sys_fmt, i); switch (c.unicode()) { // Date case 'y': if (repeat > 5) repeat = 5; else if (repeat == 3) repeat = 2; switch (repeat) { case 1: result += QLatin1String("yy"); // "y" unsupported by Qt, use "yy" break; case 5: result += QLatin1String("yyyy"); // "yyyyy" same as "yyyy" on Windows break; default: result += QString(repeat, QLatin1Char('y')); break; } break; case 'g': if (repeat > 2) repeat = 2; switch (repeat) { case 2: break; // no equivalent of "gg" in Qt default: result += QLatin1Char('g'); break; } break; case 't': if (repeat > 2) repeat = 2; result += QLatin1String("AP"); // "t" unsupported, use "AP" break; default: result += QString(repeat, c); break; } i += repeat; } return result;}static QString winDateToString(const QDate &date, DWORD flags){ SYSTEMTIME st; memset(&st, 0, sizeof(SYSTEMTIME)); st.wYear = date.year(); st.wMonth = date.month(); st.wDay = date.day(); LCID id = GetThreadLocale(); QT_WA({ TCHAR buf[255]; if (GetDateFormatW(id, flags, &st, 0, buf, 255)) return QString::fromUtf16((ushort*)buf); } , { char buf[255]; if (GetDateFormatA(id, flags, &st, 0, (char*)&buf, 255)) return QString::fromLocal8Bit(buf); }); return QString();}static QString winTimeToString(const QTime &time)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -