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/. */
7 #include "mozilla/ClearOnShutdown.h"
8 #include "mozilla/StaticPtr.h"
9 #include "mozilla/intl/Locale.h"
10 #include "nsTHashMap.h"
11 #include "nsPrintfCString.h"
13 using namespace mozilla
;
14 using namespace mozilla::intl
;
17 struct LangQuotesRec
{
22 #include "cldr-quotes.inc"
24 static StaticAutoPtr
<nsTHashMap
<nsCStringHashKey
, Quotes
>> sQuotesForLang
;
25 } // anonymous namespace
30 const Quotes
* QuotesForLang(const nsAtom
* aLang
) {
31 MOZ_ASSERT(NS_IsMainThread());
33 // On first use, initialize the hashtable from our CLDR-derived data array.
34 if (!sQuotesForLang
) {
35 sQuotesForLang
= new nsTHashMap
<nsCStringHashKey
, Quotes
>(32);
36 ClearOnShutdown(&sQuotesForLang
);
37 for (const auto& i
: sLangQuotes
) {
38 const char* s
= i
.mLangs
;
40 while ((len
= strlen(s
))) {
41 sQuotesForLang
->InsertOrUpdate(nsDependentCString(s
, len
), i
.mQuotes
);
47 nsAtomCString
langStr(aLang
);
48 const Quotes
* entry
= sQuotesForLang
->Lookup(langStr
).DataPtrOrNull();
50 // Found an exact match for the requested lang.
54 // Try parsing lang as a Locale and canonicalizing the subtags, then see if
55 // we can match it with region or script subtags, if present, or just the
56 // primary language tag.
58 auto result
= LocaleParser::TryParse(langStr
, loc
);
62 if (loc
.Canonicalize().isErr()) {
65 if (loc
.Region().Present()) {
66 nsAutoCString langAndRegion
;
67 langAndRegion
.Append(loc
.Language().Span());
68 langAndRegion
.Append('-');
69 langAndRegion
.Append(loc
.Region().Span());
70 if ((entry
= sQuotesForLang
->Lookup(langAndRegion
).DataPtrOrNull())) {
74 if (loc
.Script().Present()) {
75 nsAutoCString langAndScript
;
76 langAndScript
.Append(loc
.Language().Span());
77 langAndScript
.Append('-');
78 langAndScript
.Append(loc
.Script().Span());
79 if ((entry
= sQuotesForLang
->Lookup(langAndScript
).DataPtrOrNull())) {
83 Span
<const char> langAsSpan
= loc
.Language().Span();
84 nsAutoCString
lang(langAsSpan
.data(), langAsSpan
.size());
85 if ((entry
= sQuotesForLang
->Lookup(lang
).DataPtrOrNull())) {
93 } // namespace mozilla