DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Header

Mercurial (1aeaa33a64f9)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
/* -*- 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 "nsLanguageAtomService.h"
#include "nsUConvPropertySearch.h"
#include "nsUnicharUtils.h"
#include "nsAtom.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/Encoding.h"
#include "mozilla/intl/OSPreferences.h"
#include "mozilla/ServoBindings.h"

using namespace mozilla;
using mozilla::intl::OSPreferences;

static constexpr nsUConvProp encodingsGroups[] = {
#include "encodingsgroups.properties.h"
};

static constexpr nsUConvProp kLangGroups[] = {
#include "langGroups.properties.h"
};

// static
nsLanguageAtomService* nsLanguageAtomService::GetService() {
  static UniquePtr<nsLanguageAtomService> gLangAtomService;
  if (!gLangAtomService) {
    gLangAtomService = MakeUnique<nsLanguageAtomService>();
    ClearOnShutdown(&gLangAtomService);
  }
  return gLangAtomService.get();
}

nsAtom* nsLanguageAtomService::LookupLanguage(const nsACString& aLanguage) {
  nsAutoCString lowered(aLanguage);
  ToLowerCase(lowered);

  RefPtr<nsAtom> lang = NS_Atomize(lowered);
  return GetLanguageGroup(lang);
}

already_AddRefed<nsAtom> nsLanguageAtomService::LookupCharSet(
    NotNull<const Encoding*> aEncoding) {
  nsAutoCString charset;
  aEncoding->Name(charset);
  nsAutoCString group;
  if (NS_FAILED(nsUConvPropertySearch::SearchPropertyValue(
          encodingsGroups, ArrayLength(encodingsGroups), charset, group))) {
    return RefPtr<nsAtom>(nsGkAtoms::Unicode).forget();
  }
  return NS_Atomize(group);
}

nsAtom* nsLanguageAtomService::GetLocaleLanguage() {
  do {
    if (!mLocaleLanguage) {
      AutoTArray<nsCString, 10> regionalPrefsLocales;
      if (OSPreferences::GetInstance()->GetRegionalPrefsLocales(
              regionalPrefsLocales)) {
        // use lowercase for all language atoms
        ToLowerCase(regionalPrefsLocales[0]);
        mLocaleLanguage = NS_Atomize(regionalPrefsLocales[0]);
      } else {
        nsAutoCString locale;
        OSPreferences::GetInstance()->GetSystemLocale(locale);

        ToLowerCase(locale);  // use lowercase for all language atoms
        mLocaleLanguage = NS_Atomize(locale);
      }
    }
  } while (0);

  return mLocaleLanguage;
}

nsAtom* nsLanguageAtomService::GetLanguageGroup(nsAtom* aLanguage,
                                                bool* aNeedsToCache) {
  nsAtom* retVal = mLangToGroup.GetWeak(aLanguage);

  if (!retVal) {
    if (aNeedsToCache) {
      *aNeedsToCache = true;
      return nullptr;
    }
    RefPtr<nsAtom> uncached = GetUncachedLanguageGroup(aLanguage);
    retVal = uncached.get();

    AssertIsMainThreadOrServoLangFontPrefsCacheLocked();
    // The hashtable will keep an owning reference to the atom
    mLangToGroup.Put(aLanguage, uncached);
  }

  return retVal;
}

already_AddRefed<nsAtom> nsLanguageAtomService::GetUncachedLanguageGroup(
    nsAtom* aLanguage) const {
  nsAutoCString langStr;
  aLanguage->ToUTF8String(langStr);
  ToLowerCase(langStr);

  nsAutoCString langGroupStr;
  nsresult res = nsUConvPropertySearch::SearchPropertyValue(
      kLangGroups, ArrayLength(kLangGroups), langStr, langGroupStr);
  while (NS_FAILED(res)) {
    int32_t hyphen = langStr.RFindChar('-');
    if (hyphen <= 0) {
      langGroupStr.AssignLiteral("x-unicode");
      break;
    }
    langStr.Truncate(hyphen);
    res = nsUConvPropertySearch::SearchPropertyValue(
        kLangGroups, ArrayLength(kLangGroups), langStr, langGroupStr);
  }

  RefPtr<nsAtom> langGroup = NS_Atomize(langGroupStr);

  return langGroup.forget();
}