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

Side by Side Diff: chrome_frame/simple_resource_loader.cc

Issue 126143005: Remove Chrome Frame code and resources. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: sync to r244038 Created 6 years, 11 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/smoke_test.bat » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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_frame/simple_resource_loader.h"
6
7 #include <atlbase.h>
8
9 #include <algorithm>
10
11 #include "base/base_paths.h"
12 #include "base/file_util.h"
13 #include "base/files/file_path.h"
14 #include "base/i18n/rtl.h"
15 #include "base/memory/singleton.h"
16 #include "base/path_service.h"
17 #include "base/strings/string_util.h"
18 #include "base/strings/utf_string_conversions.h"
19 #include "base/win/i18n.h"
20 #include "base/win/windows_version.h"
21 #include "chrome_frame/policy_settings.h"
22 #include "ui/base/resource/data_pack.h"
23
24 namespace {
25
26 const wchar_t kLocalesDirName[] = L"Locales";
27
28 bool IsInvalidTagCharacter(wchar_t tag_character) {
29 return !(L'-' == tag_character ||
30 IsAsciiDigit(tag_character) ||
31 IsAsciiAlpha(tag_character));
32 }
33
34 // A helper function object that performs a lower-case ASCII comparison between
35 // two strings.
36 class CompareInsensitiveASCII
37 : public std::unary_function<const std::wstring&, bool> {
38 public:
39 explicit CompareInsensitiveASCII(const std::wstring& value)
40 : value_lowered_(WideToASCII(value)) {
41 StringToLowerASCII(&value_lowered_);
42 }
43 bool operator()(const std::wstring& comparand) {
44 return LowerCaseEqualsASCII(comparand, value_lowered_.c_str());
45 }
46
47 private:
48 std::string value_lowered_;
49 };
50
51 // Returns true if the value was added.
52 bool PushBackIfAbsent(
53 const std::wstring& value,
54 std::vector<std::wstring>* collection) {
55 if (collection->end() ==
56 std::find_if(collection->begin(), collection->end(),
57 CompareInsensitiveASCII(value))) {
58 collection->push_back(value);
59 return true;
60 }
61 return false;
62 }
63
64 // Returns true if the collection is modified.
65 bool PushBackWithFallbackIfAbsent(
66 const std::wstring& language,
67 std::vector<std::wstring>* collection) {
68 bool modified = false;
69
70 if (!language.empty()) {
71 // Try adding the language itself.
72 modified = PushBackIfAbsent(language, collection);
73
74 // Now try adding its fallback, if it has one.
75 std::wstring::size_type dash_pos = language.find(L'-');
76 if (0 < dash_pos && language.size() - 1 > dash_pos)
77 modified |= PushBackIfAbsent(language.substr(0, dash_pos), collection);
78 }
79
80 return modified;
81 }
82
83 } // namespace
84
85 SimpleResourceLoader::SimpleResourceLoader()
86 : data_pack_(NULL),
87 locale_dll_handle_(NULL) {
88 // Find and load the resource DLL.
89 std::vector<std::wstring> language_tags;
90
91 // First, try the locale dictated by policy and its fallback.
92 PushBackWithFallbackIfAbsent(
93 PolicySettings::GetInstance()->ApplicationLocale(),
94 &language_tags);
95
96 // Next, try the thread, process, user, system languages.
97 GetPreferredLanguages(&language_tags);
98
99 // Finally, fall-back on "en-US" (which may already be present in the vector,
100 // but that's okay since we'll exit with success when the first is tried).
101 language_tags.push_back(L"en-US");
102
103 base::FilePath locales_path;
104
105 DetermineLocalesDirectory(&locales_path);
106 if (!LoadLocalePack(language_tags, locales_path, &locale_dll_handle_,
107 &data_pack_, &language_)) {
108 NOTREACHED() << "Failed loading any resource dll (even \"en-US\").";
109 }
110 }
111
112 SimpleResourceLoader::~SimpleResourceLoader() {
113 delete data_pack_;
114 }
115
116 // static
117 SimpleResourceLoader* SimpleResourceLoader::GetInstance() {
118 return Singleton<SimpleResourceLoader>::get();
119 }
120
121 // static
122 void SimpleResourceLoader::GetPreferredLanguages(
123 std::vector<std::wstring>* language_tags) {
124 DCHECK(language_tags);
125 // The full set of preferred languages and their fallbacks are given priority.
126 std::vector<std::wstring> languages;
127 if (base::win::i18n::GetThreadPreferredUILanguageList(&languages)) {
128 for (std::vector<std::wstring>::const_iterator scan = languages.begin(),
129 end = languages.end(); scan != end; ++scan) {
130 PushBackIfAbsent(*scan, language_tags);
131 }
132 }
133 // Use the base i18n routines (i.e., ICU) as a last, best hope for something
134 // meaningful for the user.
135 PushBackWithFallbackIfAbsent(base::ASCIIToWide(
136 base::i18n::GetConfiguredLocale()),
137 language_tags);
138 }
139
140 // static
141 void SimpleResourceLoader::DetermineLocalesDirectory(
142 base::FilePath* locales_path) {
143 DCHECK(locales_path);
144
145 base::FilePath module_path;
146 PathService::Get(base::DIR_MODULE, &module_path);
147 *locales_path = module_path.Append(kLocalesDirName);
148
149 // We may be residing in the "locales" directory's parent, or we might be
150 // in a sibling directory. Move up one and look for Locales again in the
151 // latter case.
152 if (!base::DirectoryExists(*locales_path)) {
153 *locales_path = module_path.DirName();
154 *locales_path = locales_path->Append(kLocalesDirName);
155 }
156
157 // Don't make a second check to see if the dir is in the parent. We'll notice
158 // and log that in LoadLocaleDll when we actually try loading DLLs.
159 }
160
161 // static
162 bool SimpleResourceLoader::IsValidLanguageTag(
163 const std::wstring& language_tag) {
164 // "[a-zA-Z]+(-[a-zA-Z0-9]+)*" is a simplification, but better than nothing.
165 // Rather than pick up the weight of a regex processor, just search for a
166 // character that isn't in the above set. This will at least weed out
167 // attempts at "../../EvilBinary".
168 return language_tag.end() == std::find_if(language_tag.begin(),
169 language_tag.end(),
170 &IsInvalidTagCharacter);
171 }
172
173 // static
174 bool SimpleResourceLoader::LoadLocalePack(
175 const std::vector<std::wstring>& language_tags,
176 const base::FilePath& locales_path,
177 HMODULE* dll_handle,
178 ui::DataPack** data_pack,
179 std::wstring* language) {
180 DCHECK(language);
181
182 // The dll should only have resources, not executable code.
183 const DWORD load_flags =
184 (base::win::GetVersion() >= base::win::VERSION_VISTA ?
185 LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE | LOAD_LIBRARY_AS_IMAGE_RESOURCE :
186 DONT_RESOLVE_DLL_REFERENCES);
187
188 const std::wstring dll_suffix(L".dll");
189 const std::wstring pack_suffix(L".pak");
190
191 bool found_pack = false;
192
193 for (std::vector<std::wstring>::const_iterator scan = language_tags.begin(),
194 end = language_tags.end();
195 scan != end;
196 ++scan) {
197 if (!IsValidLanguageTag(*scan)) {
198 LOG(WARNING) << "Invalid language tag supplied while locating resources:"
199 " \"" << *scan << "\"";
200 continue;
201 }
202
203 // Attempt to load both the resource pack and the dll. We return success
204 // only we load both.
205 base::FilePath resource_pack_path =
206 locales_path.Append(*scan + pack_suffix);
207 base::FilePath dll_path = locales_path.Append(*scan + dll_suffix);
208
209 if (base::PathExists(resource_pack_path) &&
210 base::PathExists(dll_path)) {
211 scoped_ptr<ui::DataPack> cur_data_pack(
212 new ui::DataPack(ui::SCALE_FACTOR_100P));
213 if (!cur_data_pack->LoadFromPath(resource_pack_path))
214 continue;
215
216 HMODULE locale_dll_handle = LoadLibraryEx(dll_path.value().c_str(), NULL,
217 load_flags);
218 if (locale_dll_handle) {
219 *dll_handle = locale_dll_handle;
220 *language = dll_path.BaseName().RemoveExtension().value();
221 *data_pack = cur_data_pack.release();
222 found_pack = true;
223 break;
224 } else {
225 *data_pack = NULL;
226 }
227 }
228 }
229 DCHECK(found_pack || base::DirectoryExists(locales_path))
230 << "Could not locate locales DLL directory.";
231 return found_pack;
232 }
233
234 std::wstring SimpleResourceLoader::GetLocalizedResource(int message_id) {
235 if (!data_pack_) {
236 DLOG(ERROR) << "locale resources are not loaded";
237 return std::wstring();
238 }
239
240 DCHECK(IS_INTRESOURCE(message_id));
241
242 base::StringPiece data;
243 if (!data_pack_->GetStringPiece(message_id, &data)) {
244 DLOG(ERROR) << "Unable to find string for resource id:" << message_id;
245 return std::wstring();
246 }
247
248 // Data pack encodes strings as either UTF8 or UTF16.
249 base::string16 msg;
250 if (data_pack_->GetTextEncodingType() == ui::DataPack::UTF16) {
251 msg = base::string16(reinterpret_cast<const base::char16*>(data.data()),
252 data.length() / 2);
253 } else if (data_pack_->GetTextEncodingType() == ui::DataPack::UTF8) {
254 msg = base::UTF8ToUTF16(data);
255 }
256 return msg;
257 }
258
259 // static
260 std::wstring SimpleResourceLoader::GetLanguage() {
261 return SimpleResourceLoader::GetInstance()->language_;
262 }
263
264 // static
265 std::wstring SimpleResourceLoader::Get(int message_id) {
266 SimpleResourceLoader* loader = SimpleResourceLoader::GetInstance();
267 return loader->GetLocalizedResource(message_id);
268 }
269
270 HMODULE SimpleResourceLoader::GetResourceModuleHandle() {
271 return locale_dll_handle_;
272 }
OLDNEW
« no previous file with comments | « chrome_frame/simple_resource_loader.h ('k') | chrome_frame/smoke_test.bat » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698