diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /intl/locale/windows | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'intl/locale/windows')
-rw-r--r-- | intl/locale/windows/moz.build | 26 | ||||
-rw-r--r-- | intl/locale/windows/nsCollationWin.cpp | 146 | ||||
-rw-r--r-- | intl/locale/windows/nsCollationWin.h | 35 | ||||
-rw-r--r-- | intl/locale/windows/nsDateTimeFormatWin.cpp | 253 | ||||
-rw-r--r-- | intl/locale/windows/nsDateTimeFormatWin.h | 71 | ||||
-rw-r--r-- | intl/locale/windows/nsWin32Locale.cpp | 748 | ||||
-rw-r--r-- | intl/locale/windows/nsWinCharset.cpp | 101 | ||||
-rw-r--r-- | intl/locale/windows/wincharset.properties | 23 |
8 files changed, 1403 insertions, 0 deletions
diff --git a/intl/locale/windows/moz.build b/intl/locale/windows/moz.build new file mode 100644 index 000000000..5bde38b89 --- /dev/null +++ b/intl/locale/windows/moz.build @@ -0,0 +1,26 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +SOURCES += [ + 'nsCollationWin.cpp', + 'nsDateTimeFormatWin.cpp', + 'nsWin32Locale.cpp', + 'nsWinCharset.cpp', +] + +FINAL_LIBRARY = 'xul' + +GENERATED_FILES = [ + 'wincharset.properties.h', +] +wincharset = GENERATED_FILES['wincharset.properties.h'] +wincharset.script = '../props2arrays.py' +wincharset.inputs = ['wincharset.properties'] + +LOCAL_INCLUDES += [ + '..', +] + diff --git a/intl/locale/windows/nsCollationWin.cpp b/intl/locale/windows/nsCollationWin.cpp new file mode 100644 index 000000000..8dcdb8f07 --- /dev/null +++ b/intl/locale/windows/nsCollationWin.cpp @@ -0,0 +1,146 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +#include "nsCollationWin.h" +#include "nsIServiceManager.h" +#include "nsIComponentManager.h" +#include "nsILocaleService.h" +#include "nsIPlatformCharset.h" +#include "nsWin32Locale.h" +#include "nsCOMPtr.h" +#include "prmem.h" +#include "plstr.h" +#include <windows.h> + +#undef CompareString + +NS_IMPL_ISUPPORTS(nsCollationWin, nsICollation) + + +nsCollationWin::nsCollationWin() : mCollation(nullptr) +{ +} + +nsCollationWin::~nsCollationWin() +{ + if (mCollation) + delete mCollation; +} + +nsresult nsCollationWin::Initialize(nsILocale* locale) +{ + NS_ASSERTION(!mCollation, "Should only be initialized once."); + + nsresult res; + + mCollation = new nsCollation; + + // default LCID (en-US) + mLCID = 1033; + + nsAutoString localeStr; + + // get locale string, use app default if no locale specified + if (!locale) { + nsCOMPtr<nsILocaleService> localeService = + do_GetService(NS_LOCALESERVICE_CONTRACTID); + if (localeService) { + nsCOMPtr<nsILocale> appLocale; + res = localeService->GetApplicationLocale(getter_AddRefs(appLocale)); + if (NS_SUCCEEDED(res)) { + res = appLocale->GetCategory(NS_LITERAL_STRING("NSILOCALE_COLLATE"), + localeStr); + } + } + } + else { + res = locale->GetCategory(NS_LITERAL_STRING("NSILOCALE_COLLATE"), + localeStr); + } + + // Get LCID and charset name from locale, if available + LCID lcid; + res = nsWin32Locale::GetPlatformLocale(localeStr, &lcid); + if (NS_SUCCEEDED(res)) { + mLCID = lcid; + } + + nsCOMPtr <nsIPlatformCharset> platformCharset = + do_GetService(NS_PLATFORMCHARSET_CONTRACTID); + if (platformCharset) { + nsAutoCString mappedCharset; + res = platformCharset->GetDefaultCharsetForLocale(localeStr, mappedCharset); + if (NS_SUCCEEDED(res)) { + mCollation->SetCharset(mappedCharset.get()); + } + } + + return NS_OK; +} + + +NS_IMETHODIMP nsCollationWin::CompareString(int32_t strength, + const nsAString & string1, + const nsAString & string2, + int32_t *result) +{ + int retval; + nsresult res; + DWORD dwMapFlags = 0; + + if (strength == kCollationCaseInSensitive) + dwMapFlags |= NORM_IGNORECASE; + + retval = ::CompareStringW(mLCID, + dwMapFlags, + (LPCWSTR) PromiseFlatString(string1).get(), + -1, + (LPCWSTR) PromiseFlatString(string2).get(), + -1); + if (retval) { + res = NS_OK; + *result = retval - 2; + } else { + res = NS_ERROR_FAILURE; + } + + return res; +} + + +nsresult nsCollationWin::AllocateRawSortKey(int32_t strength, + const nsAString& stringIn, uint8_t** key, uint32_t* outLen) +{ + int byteLen; + void *buffer; + nsresult res = NS_OK; + DWORD dwMapFlags = LCMAP_SORTKEY; + + if (strength == kCollationCaseInSensitive) + dwMapFlags |= NORM_IGNORECASE; + + byteLen = LCMapStringW(mLCID, dwMapFlags, + (LPCWSTR) PromiseFlatString(stringIn).get(), + -1, nullptr, 0); + buffer = PR_Malloc(byteLen); + if (!buffer) { + res = NS_ERROR_OUT_OF_MEMORY; + } else { + *key = (uint8_t *)buffer; + *outLen = LCMapStringW(mLCID, dwMapFlags, + (LPCWSTR) PromiseFlatString(stringIn).get(), + -1, (LPWSTR) buffer, byteLen); + } + return res; +} + +nsresult nsCollationWin::CompareRawSortKey(const uint8_t* key1, uint32_t len1, + const uint8_t* key2, uint32_t len2, + int32_t* result) +{ + *result = PL_strcmp((const char *)key1, (const char *)key2); + return NS_OK; +} diff --git a/intl/locale/windows/nsCollationWin.h b/intl/locale/windows/nsCollationWin.h new file mode 100644 index 000000000..901211344 --- /dev/null +++ b/intl/locale/windows/nsCollationWin.h @@ -0,0 +1,35 @@ + +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef nsCollationWin_h__ +#define nsCollationWin_h__ + + +#include "nsICollation.h" +#include "nsCollation.h" // static library +#include "plstr.h" + + + +class nsCollationWin final : public nsICollation { + ~nsCollationWin(); + +protected: + nsCollation *mCollation; // XP collation class + uint32_t mLCID; // Windows platform locale ID + +public: + nsCollationWin(); + + // nsISupports interface + NS_DECL_ISUPPORTS + + // nsICollation interface + NS_DECL_NSICOLLATION + +}; + +#endif /* nsCollationWin_h__ */ diff --git a/intl/locale/windows/nsDateTimeFormatWin.cpp b/intl/locale/windows/nsDateTimeFormatWin.cpp new file mode 100644 index 000000000..f65868e1b --- /dev/null +++ b/intl/locale/windows/nsDateTimeFormatWin.cpp @@ -0,0 +1,253 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsDateTimeFormatWin.h" +#include "nsIServiceManager.h" +#include "nsIComponentManager.h" +#include "nsILocaleService.h" +#include "nsWin32Locale.h" +#include "nsUnicharUtils.h" +#include "nsCRT.h" +#include "nsCOMPtr.h" + + +#define NSDATETIMEFORMAT_BUFFER_LEN 80 + +NS_IMPL_ISUPPORTS(nsDateTimeFormatWin, nsIDateTimeFormat) + + +// init this interface to a specified locale +nsresult nsDateTimeFormatWin::Initialize(nsILocale* locale) +{ + nsAutoString localeStr; + nsresult res = NS_OK; + + // use cached info if match with stored locale + if (!locale) { + if (!mLocale.IsEmpty() && + mLocale.Equals(mAppLocale, nsCaseInsensitiveStringComparator())) { + return NS_OK; + } + } + else { + res = locale->GetCategory(NS_LITERAL_STRING("NSILOCALE_TIME"), localeStr); + if (NS_SUCCEEDED(res) && !localeStr.IsEmpty()) { + if (!mLocale.IsEmpty() && + mLocale.Equals(localeStr, nsCaseInsensitiveStringComparator())) { + return NS_OK; + } + } + } + + // default LCID (en-US) + mLCID = 1033; + + // get locale string, use app default if no locale specified + if (!locale) { + nsCOMPtr<nsILocaleService> localeService = + do_GetService(NS_LOCALESERVICE_CONTRACTID); + if (localeService) { + nsCOMPtr<nsILocale> appLocale; + res = localeService->GetApplicationLocale(getter_AddRefs(appLocale)); + if (NS_SUCCEEDED(res)) { + res = appLocale->GetCategory(NS_LITERAL_STRING("NSILOCALE_TIME"), + localeStr); + if (NS_SUCCEEDED(res) && !localeStr.IsEmpty()) { + mAppLocale.Assign(localeStr); // cache app locale name + } + } + } + } + else { + res = locale->GetCategory(NS_LITERAL_STRING("NSILOCALE_TIME"), localeStr); + } + + // Get LCID and charset name from locale, if available + if (NS_SUCCEEDED(res) && !localeStr.IsEmpty()) { + mLocale.Assign(localeStr); // cache locale name + res = nsWin32Locale::GetPlatformLocale(mLocale, (LCID *) &mLCID); + } + + return res; +} + +// performs a locale sensitive date formatting operation on the time_t parameter +nsresult nsDateTimeFormatWin::FormatTime(nsILocale* locale, + const nsDateFormatSelector dateFormatSelector, + const nsTimeFormatSelector timeFormatSelector, + const time_t timetTime, + nsAString& stringOut) +{ + return FormatTMTime(locale, dateFormatSelector, timeFormatSelector, localtime( &timetTime ), stringOut); +} + +// performs a locale sensitive date formatting operation on the struct tm parameter +nsresult nsDateTimeFormatWin::FormatTMTime(nsILocale* locale, + const nsDateFormatSelector dateFormatSelector, + const nsTimeFormatSelector timeFormatSelector, + const struct tm* tmTime, + nsAString& stringOut) +{ + SYSTEMTIME system_time; + DWORD dwFlags_Date = 0, dwFlags_Time = 0; + int dateLen, timeLen; + char16_t dateBuffer[NSDATETIMEFORMAT_BUFFER_LEN], timeBuffer[NSDATETIMEFORMAT_BUFFER_LEN]; + + // set up locale data + (void) Initialize(locale); + + // Map tm to SYSTEMTIME + system_time.wYear = 1900 + tmTime->tm_year; + system_time.wMonth = tmTime->tm_mon + 1; + system_time.wDayOfWeek = tmTime->tm_wday; + system_time.wDay = tmTime->tm_mday; + system_time.wHour = tmTime->tm_hour; + system_time.wMinute = tmTime->tm_min; + system_time.wSecond = tmTime->tm_sec; + system_time.wMilliseconds = 0; + + // Map to WinAPI date format + switch (dateFormatSelector) { + case kDateFormatLong: + dwFlags_Date = DATE_LONGDATE; + break; + case kDateFormatShort: + dwFlags_Date = DATE_SHORTDATE; + break; + case kDateFormatWeekday: + dwFlags_Date = 0; + break; + case kDateFormatYearMonth: + dwFlags_Date = 0; // TODO:only availabe NT5 + break; + } + + // Map to WinAPI time format + switch (timeFormatSelector) { + case kTimeFormatSeconds: + dwFlags_Time = 0; + break; + case kTimeFormatNoSeconds: + dwFlags_Time = TIME_NOSECONDS; + break; + case kTimeFormatSecondsForce24Hour: + dwFlags_Time = TIME_FORCE24HOURFORMAT; + break; + case kTimeFormatNoSecondsForce24Hour: + dwFlags_Time = TIME_NOSECONDS + TIME_FORCE24HOURFORMAT; + break; + } + + // Call GetDateFormatW + if (dateFormatSelector == kDateFormatNone) { + dateLen = 0; + } + else { + if (dateFormatSelector == kDateFormatYearMonth) { + dateLen = nsGetDateFormatW(0, &system_time, "yyyy/MM", + dateBuffer, NSDATETIMEFORMAT_BUFFER_LEN); + } + else if (dateFormatSelector == kDateFormatWeekday) { + dateLen = nsGetDateFormatW(0, &system_time, "ddd", + dateBuffer, NSDATETIMEFORMAT_BUFFER_LEN); + } + else { + dateLen = nsGetDateFormatW(dwFlags_Date, &system_time, nullptr, + dateBuffer, NSDATETIMEFORMAT_BUFFER_LEN); + } + if (dateLen != 0) { + dateLen--; // Since the count includes the terminating null. + } + } + + // Call GetTimeFormatW + if (timeFormatSelector == kTimeFormatNone) { + timeLen = 0; + } + else { + timeLen = nsGetTimeFormatW(dwFlags_Time, &system_time, nullptr, + timeBuffer, NSDATETIMEFORMAT_BUFFER_LEN); + if (timeLen != 0) { + timeLen--; // Since the count includes the terminating null. + } + } + + NS_ASSERTION(NSDATETIMEFORMAT_BUFFER_LEN >= (uint32_t) (dateLen + 1), "internal date buffer is not large enough"); + NS_ASSERTION(NSDATETIMEFORMAT_BUFFER_LEN >= (uint32_t) (timeLen + 1), "internal time buffer is not large enough"); + + // Copy the result + stringOut.Truncate(); + if (dateLen != 0 && timeLen != 0) { + stringOut.Assign(dateBuffer, dateLen); + stringOut.Append((char16_t *)(L" "), 1); + stringOut.Append(timeBuffer, timeLen); + } + else if (dateLen != 0 && timeLen == 0) { + stringOut.Assign(dateBuffer, dateLen); + } + else if (dateLen == 0 && timeLen != 0) { + stringOut.Assign(timeBuffer, timeLen); + } + + return NS_OK; +} + +// performs a locale sensitive date formatting operation on the PRTime parameter +nsresult nsDateTimeFormatWin::FormatPRTime(nsILocale* locale, + const nsDateFormatSelector dateFormatSelector, + const nsTimeFormatSelector timeFormatSelector, + const PRTime prTime, + nsAString& stringOut) +{ + PRExplodedTime explodedTime; + PR_ExplodeTime(prTime, PR_LocalTimeParameters, &explodedTime); + + return FormatPRExplodedTime(locale, dateFormatSelector, timeFormatSelector, &explodedTime, stringOut); +} + +// performs a locale sensitive date formatting operation on the PRExplodedTime parameter +nsresult nsDateTimeFormatWin::FormatPRExplodedTime(nsILocale* locale, + const nsDateFormatSelector dateFormatSelector, + const nsTimeFormatSelector timeFormatSelector, + const PRExplodedTime* explodedTime, + nsAString& stringOut) +{ + struct tm tmTime; + memset( &tmTime, 0, sizeof(tmTime) ); + + tmTime.tm_yday = explodedTime->tm_yday; + tmTime.tm_wday = explodedTime->tm_wday; + tmTime.tm_year = explodedTime->tm_year; + tmTime.tm_year -= 1900; + tmTime.tm_mon = explodedTime->tm_month; + tmTime.tm_mday = explodedTime->tm_mday; + tmTime.tm_hour = explodedTime->tm_hour; + tmTime.tm_min = explodedTime->tm_min; + tmTime.tm_sec = explodedTime->tm_sec; + + return FormatTMTime(locale, dateFormatSelector, timeFormatSelector, &tmTime, stringOut); +} + +int nsDateTimeFormatWin::nsGetTimeFormatW(DWORD dwFlags, const SYSTEMTIME *lpTime, + const char* format, char16_t *timeStr, int cchTime) +{ + int len = 0; + len = GetTimeFormatW(mLCID, dwFlags, lpTime, + format ? + NS_ConvertASCIItoUTF16(format).get() : + nullptr, + (LPWSTR) timeStr, cchTime); + return len; +} + +int nsDateTimeFormatWin::nsGetDateFormatW(DWORD dwFlags, const SYSTEMTIME *lpDate, + const char* format, char16_t *dateStr, int cchDate) +{ + int len = 0; + len = GetDateFormatW(mLCID, dwFlags, lpDate, + format ? NS_ConvertASCIItoUTF16(format).get() : nullptr, + (LPWSTR) dateStr, cchDate); + return len; +} diff --git a/intl/locale/windows/nsDateTimeFormatWin.h b/intl/locale/windows/nsDateTimeFormatWin.h new file mode 100644 index 000000000..1c84492ee --- /dev/null +++ b/intl/locale/windows/nsDateTimeFormatWin.h @@ -0,0 +1,71 @@ + +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef nsDateTimeFormatWin_h__ +#define nsDateTimeFormatWin_h__ + + +#include "nsIDateTimeFormat.h" +#include <windows.h> + + +// Locale sensitive date and time format interface +// +class nsDateTimeFormatWin : public nsIDateTimeFormat { + virtual ~nsDateTimeFormatWin() {} + +public: + NS_DECL_THREADSAFE_ISUPPORTS + + // performs a locale sensitive date formatting operation on the time_t parameter + NS_IMETHOD FormatTime(nsILocale* locale, + const nsDateFormatSelector dateFormatSelector, + const nsTimeFormatSelector timeFormatSelector, + const time_t timetTime, + nsAString& stringOut); + + // performs a locale sensitive date formatting operation on the struct tm parameter + NS_IMETHOD FormatTMTime(nsILocale* locale, + const nsDateFormatSelector dateFormatSelector, + const nsTimeFormatSelector timeFormatSelector, + const struct tm* tmTime, + nsAString& stringOut); + + // performs a locale sensitive date formatting operation on the PRTime parameter + NS_IMETHOD FormatPRTime(nsILocale* locale, + const nsDateFormatSelector dateFormatSelector, + const nsTimeFormatSelector timeFormatSelector, + const PRTime prTime, + nsAString& stringOut); + + // performs a locale sensitive date formatting operation on the PRExplodedTime parameter + NS_IMETHOD FormatPRExplodedTime(nsILocale* locale, + const nsDateFormatSelector dateFormatSelector, + const nsTimeFormatSelector timeFormatSelector, + const PRExplodedTime* explodedTime, + nsAString& stringOut); + + nsDateTimeFormatWin() {mLocale.SetLength(0);mAppLocale.SetLength(0);} + + +private: + // init this interface to a specified locale + NS_IMETHOD Initialize(nsILocale* locale); + + // call GetTimeFormatW or TimeFormatA + int nsGetTimeFormatW(DWORD dwFlags, const SYSTEMTIME *lpTime, + const char* format, char16_t *timeStr, int cchTime); + + // call GetDateFormatW or GetDateFormatA + int nsGetDateFormatW(DWORD dwFlags, const SYSTEMTIME *lpDate, + const char* format, char16_t *dateStr, int cchDate); + + nsString mLocale; + nsString mAppLocale; + uint32_t mLCID; // Windows platform locale ID +}; + +#endif /* nsDateTimeFormatWin_h__ */ diff --git a/intl/locale/windows/nsWin32Locale.cpp b/intl/locale/windows/nsWin32Locale.cpp new file mode 100644 index 000000000..8a66d2c64 --- /dev/null +++ b/intl/locale/windows/nsWin32Locale.cpp @@ -0,0 +1,748 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/ArrayUtils.h" + +#include "nscore.h" +#include "nsString.h" +#include "nsXPCOMStrings.h" +#include "nsReadableUtils.h" +#include "nsWin32Locale.h" +#include "prprf.h" +#include <windows.h> +#include "nsCRT.h" + +using namespace mozilla; + +struct iso_pair +{ + const char* iso_code; + DWORD win_code; +}; + +struct iso_map +{ + const char* iso_code; + DWORD win_code; + iso_pair sublang_list[20]; +}; + +nsWin32Locale::LocaleNameToLCIDPtr nsWin32Locale::localeNameToLCID = nullptr; +nsWin32Locale::LCIDToLocaleNamePtr nsWin32Locale::lcidToLocaleName = nullptr; + +// Older versions of VC++ and Win32 SDK and mingw don't have +// macros for languages and sublanguages recently added to Win32. +// see http://www.tug.org/ftp/tex/texinfo/intl/localename.c + +#ifndef LANG_URDU +#define LANG_URDU 0x20 +#endif +#ifndef LANG_ARMENIAN +#define LANG_ARMENIAN 0x2b +#endif +#ifndef LANG_AZERI +#define LANG_AZERI 0x2c +#endif +#ifndef LANG_MACEDONIAN +#define LANG_MACEDONIAN 0x2f +#endif +#ifndef LANG_GEORGIAN +#define LANG_GEORGIAN 0x37 +#endif +#ifndef LANG_HINDI +#define LANG_HINDI 0x39 +#endif +#ifndef LANG_MALAY +#define LANG_MALAY 0x3e +#endif +#ifndef LANG_KAZAK +#define LANG_KAZAK 0x3f +#endif +#ifndef LANG_KYRGYZ +#define LANG_KYRGYZ 0x40 +#endif +#ifndef LANG_SWAHILI +#define LANG_SWAHILI 0x41 +#endif +#ifndef LANG_UZBEK +#define LANG_UZBEK 0x43 +#endif +#ifndef LANG_TATAR +#define LANG_TATAR 0x44 +#endif +#ifndef LANG_PUNJABI +#define LANG_PUNJABI 0x46 +#endif +#ifndef LANG_GUJARAT +#define LANG_GUJARAT 0x47 +#endif +#ifndef LANG_TAMIL +#define LANG_TAMIL 0x49 +#endif +#ifndef LANG_TELUGU +#define LANG_TELUGU 0x4a +#endif +#ifndef LANG_KANNADA +#define LANG_KANNADA 0x4b +#endif +#ifndef LANG_MARATHI +#define LANG_MARATHI 0x4e +#endif +#ifndef LANG_SANSKRIT +#define LANG_SANSKRIT 0x4f +#endif +#ifndef LANG_MONGOLIAN +#define LANG_MONGOLIAN 0x50 +#endif +#ifndef LANG_GALICIAN +#define LANG_GALICIAN 0x56 +#endif +#ifndef LANG_KONKANI +#define LANG_KONKANI 0x57 +#endif +#ifndef LANG_DIVEHI +#define LANG_DIVEHI 0x65 +#endif + +#ifndef SUBLANG_MALAY_MALAYSIA +#define SUBLANG_MALAY_MALAYSIA 0x01 +#endif +#ifndef SUBLANG_MALAY_BRUNEI_DARUSSALAM +#define SUBLANG_MALAY_BRUNEI_DARUSSALAM 0x02 +#endif +#ifndef SUBLANG_CHINESE_MACAU +#define SUBLANG_CHINESE_MACAU 0x05 +#endif +#ifndef SUBLANG_FRENCH_MONACO +#define SUBLANG_FRENCH_MONACO 0x06 +#endif +#ifndef SUBLANG_ENGLISH_ZIMBABWE +#define SUBLANG_ENGLISH_ZIMBABWE 0x0c +#endif +#ifndef SUBLANG_ENGLISH_PHILIPPINES +#define SUBLANG_ENGLISH_PHILIPPINES 0x0d +#endif + + +// +// This list is used to map between ISO language +// References : +// http://www.iso.ch/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html +// http://www.loc.gov/standards/iso639-2/ +// http://www.ethnologue.com/ +// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/nls_19ir.asp +// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/nls_61df.asp + +static const +iso_map iso_list[] = +{ + {"af", LANG_AFRIKAANS, { + { "ZA", SUBLANG_DEFAULT }, + { "",0}} + }, + { "ar", LANG_ARABIC, { + { "SA", SUBLANG_ARABIC_SAUDI_ARABIA }, + { "IQ", SUBLANG_ARABIC_IRAQ }, + { "EG", SUBLANG_ARABIC_EGYPT }, + { "LY", SUBLANG_ARABIC_LIBYA }, + { "DZ", SUBLANG_ARABIC_ALGERIA }, + { "MA", SUBLANG_ARABIC_MOROCCO }, + { "TN", SUBLANG_ARABIC_TUNISIA }, + { "OM", SUBLANG_ARABIC_OMAN }, + { "YE", SUBLANG_ARABIC_YEMEN }, + { "SY", SUBLANG_ARABIC_SYRIA }, + { "JO", SUBLANG_ARABIC_JORDAN }, + { "LB", SUBLANG_ARABIC_LEBANON }, + { "KW", SUBLANG_ARABIC_KUWAIT }, + { "AE", SUBLANG_ARABIC_UAE }, + { "BH", SUBLANG_ARABIC_BAHRAIN }, + { "QA", SUBLANG_ARABIC_QATAR }, + {"",0}} + }, + {"az", LANG_AZERI, { + { "AZ",SUBLANG_DEFAULT }, // XXX Latin vs Cyrillic vs Arabic + { "",0}} + }, + {"be", LANG_BELARUSIAN, { + { "BY",SUBLANG_DEFAULT }, + { "",0}} + }, + {"bg", LANG_BULGARIAN, { + { "BG", SUBLANG_DEFAULT }, + { "",0}} + }, + {"ca", LANG_CATALAN, { + { "ES", SUBLANG_DEFAULT}, + { "",0}} + }, + {"cs", LANG_CZECH, { + { "CZ", SUBLANG_DEFAULT}, + {"",0}} + }, + { "da", LANG_DANISH, { + { "DK", SUBLANG_DEFAULT }, + { "",0}} + }, + { "de", LANG_GERMAN, { + { "DE", SUBLANG_GERMAN }, + { "CH", SUBLANG_GERMAN_SWISS }, + { "AT", SUBLANG_GERMAN_AUSTRIAN }, + { "LU", SUBLANG_GERMAN_LUXEMBOURG }, + { "LI", SUBLANG_GERMAN_LIECHTENSTEIN }, + { "" , 0}} + }, + {"dv", LANG_DIVEHI, { + { "MV", SUBLANG_DEFAULT}, + { "", 0}} + }, + {"el", LANG_GREEK, { + { "GR", SUBLANG_DEFAULT}, + { "", 0}} + }, + { "en", LANG_ENGLISH, { + { "US", SUBLANG_ENGLISH_US }, + { "GB", SUBLANG_ENGLISH_UK }, + { "AU", SUBLANG_ENGLISH_AUS }, + { "CA", SUBLANG_ENGLISH_CAN }, + { "NZ", SUBLANG_ENGLISH_NZ }, + { "IE", SUBLANG_ENGLISH_EIRE }, + { "ZA", SUBLANG_ENGLISH_SOUTH_AFRICA }, + { "JM", SUBLANG_ENGLISH_JAMAICA }, + { "BZ", SUBLANG_ENGLISH_BELIZE }, + { "TT", SUBLANG_ENGLISH_TRINIDAD }, + { "ZW", SUBLANG_ENGLISH_ZIMBABWE }, + { "PH", SUBLANG_ENGLISH_PHILIPPINES }, + { "",0}} + }, + { "es", LANG_SPANISH, { // XXX : SUBLANG_SPANISH_MODERN + { "ES", SUBLANG_SPANISH }, + { "MX", SUBLANG_SPANISH_MEXICAN }, + { "GT", SUBLANG_SPANISH_GUATEMALA }, + { "CR", SUBLANG_SPANISH_COSTA_RICA }, + { "PA", SUBLANG_SPANISH_PANAMA }, + { "DO", SUBLANG_SPANISH_DOMINICAN_REPUBLIC }, + { "VE", SUBLANG_SPANISH_VENEZUELA }, + { "CO", SUBLANG_SPANISH_COLOMBIA }, + { "PE", SUBLANG_SPANISH_PERU }, + { "AR", SUBLANG_SPANISH_ARGENTINA }, + { "EC", SUBLANG_SPANISH_ECUADOR }, + { "CL", SUBLANG_SPANISH_CHILE }, + { "UY", SUBLANG_SPANISH_URUGUAY }, + { "PY", SUBLANG_SPANISH_PARAGUAY }, + { "BO", SUBLANG_SPANISH_BOLIVIA }, + { "SV", SUBLANG_SPANISH_EL_SALVADOR }, + { "HN", SUBLANG_SPANISH_HONDURAS }, + { "NI", SUBLANG_SPANISH_NICARAGUA }, + { "PR", SUBLANG_SPANISH_PUERTO_RICO }, + { "", 0 }} + }, + {"et", LANG_ESTONIAN, { + { "EE", SUBLANG_DEFAULT }, + { "", 0}} + }, + {"eu", LANG_BASQUE, { + { "ES" , SUBLANG_DEFAULT }, + { "" , 0 }} + }, + {"fa", LANG_FARSI, { + { "IR", SUBLANG_DEFAULT}, + { "", 0}} + }, + {"fi", LANG_FINNISH, { + { "FI", SUBLANG_DEFAULT }, + { "",0}} + }, + {"fo", LANG_FAEROESE, { + { "FO", SUBLANG_DEFAULT }, + { "", 0}} + }, + { "fr", LANG_FRENCH, { + { "FR", SUBLANG_FRENCH }, + { "BE", SUBLANG_FRENCH_BELGIAN }, + { "CA", SUBLANG_FRENCH_CANADIAN }, + { "CH", SUBLANG_FRENCH_SWISS }, + { "LU", SUBLANG_FRENCH_LUXEMBOURG }, + { "MC", SUBLANG_FRENCH_MONACO }, + {"",0}} + }, + { "gl", LANG_GALICIAN, { + { "ES", SUBLANG_DEFAULT }, + { "", 0}} + }, + { "gu", LANG_GUJARATI, { + { "IN", SUBLANG_DEFAULT }, + { "", 0}} + }, + {"he", LANG_HEBREW, { + { "IL", SUBLANG_DEFAULT}, + { "", 0}} + }, + {"hi", LANG_HINDI, { + { "IN", SUBLANG_DEFAULT }, + { "", 0}} + }, + /* Duplicate the SUBLANG codes for Croatian and Serbian, because the Windows + LANG code is the same for both */ + {"hr", LANG_CROATIAN, { + { "CS", SUBLANG_SERBIAN_LATIN }, + { "SP", SUBLANG_SERBIAN_CYRILLIC }, + { "HR", SUBLANG_DEFAULT}, + { "" ,0 }} + }, + {"hu", LANG_HUNGARIAN, { + { "HU", SUBLANG_DEFAULT }, + { "" , 0 }} + }, + {"hy", LANG_ARMENIAN, { + { "AM", SUBLANG_DEFAULT}, + { "" ,0 }} + }, + {"id", LANG_INDONESIAN, { + { "ID", SUBLANG_DEFAULT }, + {"", 0}} + }, + {"is", LANG_ICELANDIC, { + { "IS", SUBLANG_DEFAULT }, + { "", 0}} + }, + { "it", LANG_ITALIAN, { + { "IT", SUBLANG_ITALIAN }, + { "CH", SUBLANG_ITALIAN_SWISS }, + { "", 0}} + }, + {"iw", LANG_HEBREW, { + { "IL", SUBLANG_DEFAULT}, + { "", 0}} + }, + {"ja", LANG_JAPANESE, { + { "JP", SUBLANG_DEFAULT }, + { "", 0}} + }, + { "ka", LANG_GEORGIAN, { + { "GE", SUBLANG_DEFAULT }, + { "", 0}} + }, + { "kk", LANG_KAZAK, { + { "KZ", SUBLANG_DEFAULT }, // KAZAKHSTAN + { "", 0}} + }, + { "kn", LANG_KANNADA, { + { "IN", SUBLANG_DEFAULT }, + { "", 0}} + }, + { "ko", LANG_KOREAN, { + { "KR", SUBLANG_KOREAN }, + { "", 0}} + }, + { "kok", LANG_KONKANI, { + { "IN", SUBLANG_DEFAULT }, + { "", 0}} + }, + { "ky", LANG_KYRGYZ, { + { "KG", SUBLANG_DEFAULT }, // Kygyzstan + { "", 0}} + }, + {"lt", LANG_LITHUANIAN, { + { "LT", SUBLANG_DEFAULT }, + { "" ,0 }} + }, + {"lv", LANG_LATVIAN, { + { "LV", SUBLANG_DEFAULT}, + { "", 0}} + }, + {"mk", LANG_MACEDONIAN, { + { "MK", SUBLANG_DEFAULT }, + { "", 0 }} + }, + { "mn", LANG_MONGOLIAN, { + { "MN", SUBLANG_DEFAULT }, + { "", 0}} + }, + { "mr", LANG_MARATHI, { + { "IN", SUBLANG_DEFAULT }, + { "", 0}} + }, + {"ms", LANG_MALAY, { + { "MY", SUBLANG_MALAY_MALAYSIA }, + { "BN", SUBLANG_MALAY_BRUNEI_DARUSSALAM }, // XXX + { "", 0}} + }, + {"nb", LANG_NORWEGIAN, { + { "NO", SUBLANG_NORWEGIAN_BOKMAL }, + { "", SUBLANG_NORWEGIAN_BOKMAL}} + }, + {"nl", LANG_DUTCH, { + {"NL", SUBLANG_DUTCH }, + {"BE", SUBLANG_DUTCH_BELGIAN }, + { "", 0}} + }, + {"nn", LANG_NORWEGIAN, { + { "NO", SUBLANG_NORWEGIAN_NYNORSK }, + { "", SUBLANG_NORWEGIAN_NYNORSK}} + }, + {"no", LANG_NORWEGIAN, { + { "NO", SUBLANG_DEFAULT }, + { "", 0}} + }, + { "pa", LANG_PUNJABI, { + { "IN", SUBLANG_DEFAULT }, + { "", 0}} + }, + {"pl", LANG_POLISH, { + { "PL", SUBLANG_DEFAULT }, + { "", 0}} + }, + { "pt", LANG_PORTUGUESE, { + { "PT", SUBLANG_PORTUGUESE }, + { "BR", SUBLANG_PORTUGUESE_BRAZILIAN }, + {"",0}} + }, + {"ro", LANG_ROMANIAN, { + { "RO", SUBLANG_DEFAULT }, + { "", 0}} + }, + {"ru", LANG_RUSSIAN, { + { "RU", SUBLANG_DEFAULT }, + { "", 0 }} + }, + { "sa", LANG_SANSKRIT, { + { "IN", SUBLANG_DEFAULT }, + { "", 0}} + }, + {"sk", LANG_SLOVAK, { + { "SK", SUBLANG_DEFAULT }, + { "", 0}} + }, + {"sl", LANG_SLOVENIAN, { + { "SI", SUBLANG_DEFAULT }, + { "", 0}} + }, + {"sq", LANG_ALBANIAN, { + { "AL", SUBLANG_DEFAULT }, + { "", 0}} + }, + /* Duplicate the SUBLANG codes for Croatian and Serbian, because the Windows + LANG code is the same for both */ + {"sr", LANG_SERBIAN, { + { "CS", SUBLANG_SERBIAN_LATIN }, + { "SP", SUBLANG_SERBIAN_CYRILLIC }, + { "HR", SUBLANG_DEFAULT }, + { "", 0}} + }, + { "sv", LANG_SWEDISH, { + { "SE", SUBLANG_SWEDISH }, + { "FI", SUBLANG_SWEDISH_FINLAND }, + { "", 0 }} + }, + {"sw", LANG_SWAHILI, { + { "KE", SUBLANG_DEFAULT }, + { "", 0}} + }, + { "ta", LANG_TAMIL, { + { "IN", SUBLANG_DEFAULT }, + { "", 0}} + }, + { "te", LANG_TELUGU, { + { "IN", SUBLANG_DEFAULT }, + { "", 0}} + }, + {"th", LANG_THAI, { + {"TH", SUBLANG_DEFAULT}, + {"",0}} + }, + {"tr", LANG_TURKISH, { + { "TR", SUBLANG_DEFAULT }, + { "", 0}} + }, + { "tt", LANG_TATAR, { + { "RU", SUBLANG_DEFAULT }, + { "", 0}} + }, + {"uk", LANG_UKRAINIAN, { + { "UA", SUBLANG_DEFAULT }, + { "", 0}} + }, + {"ur", LANG_URDU, { + { "PK", SUBLANG_URDU_PAKISTAN }, + { "IN", SUBLANG_URDU_INDIA }, + { "", 0}} + }, + {"uz", LANG_UZBEK, { // XXX : Cyrillic, Latin + { "UZ", SUBLANG_DEFAULT }, + { "", 0}} + }, + {"vi", LANG_VIETNAMESE, { + { "VN", SUBLANG_DEFAULT }, + { "", 0}} + }, + { "zh", LANG_CHINESE, { + { "TW", SUBLANG_CHINESE_TRADITIONAL }, + { "CN", SUBLANG_CHINESE_SIMPLIFIED }, + { "HK", SUBLANG_CHINESE_HONGKONG }, + { "SG", SUBLANG_CHINESE_SINGAPORE }, + { "MO", SUBLANG_CHINESE_MACAU }, + { "",0}} + } +}; + +#define LENGTH_MAPPING_LIST ArrayLength(iso_list) + +// +// This list maps ISO 2 digit country codes to Win32 country codes. +// This list must be kept in alphabetic (by iso code) order and synchronized +// with the list above. This is only used in debug builds to check the consistentcy +// of the internal tables. +// +#ifdef DEBUG +static const +iso_pair dbg_list[] = +{ + {"af", LANG_AFRIKAANS}, + {"ar", LANG_ARABIC}, + {"az", LANG_AZERI}, + {"be", LANG_BELARUSIAN}, + {"bg", LANG_BULGARIAN}, + {"ca", LANG_CATALAN}, + {"cs", LANG_CZECH}, + {"da", LANG_DANISH}, + {"de", LANG_GERMAN}, + {"dv", LANG_DIVEHI}, + {"el", LANG_GREEK}, + {"en", LANG_ENGLISH}, + {"es", LANG_SPANISH}, + {"et", LANG_ESTONIAN}, + {"eu", LANG_BASQUE}, + {"fa", LANG_FARSI}, + {"fi", LANG_FINNISH}, + {"fo", LANG_FAEROESE}, + {"fr", LANG_FRENCH}, + {"gl", LANG_GALICIAN}, + {"gu", LANG_GUJARATI}, + {"he", LANG_HEBREW}, + {"hi", LANG_HINDI}, + {"hr", LANG_CROATIAN}, + {"hu", LANG_HUNGARIAN}, + {"hy", LANG_ARMENIAN}, + {"id", LANG_INDONESIAN}, + {"in", LANG_INDONESIAN}, + {"is", LANG_ICELANDIC}, + {"it", LANG_ITALIAN}, + {"iw", LANG_HEBREW}, + {"ja", LANG_JAPANESE}, + {"ka", LANG_GEORGIAN}, + {"kn", LANG_KANNADA}, + {"ko", LANG_KOREAN}, + {"kok", LANG_KONKANI}, + {"lt", LANG_LITHUANIAN}, + {"lv", LANG_LATVIAN}, + {"mk", LANG_MACEDONIAN}, + {"mn", LANG_MONGOLIAN}, + {"mr", LANG_MARATHI}, + {"ms", LANG_MALAY}, + {"nb", LANG_NORWEGIAN}, + {"nl", LANG_DUTCH}, + {"nn", LANG_NORWEGIAN}, + {"no", LANG_NORWEGIAN}, + {"pa", LANG_PUNJABI}, + {"pl", LANG_POLISH}, + {"pt", LANG_PORTUGUESE}, + {"ro", LANG_ROMANIAN}, + {"ru", LANG_RUSSIAN}, + {"sa", LANG_SANSKRIT}, + {"sk", LANG_SLOVAK}, + {"sl", LANG_SLOVENIAN}, + {"sq", LANG_ALBANIAN}, + {"sr", LANG_SERBIAN}, + {"sv", LANG_SWEDISH}, + {"sw", LANG_SWAHILI}, + {"ta", LANG_TAMIL}, + {"te", LANG_TELUGU}, + {"th", LANG_THAI}, + {"tr", LANG_TURKISH}, + {"tt", LANG_TATAR}, + {"uk", LANG_UKRAINIAN}, + {"ur", LANG_URDU}, + {"uz", LANG_UZBEK}, + {"vi", LANG_VIETNAMESE}, + {"zh", LANG_CHINESE}, + {"",0} +}; +#endif + +#define CROATIAN_ISO_CODE "hr" +#define SERBIAN_ISO_CODE "sr" + +void +nsWin32Locale::initFunctionPointers(void) +{ + static bool sInitialized = false; + // We use the Vista and above functions if we have them + if (!sInitialized) { + HMODULE kernelDLL = GetModuleHandleW(L"kernel32.dll"); + if (kernelDLL) { + localeNameToLCID = (LocaleNameToLCIDPtr) GetProcAddress(kernelDLL, "LocaleNameToLCID"); + lcidToLocaleName = (LCIDToLocaleNamePtr) GetProcAddress(kernelDLL, "LCIDToLocaleName"); + } + sInitialized = true; + } +} + +// +// the mapping routines are a first approximation to get us going on +// the tier-1 languages. we are making an assumption that we can map +// language and country codes separately on Windows, which isn't true +// +nsresult +nsWin32Locale::GetPlatformLocale(const nsAString& locale, LCID* winLCID) +{ + initFunctionPointers (); + + if (localeNameToLCID) { + nsAutoString locale_autostr(locale); + LCID lcid = localeNameToLCID(locale_autostr.get(), 0); + // The function returning 0 means that the locale name couldn't be matched, + // so we fallback to the old function + if (lcid != 0) + { + *winLCID = lcid; + return NS_OK; + } + } + + char locale_string[9] = {'\0','\0','\0','\0','\0','\0','\0','\0','\0'}; + char* language_code; + char* country_code; + size_t i, j; + + // parse the locale + const char16_t* data; + j = NS_StringGetData(locale, &data); + for (i = 0; i < 7 && i < j; i++) { + locale_string[i] = data[i] == '-' ? '\0' : data[i]; + } + + language_code = locale_string; + country_code = locale_string + strlen(locale_string) + 1; + + // convert parsed locale to Windows LCID + for(i=0;i<LENGTH_MAPPING_LIST;i++) { + if (strcmp(language_code,iso_list[i].iso_code)==0) { + for(j=0;iso_list[i].sublang_list[j].win_code;j++) { + if (strcmp(country_code,iso_list[i].sublang_list[j].iso_code)==0) { + *winLCID = MAKELCID(MAKELANGID(iso_list[i].win_code,iso_list[i].sublang_list[j].win_code),SORT_DEFAULT); + return NS_OK; + } + } + // here we have a language match but no country match + *winLCID = MAKELCID(MAKELANGID(iso_list[i].win_code,SUBLANG_DEFAULT),SORT_DEFAULT); + return NS_OK; + } + } + + return NS_ERROR_FAILURE; +} + +#ifndef LOCALE_NAME_MAX_LENGTH +#define LOCALE_NAME_MAX_LENGTH 85 +#endif + +void +nsWin32Locale::GetXPLocale(LCID winLCID, nsAString& locale) +{ + initFunctionPointers (); + + if (lcidToLocaleName) + { + WCHAR ret_locale[LOCALE_NAME_MAX_LENGTH]; + int rv = lcidToLocaleName(winLCID, ret_locale, LOCALE_NAME_MAX_LENGTH, 0); + // rv 0 means that the function failed to match up the LCID, so we fallback + // to the old function + if (rv != 0) + { + locale.Assign(ret_locale); + return; + } + } + + DWORD lang_id, sublang_id; + size_t i, j; + + lang_id = PRIMARYLANGID(LANGIDFROMLCID(winLCID)); + sublang_id = SUBLANGID(LANGIDFROMLCID(winLCID)); + + /* Special-case Norwegian Bokmal and Norwegian Nynorsk, which have the same + LANG_ID on Windows, but have separate ISO-639-2 codes */ + if (lang_id == LANG_NORWEGIAN) { + if (sublang_id == SUBLANG_NORWEGIAN_BOKMAL) { + locale.AssignASCII("nb-NO"); + } else if (sublang_id == SUBLANG_NORWEGIAN_NYNORSK) { + locale.AssignASCII("nn-NO"); + } else { + locale.AssignASCII("no-NO"); + } + return; + } + + for(i=0;i<LENGTH_MAPPING_LIST;i++) { + if (lang_id==iso_list[i].win_code) { + /* Special-case Croatian and Serbian, which have the same LANG_ID on + Windows, but have been split into separate ISO-639-2 codes */ + if (lang_id == LANG_CROATIAN) { + if (sublang_id == SUBLANG_DEFAULT) { + locale.AssignLiteral(CROATIAN_ISO_CODE); + } else { + locale.AssignLiteral(SERBIAN_ISO_CODE); + } + } else { + locale.AssignASCII(iso_list[i].iso_code); + } + for(j=0;iso_list[i].sublang_list[j].win_code;j++) { + if (sublang_id == iso_list[i].sublang_list[j].win_code) { + locale.Append(char16_t('-')); + locale.AppendASCII(iso_list[i].sublang_list[j].iso_code); + break; + } + } + return; + } + } + + // + // didn't find any match. fall back to en-US, which is better + // than unusable buttons without 'OK', 'Cancel', etc (bug 224546) + // + locale.AssignLiteral("en-US"); + return; +} + +#ifdef DEBUG +void +test_internal_tables(void) +{ + size_t i; + + for(i=1;i<LENGTH_MAPPING_LIST;i++) { + if (strcmp(dbg_list[i-1].iso_code,dbg_list[i].iso_code)>=0) + fprintf(stderr,"nsLocale: language_list %s and %s are not ordered\n",dbg_list[i-1].iso_code,dbg_list[i].iso_code); + } + + i=0; + while(strlen(dbg_list[i].iso_code)!=0) { + i++; + } + if (i!=LENGTH_MAPPING_LIST) + fprintf(stderr,"nsLocale: language_list length is %u, reported length is %u\n", + unsigned(i), unsigned(LENGTH_MAPPING_LIST)); + + for(i=0;i<LENGTH_MAPPING_LIST;i++) { + if (strcmp(iso_list[i].iso_code,dbg_list[i].iso_code)!=0) { + fprintf(stderr,"nsLocale: iso_list and dbg_list different at item: %u\n", + unsigned(i)); + } + } +} + +#endif + diff --git a/intl/locale/windows/nsWinCharset.cpp b/intl/locale/windows/nsWinCharset.cpp new file mode 100644 index 000000000..c84307267 --- /dev/null +++ b/intl/locale/windows/nsWinCharset.cpp @@ -0,0 +1,101 @@ + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/ArrayUtils.h" + +#include "nsIPlatformCharset.h" +#include "nsUConvPropertySearch.h" +#include <windows.h> +#include "nsWin32Locale.h" +#include "nsCOMPtr.h" +#include "nsReadableUtils.h" +#include "nsServiceManagerUtils.h" +#include "nsPlatformCharset.h" +#include "nsEncoderDecoderUtils.h" + +using namespace mozilla; + +static const nsUConvProp kWinCharsets[] = { +#include "wincharset.properties.h" +}; + +NS_IMPL_ISUPPORTS(nsPlatformCharset, nsIPlatformCharset) + +nsPlatformCharset::nsPlatformCharset() +{ + nsAutoString acpKey(NS_LITERAL_STRING("acp.")); + acpKey.AppendInt(int32_t(::GetACP() & 0x00FFFF), 10); + MapToCharset(acpKey, mCharset); +} + +nsPlatformCharset::~nsPlatformCharset() +{ +} + +nsresult +nsPlatformCharset::MapToCharset(nsAString& inANSICodePage, nsACString& outCharset) +{ + nsAutoCString key; + LossyCopyUTF16toASCII(inANSICodePage, key); + + nsresult rv = nsUConvPropertySearch::SearchPropertyValue(kWinCharsets, + ArrayLength(kWinCharsets), key, outCharset); + if (NS_FAILED(rv)) { + outCharset.AssignLiteral("windows-1252"); + return NS_SUCCESS_USING_FALLBACK_LOCALE; + } + return rv; +} + +NS_IMETHODIMP +nsPlatformCharset::GetCharset(nsPlatformCharsetSel selector, + nsACString& oResult) +{ + oResult = mCharset; + return NS_OK; +} + +NS_IMETHODIMP +nsPlatformCharset::GetDefaultCharsetForLocale(const nsAString& localeName, nsACString& oResult) +{ + LCID localeAsLCID; + + // + // convert locale name to a code page (through the LCID) + // + nsresult rv; + oResult.Truncate(); + + rv = nsWin32Locale::GetPlatformLocale(localeName, &localeAsLCID); + if (NS_FAILED(rv)) { return rv; } + + wchar_t acp_name[6]; + if (GetLocaleInfoW(localeAsLCID, LOCALE_IDEFAULTANSICODEPAGE, acp_name, + ArrayLength(acp_name))==0) { + return NS_ERROR_FAILURE; + } + nsAutoString acp_key(NS_LITERAL_STRING("acp.")); + acp_key.Append(acp_name); + + return MapToCharset(acp_key, oResult); +} + +NS_IMETHODIMP +nsPlatformCharset::Init() +{ + return NS_OK; +} + +nsresult +nsPlatformCharset::InitGetCharset(nsACString &oString) +{ + return NS_OK; +} + +nsresult +nsPlatformCharset::VerifyCharset(nsCString &aCharset) +{ + return NS_OK; +} diff --git a/intl/locale/windows/wincharset.properties b/intl/locale/windows/wincharset.properties new file mode 100644 index 000000000..79a802492 --- /dev/null +++ b/intl/locale/windows/wincharset.properties @@ -0,0 +1,23 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file map a ACP to a charset name +# We use this to figure out the charset of file system, clipboard, etc +# + +acp.874=windows-874 +acp.932=Shift_JIS +acp.936=gb18030 +acp.949=EUC-KR +acp.950=Big5 +acp.951=Big5 +acp.1250=windows-1250 +acp.1251=windows-1251 +acp.1252=windows-1252 +acp.1253=windows-1253 +acp.1254=windows-1254 +acp.1255=windows-1255 +acp.1256=windows-1256 +acp.1257=windows-1257 +acp.1258=windows-1258 |