EncodingToLang.cpp (2199B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 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 "mozilla/intl/EncodingToLang.h" 7 #include "nsGkAtoms.h" 8 #include "nsLanguageAtomService.h" 9 10 using namespace mozilla; 11 using namespace mozilla::intl; 12 13 // Parallel arrays of Encoding and corresponding Lang atoms, 14 // in rough order of frequency. 15 16 // Unfortunately, the `mozilla::NotNull` hack that was used to 17 // declare the encoding pointers in C++ does not allow putting 18 // the pointers in a static array without a run-time initializer, 19 // so our options are: 20 // 1. Putting the pointers in a static array in Rust, at a distance. 21 // 2. Run-time initializer. 22 // 3. Using pointer pointers, as seen here. 23 const mozilla::NotNull<const mozilla::Encoding*>* 24 EncodingToLang::kEncodingsByRoughFrequency[] = { 25 #define _(encoding, lang) &encoding, 26 #include "EncodingsByFrequency.inc" 27 #undef _ 28 }; 29 30 // This one isn't constant, as it gets adjusted during Initialize(). 31 // static 32 nsAtom* EncodingToLang::sLangs[] = { 33 #define _(encoding, lang) lang, 34 #include "EncodingsByFrequency.inc" 35 #undef _ 36 }; 37 38 // static 39 nsAtom* EncodingToLang::Lookup(NotNull<const mozilla::Encoding*> aEncoding) { 40 // Linear search should be fine, since in the vast, vast majority of cases, 41 // the search stops at the first or second item. 42 unsigned int i = 0; 43 for (; i < std::size(kEncodingsByRoughFrequency); i++) { 44 if (*kEncodingsByRoughFrequency[i] == aEncoding) { 45 return sLangs[i]; 46 } 47 } 48 MOZ_ASSERT(false, "The encoding is always supposed to be found in the array"); 49 return sLangs[0]; 50 } 51 52 // static 53 void EncodingToLang::Initialize() { 54 sLangs[0] = nsLanguageAtomService::GetService()->GetLocaleLanguage(); 55 // We logically hold a strong ref to the first occurrence 56 // and a non-owning pointer to the rest. 57 NS_ADDREF(sLangs[0]); 58 for (size_t i = 1; i < std::size(sLangs); ++i) { 59 if (!sLangs[i]) { 60 sLangs[i] = sLangs[0]; 61 } 62 } 63 } 64 65 // static 66 void EncodingToLang::Shutdown() { NS_RELEASE(sLangs[0]); }