// // nsLocaleService methods // nsLocaleService::nsLocaleService(void) : mSystemLocale(0), mApplicationLocale(0) { #ifdef XP_WIN nsCOMPtr<nsIWin32Locale> win32Converter = do_GetService(NS_WIN32LOCALE_CONTRACTID); NS_ASSERTION(win32Converter, "nsLocaleService: can't get win32 converter\n"); nsAutoString xpLocale; if (win32Converter) { nsresult result; // // get the system LCID // LCID win_lcid = GetSystemDefaultLCID(); if (win_lcid==0) { return;} result = win32Converter->GetXPLocale(win_lcid, xpLocale); if (NS_FAILED(result)) { return;} result = NewLocale(xpLocale, getter_AddRefs(mSystemLocale)); if (NS_FAILED(result)) { return;} // // get the application LCID // win_lcid = GetUserDefaultLCID(); if (win_lcid==0) { return;} result = win32Converter->GetXPLocale(win_lcid, xpLocale); if (NS_FAILED(result)) { return;} result = NewLocale(xpLocale, getter_AddRefs(mApplicationLocale)); if (NS_FAILED(result)) { return;} } #endif #if (defined(XP_UNIX) && !defined(XP_MACOSX)) || defined(XP_BEOS) || defined(XP_AMIGAOS) nsCOMPtr<nsIPosixLocale> posixConverter = do_GetService(NS_POSIXLOCALE_CONTRACTID); nsAutoString xpLocale, platformLocale; if (posixConverter) { nsAutoString category, category_platform; int i; nsRefPtr<nsLocale> resultLocale(new nsLocale()); if ( resultLocale == NULL ) { return; } #ifdef MOZ_WIDGET_QT const char* lang = QLocale::languageToString(QLocale::system().language()).toAscii(); #else // Get system configuration const char* lang = getenv("LANG"); #endif for( i = 0; i < LocaleListLength; i++ ) { nsresult result; // setlocale( , "") evaluates LC_* and LANG char* lc_temp = setlocale(posix_locale_category[i], ""); CopyASCIItoUTF16(LocaleList[i], category); category_platform = category; category_platform.AppendLiteral("##PLATFORM"); if (lc_temp != nsnull) { result = posixConverter->GetXPLocale(lc_temp, xpLocale); CopyASCIItoUTF16(lc_temp, platformLocale); } else { if ( lang == nsnull ) { platformLocale.AssignLiteral("en_US"); result = posixConverter->GetXPLocale("en-US", xpLocale); } else { CopyASCIItoUTF16(lang, platformLocale); result = posixConverter->GetXPLocale(lang, xpLocale); } } if (NS_FAILED(result)) { return; } resultLocale->AddCategory(category, xpLocale); resultLocale->AddCategory(category_platform, platformLocale); } mSystemLocale = do_QueryInterface(resultLocale); mApplicationLocale = do_QueryInterface(resultLocale); } // if ( NS_SUCCEEDED )... #endif // XP_UNIX || XP_BEOS #ifdef XP_OS2 nsCOMPtr<nsIOS2Locale> os2Converter = do_GetService(NS_OS2LOCALE_CONTRACTID); nsAutoString xpLocale; if (os2Converter) { nsAutoString category; int i; nsRefPtr<nsLocale> resultLocale(new nsLocale()); if ( resultLocale == NULL ) { return; } LocaleObject locale_object = NULL; int result = UniCreateLocaleObject(UNI_UCS_STRING_POINTER, (UniChar *)L"", &locale_object); if (result != ULS_SUCCESS) { int result = UniCreateLocaleObject(UNI_UCS_STRING_POINTER, (UniChar *)L"en_US", &locale_object); } char* lc_temp; for( i = 0; i < LocaleListLength; i++ ) { lc_temp = nsnull; UniQueryLocaleObject(locale_object, posix_locale_category[i], UNI_MBS_STRING_POINTER, (void **)&lc_temp); category.AssignWithConversion(LocaleList[i]); nsresult result; if (lc_temp != nsnull) result = os2Converter->GetXPLocale(lc_temp, xpLocale); else { char* lang = getenv("LANG"); if ( lang == nsnull ) { result = os2Converter->GetXPLocale("en-US", xpLocale); } else result = os2Converter->GetXPLocale(lang, xpLocale); } if (NS_FAILED(result)) { UniFreeMem(lc_temp); UniFreeLocaleObject(locale_object); return; } resultLocale->AddCategory(category, xpLocale); UniFreeMem(lc_temp); } UniFreeLocaleObject(locale_object); mSystemLocale = do_QueryInterface(resultLocale); mApplicationLocale = do_QueryInterface(resultLocale); } // if ( NS_SUCCEEDED )... #endif // XP_OS2 #ifdef XP_MACOSX // Get string representation of user's current locale CFLocaleRef userLocaleRef = ::CFLocaleCopyCurrent(); CFStringRef userLocaleStr = ::CFLocaleGetIdentifier(userLocaleRef); ::CFRetain(userLocaleStr); nsAutoTArray<UniChar, 32> buffer; int size = ::CFStringGetLength(userLocaleStr); if (buffer.SetLength(size + 1)) { CFRange range = ::CFRangeMake(0, size); ::CFStringGetCharacters(userLocaleStr, range, buffer.Elements()); buffer[size] = 0; // Convert the locale string to the format that Mozilla expects nsAutoString xpLocale(buffer.Elements()); xpLocale.ReplaceChar('_', '-'); nsresult rv = NewLocale(xpLocale, getter_AddRefs(mSystemLocale)); if (NS_SUCCEEDED(rv)) { mApplicationLocale = mSystemLocale; } } ::CFRelease(userLocaleStr); ::CFRelease(userLocaleRef); NS_ASSERTION(mApplicationLocale, "Failed to create locale objects"); #endif // XP_MACOSX }
NS_IMETHODIMP nsLocaleService::GetLocaleFromAcceptLanguage(const char *acceptLanguage, nsILocale **_retval) { char* input; char* cPtr; char* cPtr1; char* cPtr2; int i; int j; int countLang = 0; char acceptLanguageList[NSILOCALE_MAX_ACCEPT_LANGUAGE][NSILOCALE_MAX_ACCEPT_LENGTH]; nsresult result; input = new char[strlen(acceptLanguage)+1]; NS_ASSERTION(input!=nsnull,"nsLocaleFactory::GetLocaleFromAcceptLanguage: memory allocation failed."); if (input == (char*)NULL){ return NS_ERROR_OUT_OF_MEMORY; } strcpy(input, acceptLanguage); cPtr1 = input-1; cPtr2 = input; /* put in standard form */ while (*(++cPtr1)) { if (isalpha(*cPtr1)) *cPtr2++ = tolower(*cPtr1); /* force lower case */ else if (isspace(*cPtr1)) ; /* ignore any space */ else if (*cPtr1=='-') *cPtr2++ = '_'; /* "-" -> "_" */ else if (*cPtr1=='*') ; /* ignore "*" */ else *cPtr2++ = *cPtr1; /* else unchanged */ } *cPtr2 = '\0'; countLang = 0; if (strchr(input,';')) { /* deal with the quality values */ float qvalue[NSILOCALE_MAX_ACCEPT_LANGUAGE]; float qSwap; float bias = 0.0f; char* ptrLanguage[NSILOCALE_MAX_ACCEPT_LANGUAGE]; char* ptrSwap; cPtr = nsCRT::strtok(input,",",&cPtr2); while (cPtr) { qvalue[countLang] = 1.0f; /* add extra parens to get rid of warning */ if ((cPtr1 = strchr(cPtr,';')) != nsnull) { PR_sscanf(cPtr1,";q=%f",&qvalue[countLang]); *cPtr1 = '\0'; } if (strlen(cPtr)<NSILOCALE_MAX_ACCEPT_LANGUAGE) { /* ignore if too long */ qvalue[countLang] -= (bias += 0.0001f); /* to insure original order */ ptrLanguage[countLang++] = cPtr; if (countLang>=NSILOCALE_MAX_ACCEPT_LANGUAGE) break; /* quit if too many */ } cPtr = nsCRT::strtok(cPtr2,",",&cPtr2); } /* sort according to decending qvalue */ /* not a very good algorithm, but count is not likely large */ for ( i=0 ; i<countLang-1 ; i++ ) { for ( j=i+1 ; j<countLang ; j++ ) { if (qvalue[i]<qvalue[j]) { qSwap = qvalue[i]; qvalue[i] = qvalue[j]; qvalue[j] = qSwap; ptrSwap = ptrLanguage[i]; ptrLanguage[i] = ptrLanguage[j]; ptrLanguage[j] = ptrSwap; } } } for ( i=0 ; i<countLang ; i++ ) { PL_strncpyz(acceptLanguageList[i],ptrLanguage[i],NSILOCALE_MAX_ACCEPT_LENGTH); } } else { /* simple case: no quality values */ cPtr = nsCRT::strtok(input,",",&cPtr2); while (cPtr) { if (strlen(cPtr)<NSILOCALE_MAX_ACCEPT_LENGTH) { /* ignore if too long */ PL_strncpyz(acceptLanguageList[countLang++],cPtr,NSILOCALE_MAX_ACCEPT_LENGTH); if (countLang>=NSILOCALE_MAX_ACCEPT_LENGTH) break; /* quit if too many */ } cPtr = nsCRT::strtok(cPtr2,",",&cPtr2); } } // // now create the locale // result = NS_ERROR_FAILURE; if (countLang>0) { result = NewLocale(NS_ConvertASCIItoUTF16(acceptLanguageList[0]), _retval); } // // clean up // delete[] input; return result; }
// // nsLocaleService methods // nsLocaleService::nsLocaleService(void) { #ifdef XP_WIN nsAutoString xpLocale; // // get the system LCID // LCID win_lcid = GetSystemDefaultLCID(); NS_ENSURE_TRUE_VOID(win_lcid); nsWin32Locale::GetXPLocale(win_lcid, xpLocale); nsresult rv = NewLocale(xpLocale, getter_AddRefs(mSystemLocale)); NS_ENSURE_SUCCESS_VOID(rv); // // get the application LCID // win_lcid = GetUserDefaultLCID(); NS_ENSURE_TRUE_VOID(win_lcid); nsWin32Locale::GetXPLocale(win_lcid, xpLocale); rv = NewLocale(xpLocale, getter_AddRefs(mApplicationLocale)); NS_ENSURE_SUCCESS_VOID(rv); #endif #if defined(XP_UNIX) && !defined(XP_MACOSX) nsRefPtr<nsLocale> resultLocale(new nsLocale()); NS_ENSURE_TRUE_VOID(resultLocale); #ifdef MOZ_WIDGET_QT const char* lang = QLocale::system().name().toUtf8(); #else // Get system configuration const char* lang = getenv("LANG"); #endif nsAutoString xpLocale, platformLocale; nsAutoString category, category_platform; int i; for( i = 0; i < LocaleListLength; i++ ) { nsresult result; // setlocale( , "") evaluates LC_* and LANG char* lc_temp = setlocale(posix_locale_category[i], ""); CopyASCIItoUTF16(LocaleList[i], category); category_platform = category; category_platform.AppendLiteral("##PLATFORM"); if (lc_temp != nullptr) { result = nsPosixLocale::GetXPLocale(lc_temp, xpLocale); CopyASCIItoUTF16(lc_temp, platformLocale); } else { if ( lang == nullptr ) { platformLocale.AssignLiteral("en_US"); result = nsPosixLocale::GetXPLocale("en-US", xpLocale); } else { CopyASCIItoUTF16(lang, platformLocale); result = nsPosixLocale::GetXPLocale(lang, xpLocale); } } if (NS_FAILED(result)) { return; } resultLocale->AddCategory(category, xpLocale); resultLocale->AddCategory(category_platform, platformLocale); } mSystemLocale = do_QueryInterface(resultLocale); mApplicationLocale = do_QueryInterface(resultLocale); #endif // XP_UNIX #ifdef XP_MACOSX // Get string representation of user's current locale CFLocaleRef userLocaleRef = ::CFLocaleCopyCurrent(); CFStringRef userLocaleStr = ::CFLocaleGetIdentifier(userLocaleRef); ::CFRetain(userLocaleStr); nsAutoTArray<UniChar, 32> buffer; int size = ::CFStringGetLength(userLocaleStr); if (buffer.SetLength(size + 1)) { CFRange range = ::CFRangeMake(0, size); ::CFStringGetCharacters(userLocaleStr, range, buffer.Elements()); buffer[size] = 0; // Convert the locale string to the format that Mozilla expects nsAutoString xpLocale(buffer.Elements()); xpLocale.ReplaceChar('_', '-'); nsresult rv = NewLocale(xpLocale, getter_AddRefs(mSystemLocale)); if (NS_SUCCEEDED(rv)) { mApplicationLocale = mSystemLocale; } } ::CFRelease(userLocaleStr); ::CFRelease(userLocaleRef); NS_ASSERTION(mApplicationLocale, "Failed to create locale objects"); #endif // XP_MACOSX }