michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsLanguageAtomService.h" michael@0: #include "nsICharsetConverterManager.h" michael@0: #include "nsILocaleService.h" michael@0: #include "nsUnicharUtils.h" michael@0: #include "nsIAtom.h" michael@0: #include "mozilla/Services.h" michael@0: #include "nsServiceManagerUtils.h" michael@0: michael@0: NS_IMPL_ISUPPORTS(nsLanguageAtomService, nsILanguageAtomService) michael@0: michael@0: nsLanguageAtomService::nsLanguageAtomService() michael@0: { michael@0: } michael@0: michael@0: nsresult michael@0: nsLanguageAtomService::InitLangGroupTable() michael@0: { michael@0: if (mLangGroups) michael@0: return NS_OK; michael@0: michael@0: nsCOMPtr bundleService = michael@0: mozilla::services::GetStringBundleService(); michael@0: if (!bundleService) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: return bundleService->CreateBundle("resource://gre/res/langGroups.properties", michael@0: getter_AddRefs(mLangGroups)); michael@0: } michael@0: michael@0: nsIAtom* michael@0: nsLanguageAtomService::LookupLanguage(const nsACString &aLanguage, michael@0: nsresult *aError) michael@0: { michael@0: nsAutoCString lowered(aLanguage); michael@0: ToLowerCase(lowered); michael@0: michael@0: nsCOMPtr lang = do_GetAtom(lowered); michael@0: return GetLanguageGroup(lang, aError); michael@0: } michael@0: michael@0: already_AddRefed michael@0: nsLanguageAtomService::LookupCharSet(const char *aCharSet, nsresult *aError) michael@0: { michael@0: if (!mCharSets) { michael@0: mCharSets = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID); michael@0: if (!mCharSets) { michael@0: if (aError) michael@0: *aError = NS_ERROR_FAILURE; michael@0: michael@0: return nullptr; michael@0: } michael@0: } michael@0: michael@0: nsCOMPtr langGroup; michael@0: mCharSets->GetCharsetLangGroup(aCharSet, getter_AddRefs(langGroup)); michael@0: if (!langGroup) { michael@0: if (aError) michael@0: *aError = NS_ERROR_FAILURE; michael@0: michael@0: return nullptr; michael@0: } michael@0: michael@0: if (aError) michael@0: *aError = NS_OK; michael@0: michael@0: return langGroup.forget(); michael@0: } michael@0: michael@0: nsIAtom* michael@0: nsLanguageAtomService::GetLocaleLanguage(nsresult *aError) michael@0: { michael@0: nsresult res = NS_OK; michael@0: michael@0: do { michael@0: if (!mLocaleLanguage) { michael@0: nsCOMPtr localeService; michael@0: localeService = do_GetService(NS_LOCALESERVICE_CONTRACTID); michael@0: if (!localeService) { michael@0: res = NS_ERROR_FAILURE; michael@0: break; michael@0: } michael@0: michael@0: nsCOMPtr locale; michael@0: res = localeService->GetApplicationLocale(getter_AddRefs(locale)); michael@0: if (NS_FAILED(res)) michael@0: break; michael@0: michael@0: nsAutoString loc; michael@0: res = locale->GetCategory(NS_LITERAL_STRING(NSILOCALE_MESSAGE), loc); michael@0: if (NS_FAILED(res)) michael@0: break; michael@0: michael@0: ToLowerCase(loc); // use lowercase for all language atoms michael@0: mLocaleLanguage = do_GetAtom(loc); michael@0: } michael@0: } while (0); michael@0: michael@0: if (aError) michael@0: *aError = res; michael@0: michael@0: return mLocaleLanguage; michael@0: } michael@0: michael@0: nsIAtom* michael@0: nsLanguageAtomService::GetLanguageGroup(nsIAtom *aLanguage, michael@0: nsresult *aError) michael@0: { michael@0: nsIAtom *retVal; michael@0: nsresult res = NS_OK; michael@0: michael@0: retVal = mLangToGroup.GetWeak(aLanguage); michael@0: michael@0: if (!retVal) { michael@0: if (!mLangGroups) { michael@0: if (NS_FAILED(InitLangGroupTable())) { michael@0: if (aError) { michael@0: *aError = NS_ERROR_FAILURE; michael@0: } michael@0: return nullptr; michael@0: } michael@0: } michael@0: michael@0: nsString langStr; michael@0: aLanguage->ToString(langStr); michael@0: michael@0: nsXPIDLString langGroupStr; michael@0: res = mLangGroups->GetStringFromName(langStr.get(), michael@0: getter_Copies(langGroupStr)); michael@0: if (NS_FAILED(res)) { michael@0: int32_t hyphen = langStr.FindChar('-'); michael@0: if (hyphen >= 0) { michael@0: nsAutoString truncated(langStr); michael@0: truncated.Truncate(hyphen); michael@0: res = mLangGroups->GetStringFromName(truncated.get(), michael@0: getter_Copies(langGroupStr)); michael@0: if (NS_FAILED(res)) { michael@0: langGroupStr.AssignLiteral("x-unicode"); michael@0: } michael@0: } else { michael@0: langGroupStr.AssignLiteral("x-unicode"); michael@0: } michael@0: } michael@0: michael@0: nsCOMPtr langGroup = do_GetAtom(langGroupStr); michael@0: michael@0: // The hashtable will keep an owning reference to the atom michael@0: mLangToGroup.Put(aLanguage, langGroup); michael@0: retVal = langGroup.get(); michael@0: } michael@0: michael@0: if (aError) { michael@0: *aError = res; michael@0: } michael@0: michael@0: return retVal; michael@0: }