LCOV - code coverage report
Current view: top level - intl/locale - nsLocaleService.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 118 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 12 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #include "nsCOMPtr.h"
       7             : #include "nsILocale.h"
       8             : #include "nsILocaleService.h"
       9             : #include "nsLocale.h"
      10             : #include "nsCRT.h"
      11             : #include "prprf.h"
      12             : #include "nsTArray.h"
      13             : #include "nsString.h"
      14             : #include "mozilla/UniquePtr.h"
      15             : 
      16             : #include <ctype.h>
      17             : 
      18             : #if defined(XP_WIN)
      19             : #  include "nsWin32Locale.h"
      20             : #elif defined(XP_MACOSX)
      21             : #  include <Carbon/Carbon.h>
      22             : #elif defined(XP_UNIX)
      23             : #  include <locale.h>
      24             : #  include <stdlib.h>
      25             : #  include "nsPosixLocale.h"
      26             : #endif
      27             : 
      28             : using namespace mozilla;
      29             : 
      30             : //
      31             : // implementation constants
      32             : const int LocaleListLength = 6;
      33             : const char* LocaleList[LocaleListLength] =
      34             : {
      35             :         NSILOCALE_COLLATE,
      36             :         NSILOCALE_CTYPE,
      37             :         NSILOCALE_MONETARY,
      38             :         NSILOCALE_NUMERIC,
      39             :         NSILOCALE_TIME,
      40             :         NSILOCALE_MESSAGE
      41             : };
      42             : 
      43             : #define NSILOCALE_MAX_ACCEPT_LANGUAGE   16
      44             : #define NSILOCALE_MAX_ACCEPT_LENGTH             18
      45             : 
      46             : #if (defined(XP_UNIX) && !defined(XP_MACOSX))
      47             : static int posix_locale_category[LocaleListLength] =
      48             : {
      49             :   LC_COLLATE,
      50             :   LC_CTYPE,
      51             :   LC_MONETARY,
      52             :   LC_NUMERIC,
      53             :   LC_TIME,
      54             : #ifdef HAVE_I18N_LC_MESSAGES
      55             :   LC_MESSAGES
      56             : #else
      57             :   LC_CTYPE
      58             : #endif
      59             : };
      60             : #endif
      61             : 
      62             : //
      63             : // nsILocaleService implementation
      64             : //
      65             : class nsLocaleService: public nsILocaleService {
      66             : 
      67             : public:
      68             : 
      69             :         //
      70             :         // nsISupports
      71             :         //
      72             :         NS_DECL_THREADSAFE_ISUPPORTS
      73             : 
      74             :         //
      75             :         // nsILocaleService
      76             :         //
      77             :     NS_DECL_NSILOCALESERVICE
      78             : 
      79             : 
      80             :         nsLocaleService(void);
      81             : 
      82             : protected:
      83             : 
      84             :         nsresult SetSystemLocale(void);
      85             :         nsresult SetApplicationLocale(void);
      86             : 
      87             :         nsCOMPtr<nsILocale>                               mSystemLocale;
      88             :         nsCOMPtr<nsILocale>                               mApplicationLocale;
      89             : 
      90             :         virtual ~nsLocaleService(void);
      91             : };
      92             : 
      93             : //
      94             : // nsLocaleService methods
      95             : //
      96           0 : nsLocaleService::nsLocaleService(void)
      97             : {
      98             : #ifdef XP_WIN
      99             :     nsAutoString        xpLocale;
     100             :     //
     101             :     // get the system LCID
     102             :     //
     103             :     LCID win_lcid = GetSystemDefaultLCID();
     104             :     NS_ENSURE_TRUE_VOID(win_lcid);
     105             :     nsWin32Locale::GetXPLocale(win_lcid, xpLocale);
     106             :     nsresult rv = NewLocale(xpLocale, getter_AddRefs(mSystemLocale));
     107             :     NS_ENSURE_SUCCESS_VOID(rv);
     108             : 
     109             :     //
     110             :     // get the application LCID
     111             :     //
     112             :     win_lcid = GetUserDefaultLCID();
     113             :     NS_ENSURE_TRUE_VOID(win_lcid);
     114             :     nsWin32Locale::GetXPLocale(win_lcid, xpLocale);
     115             :     rv = NewLocale(xpLocale, getter_AddRefs(mApplicationLocale));
     116             :     NS_ENSURE_SUCCESS_VOID(rv);
     117             : #endif
     118             : #if defined(XP_UNIX) && !defined(XP_MACOSX)
     119           0 :     RefPtr<nsLocale> resultLocale(new nsLocale());
     120           0 :     NS_ENSURE_TRUE_VOID(resultLocale);
     121             : 
     122             :     // Get system configuration
     123           0 :     const char* lang = getenv("LANG");
     124             : 
     125           0 :     nsAutoString xpLocale, platformLocale;
     126           0 :     nsAutoString category, category_platform;
     127             :     int i;
     128             : 
     129           0 :     for( i = 0; i < LocaleListLength; i++ ) {
     130             :         nsresult result;
     131             :         // setlocale( , "") evaluates LC_* and LANG
     132           0 :         char* lc_temp = setlocale(posix_locale_category[i], "");
     133           0 :         CopyASCIItoUTF16(LocaleList[i], category);
     134           0 :         category_platform = category;
     135           0 :         category_platform.AppendLiteral("##PLATFORM");
     136             : 
     137           0 :         bool lc_temp_valid = lc_temp != nullptr;
     138             : 
     139             : #if defined(MOZ_WIDGET_ANDROID)
     140             :         // Treat the "C" env as nothing useful. See Bug 1095298.
     141             :         lc_temp_valid = lc_temp_valid && strcmp(lc_temp, "C") != 0;
     142             : #endif
     143             : 
     144           0 :         if (lc_temp_valid) {
     145           0 :             result = nsPosixLocale::GetXPLocale(lc_temp, xpLocale);
     146           0 :             CopyASCIItoUTF16(lc_temp, platformLocale);
     147             :         } else {
     148           0 :             if ( lang == nullptr ) {
     149           0 :                 platformLocale.AssignLiteral("en_US");
     150           0 :                 result = nsPosixLocale::GetXPLocale("en-US", xpLocale);
     151             :             } else {
     152           0 :                 CopyASCIItoUTF16(lang, platformLocale);
     153           0 :                 result = nsPosixLocale::GetXPLocale(lang, xpLocale);
     154             :             }
     155             :         }
     156           0 :         if (NS_FAILED(result)) {
     157           0 :             return;
     158             :         }
     159           0 :         resultLocale->AddCategory(category, xpLocale);
     160           0 :         resultLocale->AddCategory(category_platform, platformLocale);
     161             :     }
     162           0 :     mSystemLocale = do_QueryInterface(resultLocale);
     163           0 :     mApplicationLocale = do_QueryInterface(resultLocale);
     164             : 
     165             : #endif // XP_UNIX
     166             : 
     167             : #ifdef XP_MACOSX
     168             :     // Get string representation of user's current locale
     169             :     CFLocaleRef userLocaleRef = ::CFLocaleCopyCurrent();
     170             :     CFStringRef userLocaleStr = ::CFLocaleGetIdentifier(userLocaleRef);
     171             :     ::CFRetain(userLocaleStr);
     172             : 
     173             :     AutoTArray<UniChar, 32> buffer;
     174             :     int size = ::CFStringGetLength(userLocaleStr);
     175             :     buffer.SetLength(size + 1);
     176             :     CFRange range = ::CFRangeMake(0, size);
     177             :     ::CFStringGetCharacters(userLocaleStr, range, buffer.Elements());
     178             :     buffer[size] = 0;
     179             : 
     180             :     // Convert the locale string to the format that Mozilla expects
     181             :     nsAutoString xpLocale(reinterpret_cast<char16_t*>(buffer.Elements()));
     182             :     xpLocale.ReplaceChar('_', '-');
     183             : 
     184             :     nsresult rv = NewLocale(xpLocale, getter_AddRefs(mSystemLocale));
     185             :     if (NS_SUCCEEDED(rv)) {
     186             :         mApplicationLocale = mSystemLocale;
     187             :     }
     188             : 
     189             :     ::CFRelease(userLocaleStr);
     190             :     ::CFRelease(userLocaleRef);
     191             : 
     192             :     NS_ASSERTION(mApplicationLocale, "Failed to create locale objects");
     193             : #endif // XP_MACOSX
     194             : }
     195             : 
     196           0 : nsLocaleService::~nsLocaleService(void)
     197             : {
     198           0 : }
     199             : 
     200           0 : NS_IMPL_ISUPPORTS(nsLocaleService, nsILocaleService)
     201             : 
     202             : NS_IMETHODIMP
     203           0 : nsLocaleService::NewLocale(const nsAString &aLocale, nsILocale **_retval)
     204             : {
     205             :     nsresult result;
     206             : 
     207           0 :     *_retval = nullptr;
     208             : 
     209           0 :     RefPtr<nsLocale> resultLocale(new nsLocale());
     210           0 :     if (!resultLocale) return NS_ERROR_OUT_OF_MEMORY;
     211             : 
     212           0 :     for (int32_t i = 0; i < LocaleListLength; i++) {
     213           0 :       NS_ConvertASCIItoUTF16 category(LocaleList[i]);
     214           0 :       result = resultLocale->AddCategory(category, aLocale);
     215           0 :       if (NS_FAILED(result)) return result;
     216             : #if defined(XP_UNIX) && !defined(XP_MACOSX)
     217           0 :       category.AppendLiteral("##PLATFORM");
     218           0 :       result = resultLocale->AddCategory(category, aLocale);
     219           0 :       if (NS_FAILED(result)) return result;
     220             : #endif
     221             :     }
     222             : 
     223           0 :     NS_ADDREF(*_retval = resultLocale);
     224           0 :     return NS_OK;
     225             : }
     226             : 
     227             : 
     228             : NS_IMETHODIMP
     229           0 : nsLocaleService::GetSystemLocale(nsILocale **_retval)
     230             : {
     231           0 :         if (mSystemLocale) {
     232           0 :                 NS_ADDREF(*_retval = mSystemLocale);
     233           0 :                 return NS_OK;
     234             :         }
     235             : 
     236           0 :         *_retval = (nsILocale*)nullptr;
     237           0 :         return NS_ERROR_FAILURE;
     238             : }
     239             : 
     240             : NS_IMETHODIMP
     241           0 : nsLocaleService::GetApplicationLocale(nsILocale **_retval)
     242             : {
     243           0 :         if (mApplicationLocale) {
     244           0 :                 NS_ADDREF(*_retval = mApplicationLocale);
     245           0 :                 return NS_OK;
     246             :         }
     247             : 
     248           0 :         *_retval=(nsILocale*)nullptr;
     249           0 :         return NS_ERROR_FAILURE;
     250             : }
     251             : 
     252             : NS_IMETHODIMP
     253           0 : nsLocaleService::GetLocaleFromAcceptLanguage(const char *acceptLanguage, nsILocale **_retval)
     254             : {
     255             :   char* cPtr;
     256             :   char* cPtr1;
     257             :   char* cPtr2;
     258             :   int i;
     259             :   int j;
     260           0 :   int countLang = 0;
     261             :   char  acceptLanguageList[NSILOCALE_MAX_ACCEPT_LANGUAGE][NSILOCALE_MAX_ACCEPT_LENGTH];
     262             :   nsresult      result;
     263             : 
     264           0 :   auto input = MakeUnique<char[]>(strlen(acceptLanguage)+1);
     265             : 
     266           0 :   strcpy(input.get(), acceptLanguage);
     267           0 :   cPtr1 = input.get()-1;
     268           0 :   cPtr2 = input.get();
     269             : 
     270             :   /* put in standard form */
     271           0 :   while (*(++cPtr1)) {
     272           0 :     if      (isalpha(*cPtr1))  *cPtr2++ = tolower(*cPtr1); /* force lower case */
     273           0 :     else if (isspace(*cPtr1))  ;                           /* ignore any space */
     274           0 :     else if (*cPtr1=='-')      *cPtr2++ = '_';             /* "-" -> "_"       */
     275           0 :     else if (*cPtr1=='*')      ;                           /* ignore "*"       */
     276           0 :     else                       *cPtr2++ = *cPtr1;          /* else unchanged   */
     277             :   }
     278           0 :   *cPtr2 = '\0';
     279             : 
     280           0 :   countLang = 0;
     281             : 
     282           0 :   if (strchr(input.get(), ';')) {
     283             :     /* deal with the quality values */
     284             : 
     285             :     float qvalue[NSILOCALE_MAX_ACCEPT_LANGUAGE];
     286             :     float qSwap;
     287           0 :     float bias = 0.0f;
     288             :     char* ptrLanguage[NSILOCALE_MAX_ACCEPT_LANGUAGE];
     289             :     char* ptrSwap;
     290             : 
     291           0 :     cPtr = nsCRT::strtok(input.get(),",",&cPtr2);
     292           0 :     while (cPtr) {
     293           0 :       qvalue[countLang] = 1.0f;
     294             :       /* add extra parens to get rid of warning */
     295           0 :       if ((cPtr1 = strchr(cPtr,';')) != nullptr) {
     296           0 :         PR_sscanf(cPtr1,";q=%f",&qvalue[countLang]);
     297           0 :         *cPtr1 = '\0';
     298             :       }
     299           0 :       if (strlen(cPtr)<NSILOCALE_MAX_ACCEPT_LANGUAGE) {     /* ignore if too long */
     300           0 :         qvalue[countLang] -= (bias += 0.0001f); /* to insure original order */
     301           0 :         ptrLanguage[countLang++] = cPtr;
     302           0 :         if (countLang>=NSILOCALE_MAX_ACCEPT_LANGUAGE) break; /* quit if too many */
     303             :       }
     304           0 :       cPtr = nsCRT::strtok(cPtr2,",",&cPtr2);
     305             :     }
     306             : 
     307             :     /* sort according to decending qvalue */
     308             :     /* not a very good algorithm, but count is not likely large */
     309           0 :     for ( i=0 ; i<countLang-1 ; i++ ) {
     310           0 :       for ( j=i+1 ; j<countLang ; j++ ) {
     311           0 :         if (qvalue[i]<qvalue[j]) {
     312           0 :           qSwap     = qvalue[i];
     313           0 :           qvalue[i] = qvalue[j];
     314           0 :           qvalue[j] = qSwap;
     315           0 :           ptrSwap        = ptrLanguage[i];
     316           0 :           ptrLanguage[i] = ptrLanguage[j];
     317           0 :           ptrLanguage[j] = ptrSwap;
     318             :         }
     319             :       }
     320             :     }
     321           0 :     for ( i=0 ; i<countLang ; i++ ) {
     322           0 :       PL_strncpyz(acceptLanguageList[i],ptrLanguage[i],NSILOCALE_MAX_ACCEPT_LENGTH);
     323             :     }
     324             : 
     325             :   } else {
     326             :     /* simple case: no quality values */
     327             : 
     328           0 :     cPtr = nsCRT::strtok(input.get(),",",&cPtr2);
     329           0 :     while (cPtr) {
     330           0 :       if (strlen(cPtr)<NSILOCALE_MAX_ACCEPT_LENGTH) {        /* ignore if too long */
     331           0 :         PL_strncpyz(acceptLanguageList[countLang++],cPtr,NSILOCALE_MAX_ACCEPT_LENGTH);
     332           0 :         if (countLang>=NSILOCALE_MAX_ACCEPT_LENGTH) break; /* quit if too many */
     333             :       }
     334           0 :       cPtr = nsCRT::strtok(cPtr2,",",&cPtr2);
     335             :     }
     336             :   }
     337             : 
     338             :   //
     339             :   // now create the locale
     340             :   //
     341           0 :   result = NS_ERROR_FAILURE;
     342           0 :   if (countLang>0) {
     343           0 :           result = NewLocale(NS_ConvertASCIItoUTF16(acceptLanguageList[0]), _retval);
     344             :   }
     345             : 
     346             :   //
     347             :   // clean up
     348             :   //
     349           0 :   return result;
     350             : }
     351             : 
     352             : 
     353             : nsresult
     354           0 : nsLocaleService::GetLocaleComponentForUserAgent(nsAString& retval)
     355             : {
     356           0 :     nsCOMPtr<nsILocale>     system_locale;
     357             :     nsresult                result;
     358             : 
     359           0 :     result = GetSystemLocale(getter_AddRefs(system_locale));
     360           0 :     if (NS_SUCCEEDED(result))
     361             :     {
     362           0 :         result = system_locale->
     363           0 :                  GetCategory(NS_LITERAL_STRING(NSILOCALE_MESSAGE), retval);
     364           0 :         return result;
     365             :     }
     366             : 
     367           0 :     return result;
     368             : }
     369             : 
     370             : 
     371             : 
     372             : nsresult
     373           0 : NS_NewLocaleService(nsILocaleService** result)
     374             : {
     375           0 :   if(!result)
     376           0 :     return NS_ERROR_NULL_POINTER;
     377           0 :   *result = new nsLocaleService();
     378           0 :   if (! *result)
     379           0 :     return NS_ERROR_OUT_OF_MEMORY;
     380           0 :   NS_ADDREF(*result);
     381           0 :   return NS_OK;
     382             : }

Generated by: LCOV version 1.13