Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(91)

Side by Side Diff: chrome_frame/simple_resource_loader.cc

Issue 7763006: Load both language packs and the resource dlls in ChromeFrame and look for localized strings (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome_frame/simple_resource_loader.h ('k') | chrome_frame/test/simple_resource_loader_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome_frame/simple_resource_loader.h" 5 #include "chrome_frame/simple_resource_loader.h"
6 6
7 #include <atlbase.h> 7 #include <atlbase.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 10
11 #include "base/base_paths.h" 11 #include "base/base_paths.h"
12 #include "base/file_path.h" 12 #include "base/file_path.h"
13 #include "base/file_util.h" 13 #include "base/file_util.h"
14 #include "base/path_service.h" 14 #include "base/path_service.h"
15 #include "base/i18n/rtl.h" 15 #include "base/i18n/rtl.h"
16 #include "base/memory/singleton.h" 16 #include "base/memory/singleton.h"
17 #include "base/string_util.h" 17 #include "base/string_util.h"
18 #include "base/utf_string_conversions.h" 18 #include "base/utf_string_conversions.h"
19 #include "base/win/i18n.h" 19 #include "base/win/i18n.h"
20 #include "base/win/windows_version.h" 20 #include "base/win/windows_version.h"
21
22 #include "chrome_frame/policy_settings.h" 21 #include "chrome_frame/policy_settings.h"
22 #include "ui/base/resource/data_pack.h"
23 #include "ui/base/resource/resource_bundle.h"
23 24
24 namespace { 25 namespace {
25 26
26 const wchar_t kLocalesDirName[] = L"Locales"; 27 const wchar_t kLocalesDirName[] = L"Locales";
27 28
28 bool IsInvalidTagCharacter(wchar_t tag_character) { 29 bool IsInvalidTagCharacter(wchar_t tag_character) {
29 return !(L'-' == tag_character || 30 return !(L'-' == tag_character ||
30 IsAsciiDigit(tag_character) || 31 IsAsciiDigit(tag_character) ||
31 IsAsciiAlpha(tag_character)); 32 IsAsciiAlpha(tag_character));
32 } 33 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 if (0 < dash_pos && language.size() - 1 > dash_pos) 77 if (0 < dash_pos && language.size() - 1 > dash_pos)
77 modified |= PushBackIfAbsent(language.substr(0, dash_pos), collection); 78 modified |= PushBackIfAbsent(language.substr(0, dash_pos), collection);
78 } 79 }
79 80
80 return modified; 81 return modified;
81 } 82 }
82 83
83 } // namespace 84 } // namespace
84 85
85 SimpleResourceLoader::SimpleResourceLoader() 86 SimpleResourceLoader::SimpleResourceLoader()
86 : locale_dll_handle_(NULL) { 87 : data_pack_(NULL),
88 locale_dll_handle_(NULL) {
87 // Find and load the resource DLL. 89 // Find and load the resource DLL.
88 std::vector<std::wstring> language_tags; 90 std::vector<std::wstring> language_tags;
89 91
90 // First, try the locale dictated by policy and its fallback. 92 // First, try the locale dictated by policy and its fallback.
91 PushBackWithFallbackIfAbsent( 93 PushBackWithFallbackIfAbsent(
92 PolicySettings::GetInstance()->ApplicationLocale(), 94 PolicySettings::GetInstance()->ApplicationLocale(),
93 &language_tags); 95 &language_tags);
94 96
95 // Next, try the thread, process, user, system languages. 97 // Next, try the thread, process, user, system languages.
96 GetPreferredLanguages(&language_tags); 98 GetPreferredLanguages(&language_tags);
97 99
98 // Finally, fall-back on "en-US" (which may already be present in the vector, 100 // Finally, fall-back on "en-US" (which may already be present in the vector,
99 // but that's okay since we'll exit with success when the first is tried). 101 // but that's okay since we'll exit with success when the first is tried).
100 language_tags.push_back(L"en-US"); 102 language_tags.push_back(L"en-US");
101 103
102 FilePath locales_path; 104 FilePath locales_path;
103 FilePath locale_dll_path;
104 105
105 DetermineLocalesDirectory(&locales_path); 106 DetermineLocalesDirectory(&locales_path);
106 if (LoadLocaleDll(language_tags, locales_path, &locale_dll_handle_, 107 if (!LoadLocalePack(language_tags, locales_path, &locale_dll_handle_,
107 &locale_dll_path)) { 108 &data_pack_, &language_)) {
108 language_ = locale_dll_path.BaseName().RemoveExtension().value();
109 } else {
110 NOTREACHED() << "Failed loading any resource dll (even \"en-US\")."; 109 NOTREACHED() << "Failed loading any resource dll (even \"en-US\").";
111 } 110 }
112 } 111 }
113 112
114 SimpleResourceLoader::~SimpleResourceLoader() { 113 SimpleResourceLoader::~SimpleResourceLoader() {
115 locale_dll_handle_ = NULL; 114 delete data_pack_;
116 } 115 }
117 116
118 // static 117 // static
119 SimpleResourceLoader* SimpleResourceLoader::GetInstance() { 118 SimpleResourceLoader* SimpleResourceLoader::GetInstance() {
120 return Singleton<SimpleResourceLoader>::get(); 119 return Singleton<SimpleResourceLoader>::get();
121 } 120 }
122 121
123 // static 122 // static
124 void SimpleResourceLoader::GetPreferredLanguages( 123 void SimpleResourceLoader::GetPreferredLanguages(
125 std::vector<std::wstring>* language_tags) { 124 std::vector<std::wstring>* language_tags) {
126 DCHECK(language_tags); 125 DCHECK(language_tags);
127 // The full set of preferred languages and their fallbacks are given priority. 126 // The full set of preferred languages and their fallbacks are given priority.
128 std::vector<std::wstring> languages; 127 std::vector<std::wstring> languages;
129 if (base::win::i18n::GetThreadPreferredUILanguageList(&languages)) { 128 if (base::win::i18n::GetThreadPreferredUILanguageList(&languages)) {
130 for (std::vector<std::wstring>::const_iterator scan = languages.begin(), 129 for (std::vector<std::wstring>::const_iterator scan = languages.begin(),
131 end = languages.end(); scan != end; ++scan) { 130 end = languages.end(); scan != end; ++scan) {
132 PushBackIfAbsent(*scan, language_tags); 131 PushBackIfAbsent(*scan, language_tags);
133 } 132 }
134 } 133 }
135
136 // Use the base i18n routines (i.e., ICU) as a last, best hope for something 134 // Use the base i18n routines (i.e., ICU) as a last, best hope for something
137 // meaningful for the user. 135 // meaningful for the user.
138 PushBackWithFallbackIfAbsent(ASCIIToWide(base::i18n::GetConfiguredLocale()), 136 PushBackWithFallbackIfAbsent(ASCIIToWide(base::i18n::GetConfiguredLocale()),
139 language_tags); 137 language_tags);
140 } 138 }
141 139
142 // static 140 // static
143 void SimpleResourceLoader::DetermineLocalesDirectory(FilePath* locales_path) { 141 void SimpleResourceLoader::DetermineLocalesDirectory(FilePath* locales_path) {
144 DCHECK(locales_path); 142 DCHECK(locales_path);
145 143
(...skipping 19 matching lines...) Expand all
165 // "[a-zA-Z]+(-[a-zA-Z0-9]+)*" is a simplification, but better than nothing. 163 // "[a-zA-Z]+(-[a-zA-Z0-9]+)*" is a simplification, but better than nothing.
166 // Rather than pick up the weight of a regex processor, just search for a 164 // Rather than pick up the weight of a regex processor, just search for a
167 // character that isn't in the above set. This will at least weed out 165 // character that isn't in the above set. This will at least weed out
168 // attempts at "../../EvilBinary". 166 // attempts at "../../EvilBinary".
169 return language_tag.end() == std::find_if(language_tag.begin(), 167 return language_tag.end() == std::find_if(language_tag.begin(),
170 language_tag.end(), 168 language_tag.end(),
171 &IsInvalidTagCharacter); 169 &IsInvalidTagCharacter);
172 } 170 }
173 171
174 // static 172 // static
175 bool SimpleResourceLoader::LoadLocaleDll( 173 bool SimpleResourceLoader::LoadLocalePack(
176 const std::vector<std::wstring>& language_tags, 174 const std::vector<std::wstring>& language_tags,
177 const FilePath& locales_path, 175 const FilePath& locales_path,
178 HMODULE* dll_handle, 176 HMODULE* dll_handle,
179 FilePath* file_path) { 177 ui::DataPack** data_pack,
180 DCHECK(file_path); 178 std::wstring* language) {
179 DCHECK(language);
181 180
182 // The dll should only have resources, not executable code. 181 // The dll should only have resources, not executable code.
183 const DWORD load_flags = 182 const DWORD load_flags =
184 (base::win::GetVersion() >= base::win::VERSION_VISTA ? 183 (base::win::GetVersion() >= base::win::VERSION_VISTA ?
185 LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE | LOAD_LIBRARY_AS_IMAGE_RESOURCE : 184 LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE | LOAD_LIBRARY_AS_IMAGE_RESOURCE :
186 DONT_RESOLVE_DLL_REFERENCES); 185 DONT_RESOLVE_DLL_REFERENCES);
186
187 const std::wstring dll_suffix(L".dll"); 187 const std::wstring dll_suffix(L".dll");
188 bool found_dll = false; 188 const std::wstring pack_suffix(L".pak");
189
190 bool found_pack = false;
189 191
190 for (std::vector<std::wstring>::const_iterator scan = language_tags.begin(), 192 for (std::vector<std::wstring>::const_iterator scan = language_tags.begin(),
191 end = language_tags.end(); 193 end = language_tags.end();
192 scan != end; 194 scan != end;
193 ++scan) { 195 ++scan) {
194 if (!IsValidLanguageTag(*scan)) { 196 if (!IsValidLanguageTag(*scan)) {
195 LOG(WARNING) << "Invalid language tag supplied while locating resources:" 197 LOG(WARNING) << "Invalid language tag supplied while locating resources:"
196 " \"" << *scan << "\""; 198 " \"" << *scan << "\"";
197 continue; 199 continue;
198 } 200 }
199 FilePath look_path = locales_path.Append(*scan + dll_suffix); 201
200 HMODULE locale_dll_handle = LoadLibraryEx(look_path.value().c_str(), NULL, 202 // Attempt to load both the resource pack and the dll. We return success
201 load_flags); 203 // only we load both.
202 if (NULL != locale_dll_handle) { 204 FilePath resource_pack_path = locales_path.Append(*scan + pack_suffix);
203 *dll_handle = locale_dll_handle; 205 FilePath dll_path = locales_path.Append(*scan + dll_suffix);
204 *file_path = look_path; 206
205 found_dll = true; 207 if (file_util::PathExists(resource_pack_path) &&
206 break; 208 file_util::PathExists(dll_path)) {
209 *data_pack = ui::ResourceBundle::LoadResourcesDataPak(resource_pack_path);
210 if (!*data_pack) {
211 continue;
212 }
213 HMODULE locale_dll_handle = LoadLibraryEx(dll_path.value().c_str(), NULL,
214 load_flags);
215 if (locale_dll_handle) {
216 *dll_handle = locale_dll_handle;
217 *language = dll_path.BaseName().RemoveExtension().value();
218 found_pack = true;
219 break;
220 } else {
221 *data_pack = NULL;
222 }
207 } 223 }
208 DPCHECK(ERROR_FILE_NOT_FOUND == GetLastError())
209 << "Unable to load generated resources from " << look_path.value();
210 } 224 }
211 225 DCHECK(found_pack || file_util::DirectoryExists(locales_path))
212 DCHECK(found_dll || file_util::DirectoryExists(locales_path))
213 << "Could not locate locales DLL directory."; 226 << "Could not locate locales DLL directory.";
214 227 return found_pack;
215 return found_dll;
216 } 228 }
217 229
218 std::wstring SimpleResourceLoader::GetLocalizedResource(int message_id) { 230 std::wstring SimpleResourceLoader::GetLocalizedResource(int message_id) {
219 if (!locale_dll_handle_) { 231 if (!data_pack_) {
220 DLOG(ERROR) << "locale resources are not loaded"; 232 DLOG(ERROR) << "locale resources are not loaded";
221 return std::wstring(); 233 return std::wstring();
222 } 234 }
223 235
224 DCHECK(IS_INTRESOURCE(message_id)); 236 DCHECK(IS_INTRESOURCE(message_id));
225 237
226 const ATLSTRINGRESOURCEIMAGE* image = AtlGetStringResourceImage( 238 base::StringPiece data;
227 locale_dll_handle_, message_id); 239 if (!data_pack_->GetStringPiece(message_id, &data)) {
228 if (!image) { 240 DLOG(ERROR) << "Unable to find string for resource id:" << message_id;
229 // Fall back on the current module (shouldn't be any strings here except 241 return std::wstring();
230 // in unittests).
231 image = AtlGetStringResourceImage(_AtlBaseModule.GetModuleInstance(),
232 message_id);
233 if (!image) {
234 NOTREACHED() << "unable to find resource: " << message_id;
235 return std::wstring();
236 }
237 } 242 }
238 return std::wstring(image->achString, image->nLength); 243
244 // Data pack encodes strings as UTF16.
245 DCHECK_EQ(data.length() % 2, 0U);
246 string16 msg(reinterpret_cast<const char16*>(data.data()),
247 data.length() / 2);
248 return msg;
239 } 249 }
240 250
241 // static 251 // static
242 std::wstring SimpleResourceLoader::GetLanguage() { 252 std::wstring SimpleResourceLoader::GetLanguage() {
243 return SimpleResourceLoader::GetInstance()->language_; 253 return SimpleResourceLoader::GetInstance()->language_;
244 } 254 }
245 255
246 // static 256 // static
247 std::wstring SimpleResourceLoader::Get(int message_id) { 257 std::wstring SimpleResourceLoader::Get(int message_id) {
248 SimpleResourceLoader* loader = SimpleResourceLoader::GetInstance(); 258 SimpleResourceLoader* loader = SimpleResourceLoader::GetInstance();
249 return loader->GetLocalizedResource(message_id); 259 return loader->GetLocalizedResource(message_id);
250 } 260 }
251 261
252 HMODULE SimpleResourceLoader::GetResourceModuleHandle() { 262 HMODULE SimpleResourceLoader::GetResourceModuleHandle() {
253 return locale_dll_handle_; 263 return locale_dll_handle_;
254 } 264 }
OLDNEW
« no previous file with comments | « chrome_frame/simple_resource_loader.h ('k') | chrome_frame/test/simple_resource_loader_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698