• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/common/spellcheck_common.h"
6 
7 #include "base/files/file_path.h"
8 #include "base/logging.h"
9 #include "third_party/icu/source/common/unicode/uloc.h"
10 
11 namespace chrome {
12 namespace spellcheck_common {
13 
14 struct LanguageRegion {
15   const char* language;  // The language.
16   const char* language_region;  // language & region, used by dictionaries.
17 };
18 
19 struct LanguageVersion {
20   const char* language;  // The language input.
21   const char* version;   // The corresponding version.
22 };
23 
24 static const LanguageRegion g_supported_spellchecker_languages[] = {
25   // Several languages are not to be included in the spellchecker list:
26   // th-TH, vi-VI.
27   {"af", "af-ZA"},
28   {"bg", "bg-BG"},
29   {"ca", "ca-ES"},
30   {"cs", "cs-CZ"},
31   {"da", "da-DK"},
32   {"de", "de-DE"},
33   {"el", "el-GR"},
34   {"en-AU", "en-AU"},
35   {"en-CA", "en-CA"},
36   {"en-GB", "en-GB"},
37   {"en-US", "en-US"},
38   {"es", "es-ES"},
39   {"et", "et-EE"},
40   {"fo", "fo-FO"},
41   {"fr", "fr-FR"},
42   {"he", "he-IL"},
43   {"hi", "hi-IN"},
44   {"hr", "hr-HR"},
45   {"hu", "hu-HU"},
46   {"id", "id-ID"},
47   {"it", "it-IT"},
48   {"ko", "ko"},
49   {"lt", "lt-LT"},
50   {"lv", "lv-LV"},
51   {"nb", "nb-NO"},
52   {"nl", "nl-NL"},
53   {"pl", "pl-PL"},
54   {"pt-BR", "pt-BR"},
55   {"pt-PT", "pt-PT"},
56   {"ro", "ro-RO"},
57   {"ru", "ru-RU"},
58   {"sh", "sh"},
59   {"sk", "sk-SK"},
60   {"sl", "sl-SI"},
61   {"sq", "sq"},
62   {"sr", "sr"},
63   {"sv", "sv-SE"},
64   {"ta", "ta-IN"},
65   {"tg", "tg-TG"},
66   {"tr", "tr-TR"},
67   {"uk", "uk-UA"},
68   {"vi", "vi-VN"},
69 };
70 
IsValidRegion(const std::string & region)71 bool IsValidRegion(const std::string& region) {
72   for (size_t i = 0; i < arraysize(g_supported_spellchecker_languages);
73        ++i) {
74     if (g_supported_spellchecker_languages[i].language_region == region)
75       return true;
76   }
77   return false;
78 }
79 
80 // This function returns the language-region version of language name.
81 // e.g. returns hi-IN for hi.
GetSpellCheckLanguageRegion(const std::string & input_language)82 std::string GetSpellCheckLanguageRegion(const std::string& input_language) {
83   for (size_t i = 0; i < arraysize(g_supported_spellchecker_languages);
84        ++i) {
85     if (g_supported_spellchecker_languages[i].language == input_language) {
86       return std::string(
87           g_supported_spellchecker_languages[i].language_region);
88     }
89   }
90 
91   return input_language;
92 }
93 
GetVersionedFileName(const std::string & input_language,const base::FilePath & dict_dir)94 base::FilePath GetVersionedFileName(const std::string& input_language,
95                                     const base::FilePath& dict_dir) {
96   // The default dictionary version is 3-0. This version indicates that the bdic
97   // file contains a checksum.
98   static const char kDefaultVersionString[] = "-3-0";
99 
100   // Add non-default version strings here. Use the same version for all the
101   // dictionaries that you add at the same time. Increment the major version
102   // number if you're updating either dic or aff files. Increment the minor
103   // version number if you're updating only dic_delta files.
104   static LanguageVersion special_version_string[] = {
105     {"tr-TR", "-4-0"},  // Jan 9, 2013: Add "FLAG num" to aff to avoid heapcheck
106                         // crash.
107     {"tg-TG", "-5-0"},  // Mar 4, 2014: Add Tajik dictionary.
108   };
109 
110   // Generate the bdict file name using default version string or special
111   // version string, depending on the language.
112   std::string language = GetSpellCheckLanguageRegion(input_language);
113   std::string versioned_bdict_file_name(language + kDefaultVersionString +
114                                         ".bdic");
115   for (size_t i = 0; i < arraysize(special_version_string); ++i) {
116     if (language == special_version_string[i].language) {
117       versioned_bdict_file_name =
118           language + special_version_string[i].version + ".bdic";
119       break;
120     }
121   }
122 
123   return dict_dir.AppendASCII(versioned_bdict_file_name);
124 }
125 
GetCorrespondingSpellCheckLanguage(const std::string & language)126 std::string GetCorrespondingSpellCheckLanguage(const std::string& language) {
127   // Look for exact match in the Spell Check language list.
128   for (size_t i = 0; i < arraysize(g_supported_spellchecker_languages);
129        ++i) {
130     // First look for exact match in the language region of the list.
131     std::string spellcheck_language(
132         g_supported_spellchecker_languages[i].language);
133     if (spellcheck_language == language)
134       return language;
135 
136     // Next, look for exact match in the language_region part of the list.
137     std::string spellcheck_language_region(
138         g_supported_spellchecker_languages[i].language_region);
139     if (spellcheck_language_region == language)
140       return g_supported_spellchecker_languages[i].language;
141   }
142 
143   // No match found - return blank.
144   return std::string();
145 }
146 
SpellCheckLanguages(std::vector<std::string> * languages)147 void SpellCheckLanguages(std::vector<std::string>* languages) {
148   for (size_t i = 0; i < arraysize(g_supported_spellchecker_languages);
149        ++i) {
150     languages->push_back(g_supported_spellchecker_languages[i].language);
151   }
152 }
153 
GetISOLanguageCountryCodeFromLocale(const std::string & locale,std::string * language_code,std::string * country_code)154 void GetISOLanguageCountryCodeFromLocale(const std::string& locale,
155                                          std::string* language_code,
156                                          std::string* country_code) {
157   DCHECK(language_code);
158   DCHECK(country_code);
159   char language[ULOC_LANG_CAPACITY] = ULOC_ENGLISH;
160   const char* country = "USA";
161   if (!locale.empty()) {
162     UErrorCode error = U_ZERO_ERROR;
163     char id[ULOC_LANG_CAPACITY + ULOC_SCRIPT_CAPACITY + ULOC_COUNTRY_CAPACITY];
164     uloc_addLikelySubtags(locale.c_str(), id, arraysize(id), &error);
165     error = U_ZERO_ERROR;
166     uloc_getLanguage(id, language, arraysize(language), &error);
167     country = uloc_getISO3Country(id);
168   }
169   *language_code = std::string(language);
170   *country_code = std::string(country);
171 }
172 
173 }  // namespace spellcheck_common
174 }  // namespace chrome
175