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

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
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/resource_bundle.h"
23 23
24 namespace { 24 namespace {
25 25
26 const wchar_t kLocalesDirName[] = L"Locales"; 26 const wchar_t kLocalesDirName[] = L"Locales";
27 27
28 bool IsInvalidTagCharacter(wchar_t tag_character) { 28 bool IsInvalidTagCharacter(wchar_t tag_character) {
29 return !(L'-' == tag_character || 29 return !(L'-' == tag_character ||
30 IsAsciiDigit(tag_character) || 30 IsAsciiDigit(tag_character) ||
31 IsAsciiAlpha(tag_character)); 31 IsAsciiAlpha(tag_character));
32 } 32 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 if (0 < dash_pos && language.size() - 1 > dash_pos) 76 if (0 < dash_pos && language.size() - 1 > dash_pos)
77 modified |= PushBackIfAbsent(language.substr(0, dash_pos), collection); 77 modified |= PushBackIfAbsent(language.substr(0, dash_pos), collection);
78 } 78 }
79 79
80 return modified; 80 return modified;
81 } 81 }
82 82
83 } // namespace 83 } // namespace
84 84
85 SimpleResourceLoader::SimpleResourceLoader() 85 SimpleResourceLoader::SimpleResourceLoader()
86 : locale_dll_handle_(NULL) { 86 : data_pack_(NULL),
87 locale_dll_handle_(NULL) {
87 // Find and load the resource DLL. 88 // Find and load the resource DLL.
88 std::vector<std::wstring> language_tags; 89 std::vector<std::wstring> language_tags;
89 90
90 // First, try the locale dictated by policy and its fallback. 91 // First, try the locale dictated by policy and its fallback.
91 PushBackWithFallbackIfAbsent( 92 PushBackWithFallbackIfAbsent(
92 PolicySettings::GetInstance()->ApplicationLocale(), 93 PolicySettings::GetInstance()->ApplicationLocale(),
93 &language_tags); 94 &language_tags);
94 95
95 // Next, try the thread, process, user, system languages. 96 // Next, try the thread, process, user, system languages.
96 GetPreferredLanguages(&language_tags); 97 GetPreferredLanguages(&language_tags);
97 98
98 // Finally, fall-back on "en-US" (which may already be present in the vector, 99 // 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). 100 // but that's okay since we'll exit with success when the first is tried).
100 language_tags.push_back(L"en-US"); 101 language_tags.push_back(L"en-US");
101 102
102 FilePath locales_path; 103 FilePath locales_path;
103 FilePath locale_dll_path; 104 FilePath locale_pack_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_, &locale_pack_path)) {
tony 2011/08/26 21:36:30 Nit: Maybe we should just return the language as a
ananta 2011/08/26 21:50:17 Done.
108 language_ = locale_dll_path.BaseName().RemoveExtension().value(); 109 language_ = locale_pack_path.BaseName().RemoveExtension().value();
109 } else { 110 } else {
110 NOTREACHED() << "Failed loading any resource dll (even \"en-US\")."; 111 NOTREACHED() << "Failed loading any resource dll (even \"en-US\").";
111 } 112 }
112 } 113 }
113 114
114 SimpleResourceLoader::~SimpleResourceLoader() { 115 SimpleResourceLoader::~SimpleResourceLoader() {
115 locale_dll_handle_ = NULL; 116 delete data_pack_;
116 } 117 }
117 118
118 // static 119 // static
119 SimpleResourceLoader* SimpleResourceLoader::GetInstance() { 120 SimpleResourceLoader* SimpleResourceLoader::GetInstance() {
120 return Singleton<SimpleResourceLoader>::get(); 121 return Singleton<SimpleResourceLoader>::get();
121 } 122 }
122 123
123 // static 124 // static
124 void SimpleResourceLoader::GetPreferredLanguages( 125 void SimpleResourceLoader::GetPreferredLanguages(
125 std::vector<std::wstring>* language_tags) { 126 std::vector<std::wstring>* language_tags) {
126 DCHECK(language_tags); 127 DCHECK(language_tags);
127 // The full set of preferred languages and their fallbacks are given priority. 128 // The full set of preferred languages and their fallbacks are given priority.
128 std::vector<std::wstring> languages; 129 std::vector<std::wstring> languages;
129 if (base::win::i18n::GetThreadPreferredUILanguageList(&languages)) { 130 if (base::win::i18n::GetThreadPreferredUILanguageList(&languages)) {
130 for (std::vector<std::wstring>::const_iterator scan = languages.begin(), 131 for (std::vector<std::wstring>::const_iterator scan = languages.begin(),
131 end = languages.end(); scan != end; ++scan) { 132 end = languages.end(); scan != end; ++scan) {
132 PushBackIfAbsent(*scan, language_tags); 133 PushBackIfAbsent(*scan, language_tags);
133 } 134 }
134 } 135 }
135
136 // Use the base i18n routines (i.e., ICU) as a last, best hope for something 136 // Use the base i18n routines (i.e., ICU) as a last, best hope for something
137 // meaningful for the user. 137 // meaningful for the user.
138 PushBackWithFallbackIfAbsent(ASCIIToWide(base::i18n::GetConfiguredLocale()), 138 PushBackWithFallbackIfAbsent(ASCIIToWide(base::i18n::GetConfiguredLocale()),
139 language_tags); 139 language_tags);
140 } 140 }
141 141
142 // static 142 // static
143 void SimpleResourceLoader::DetermineLocalesDirectory(FilePath* locales_path) { 143 void SimpleResourceLoader::DetermineLocalesDirectory(FilePath* locales_path) {
144 DCHECK(locales_path); 144 DCHECK(locales_path);
145 145
(...skipping 19 matching lines...) Expand all
165 // "[a-zA-Z]+(-[a-zA-Z0-9]+)*" is a simplification, but better than nothing. 165 // "[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 166 // 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 167 // character that isn't in the above set. This will at least weed out
168 // attempts at "../../EvilBinary". 168 // attempts at "../../EvilBinary".
169 return language_tag.end() == std::find_if(language_tag.begin(), 169 return language_tag.end() == std::find_if(language_tag.begin(),
170 language_tag.end(), 170 language_tag.end(),
171 &IsInvalidTagCharacter); 171 &IsInvalidTagCharacter);
172 } 172 }
173 173
174 // static 174 // static
175 bool SimpleResourceLoader::LoadLocaleDll( 175 bool SimpleResourceLoader::LoadLocalePack(
176 const std::vector<std::wstring>& language_tags, 176 const std::vector<std::wstring>& language_tags,
177 const FilePath& locales_path, 177 const FilePath& locales_path,
178 HMODULE* dll_handle, 178 HMODULE* dll_handle,
179 ui::DataPack** data_pack,
179 FilePath* file_path) { 180 FilePath* file_path) {
180 DCHECK(file_path); 181 DCHECK(file_path);
181 182
182 // The dll should only have resources, not executable code. 183 // The dll should only have resources, not executable code.
183 const DWORD load_flags = 184 const DWORD load_flags =
184 (base::win::GetVersion() >= base::win::VERSION_VISTA ? 185 (base::win::GetVersion() >= base::win::VERSION_VISTA ?
185 LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE | LOAD_LIBRARY_AS_IMAGE_RESOURCE : 186 LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE | LOAD_LIBRARY_AS_IMAGE_RESOURCE :
186 DONT_RESOLVE_DLL_REFERENCES); 187 DONT_RESOLVE_DLL_REFERENCES);
188
187 const std::wstring dll_suffix(L".dll"); 189 const std::wstring dll_suffix(L".dll");
188 bool found_dll = false; 190 const std::wstring pack_suffix(L".pak");
191
192 bool found_pack = false;
189 193
190 for (std::vector<std::wstring>::const_iterator scan = language_tags.begin(), 194 for (std::vector<std::wstring>::const_iterator scan = language_tags.begin(),
191 end = language_tags.end(); 195 end = language_tags.end();
192 scan != end; 196 scan != end;
193 ++scan) { 197 ++scan) {
194 if (!IsValidLanguageTag(*scan)) { 198 if (!IsValidLanguageTag(*scan)) {
195 LOG(WARNING) << "Invalid language tag supplied while locating resources:" 199 LOG(WARNING) << "Invalid language tag supplied while locating resources:"
196 " \"" << *scan << "\""; 200 " \"" << *scan << "\"";
197 continue; 201 continue;
198 } 202 }
199 FilePath look_path = locales_path.Append(*scan + dll_suffix); 203
200 HMODULE locale_dll_handle = LoadLibraryEx(look_path.value().c_str(), NULL, 204 // Attempt to load both the resource pack and the dll. We return success
201 load_flags); 205 // only we load both.
202 if (NULL != locale_dll_handle) { 206 FilePath resource_pack_path = locales_path.Append(*scan + pack_suffix);
203 *dll_handle = locale_dll_handle; 207 FilePath dll_path = locales_path.Append(*scan + dll_suffix);
204 *file_path = look_path; 208
205 found_dll = true; 209 if (file_util::PathExists(resource_pack_path) &&
206 break; 210 file_util::PathExists(dll_path)) {
211 *data_pack = ui::ResourceBundle::LoadResourcesDataPak(resource_pack_path);
212 if (!*data_pack) {
213 continue;
214 }
215 HMODULE locale_dll_handle = LoadLibraryEx(dll_path.value().c_str(), NULL,
216 load_flags);
217 if (locale_dll_handle) {
218 *dll_handle = locale_dll_handle;
219 *file_path = dll_path;
220 found_pack = true;
221 break;
222 } else {
223 *data_pack = NULL;
224 }
207 } 225 }
208 DPCHECK(ERROR_FILE_NOT_FOUND == GetLastError())
209 << "Unable to load generated resources from " << look_path.value();
210 } 226 }
211 227 DCHECK(found_pack || file_util::DirectoryExists(locales_path))
212 DCHECK(found_dll || file_util::DirectoryExists(locales_path))
213 << "Could not locate locales DLL directory."; 228 << "Could not locate locales DLL directory.";
214 229 return found_pack;
215 return found_dll;
216 } 230 }
217 231
218 std::wstring SimpleResourceLoader::GetLocalizedResource(int message_id) { 232 std::wstring SimpleResourceLoader::GetLocalizedResource(int message_id) {
219 if (!locale_dll_handle_) { 233 if (!data_pack_) {
220 DLOG(ERROR) << "locale resources are not loaded"; 234 DLOG(ERROR) << "locale resources are not loaded";
221 return std::wstring(); 235 return std::wstring();
222 } 236 }
223 237
224 DCHECK(IS_INTRESOURCE(message_id)); 238 DCHECK(IS_INTRESOURCE(message_id));
225 239
226 const ATLSTRINGRESOURCEIMAGE* image = AtlGetStringResourceImage( 240 base::StringPiece data;
227 locale_dll_handle_, message_id); 241 if (!data_pack_->GetStringPiece(message_id, &data)) {
228 if (!image) { 242 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 243 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 } 244 }
238 return std::wstring(image->achString, image->nLength); 245
246 // Data pack encodes strings as UTF16.
247 DCHECK_EQ(data.length() % 2, 0U);
248 string16 msg(reinterpret_cast<const char16*>(data.data()),
249 data.length() / 2);
250 return msg;
239 } 251 }
240 252
241 // static 253 // static
242 std::wstring SimpleResourceLoader::GetLanguage() { 254 std::wstring SimpleResourceLoader::GetLanguage() {
243 return SimpleResourceLoader::GetInstance()->language_; 255 return SimpleResourceLoader::GetInstance()->language_;
244 } 256 }
245 257
246 // static 258 // static
247 std::wstring SimpleResourceLoader::Get(int message_id) { 259 std::wstring SimpleResourceLoader::Get(int message_id) {
248 SimpleResourceLoader* loader = SimpleResourceLoader::GetInstance(); 260 SimpleResourceLoader* loader = SimpleResourceLoader::GetInstance();
249 return loader->GetLocalizedResource(message_id); 261 return loader->GetLocalizedResource(message_id);
250 } 262 }
251 263
252 HMODULE SimpleResourceLoader::GetResourceModuleHandle() { 264 HMODULE SimpleResourceLoader::GetResourceModuleHandle() {
253 return locale_dll_handle_; 265 return locale_dll_handle_;
254 } 266 }
OLDNEW
« chrome_frame/simple_resource_loader.h ('K') | « chrome_frame/simple_resource_loader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698