|
1 /* |
|
2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. |
|
3 * |
|
4 * Redistribution and use in source and binary forms, with or without |
|
5 * modification, are permitted provided that the following conditions |
|
6 * are met: |
|
7 * 1. Redistributions of source code must retain the above copyright |
|
8 * notice, this list of conditions and the following disclaimer. |
|
9 * 2. Redistributions in binary form must reproduce the above copyright |
|
10 * notice, this list of conditions and the following disclaimer in the |
|
11 * documentation and/or other materials provided with the distribution. |
|
12 * |
|
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |
|
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
|
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
|
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
|
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
|
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
|
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
24 */ |
|
25 |
|
26 #include "config.h" |
|
27 #include "WebKitDLL.h" |
|
28 |
|
29 #include "WebLocalizableStrings.h" |
|
30 |
|
31 #pragma warning(push, 0) |
|
32 #include <WebCore/PlatformString.h> |
|
33 #include <WebCore/StringHash.h> |
|
34 #pragma warning(pop) |
|
35 |
|
36 #include <WTF/Assertions.h> |
|
37 #include <WTF/HashMap.h> |
|
38 #include <CoreFoundation/CoreFoundation.h> |
|
39 |
|
40 using namespace WebCore; |
|
41 |
|
42 WebLocalizableStringsBundle WebKitLocalizableStringsBundle = { "com.apple.WebKit", 0 }; |
|
43 |
|
44 static CFBundleRef localizedStringsMainBundle; |
|
45 static HashMap<String, String> mainBundleLocStrings; |
|
46 static HashMap<String, String> frameworkLocStrings; |
|
47 |
|
48 static CFBundleRef createWebKitBundle() |
|
49 { |
|
50 WCHAR pathStr[MAX_PATH]; |
|
51 DWORD length = ::GetModuleFileNameW(gInstance, pathStr, MAX_PATH); |
|
52 if (!length || (length == MAX_PATH && GetLastError() == ERROR_INSUFFICIENT_BUFFER)) |
|
53 return 0; |
|
54 |
|
55 bool found = false; |
|
56 for (int i = length - 1; i >= 0; i--) { |
|
57 // warning C6385: Invalid data: accessing 'pathStr', the readable size is '520' bytes, but '2000' bytes might be read |
|
58 #pragma warning(suppress: 6385) |
|
59 if (pathStr[i] == L'\\') { |
|
60 // warning C6386: Buffer overrun: accessing 'pathStr', the writable size is '520' bytes, but '1996' bytes might be written |
|
61 #pragma warning(suppress: 6386) |
|
62 pathStr[i] = 0; |
|
63 found = true; |
|
64 break; |
|
65 } |
|
66 } |
|
67 if (!found) |
|
68 return 0; |
|
69 |
|
70 if (wcscat_s(pathStr, MAX_PATH, L"\\WebKit.resources")) |
|
71 return 0; |
|
72 |
|
73 String bundlePathString(pathStr); |
|
74 CFStringRef bundlePathCFString = bundlePathString.createCFString(); |
|
75 if (!bundlePathCFString) |
|
76 return 0; |
|
77 |
|
78 CFURLRef bundleURLRef = CFURLCreateWithFileSystemPath(0, bundlePathCFString, kCFURLWindowsPathStyle, true); |
|
79 CFRelease(bundlePathCFString); |
|
80 if (!bundleURLRef) |
|
81 return 0; |
|
82 |
|
83 CFBundleRef bundle = CFBundleCreate(0, bundleURLRef); |
|
84 CFRelease(bundleURLRef); |
|
85 return bundle; |
|
86 } |
|
87 |
|
88 void SetWebLocalizedStringMainBundle(CFBundleRef bundle) |
|
89 { |
|
90 if (bundle) |
|
91 CFRetain(bundle); |
|
92 if (localizedStringsMainBundle) |
|
93 CFRelease(localizedStringsMainBundle); |
|
94 localizedStringsMainBundle = bundle; |
|
95 } |
|
96 |
|
97 CFStringRef WebLocalizedString(WebLocalizableStringsBundle* stringsBundle, const UniChar* key) |
|
98 { |
|
99 static CFStringRef notFound = CFSTR("localized string not found"); |
|
100 |
|
101 CFBundleRef bundle; |
|
102 if (!stringsBundle) { |
|
103 static CFBundleRef mainBundle; |
|
104 if (!mainBundle) { |
|
105 mainBundle = localizedStringsMainBundle; |
|
106 if (!mainBundle) |
|
107 return notFound; |
|
108 } |
|
109 bundle = mainBundle; |
|
110 } else { |
|
111 bundle = stringsBundle->bundle; |
|
112 if (!bundle) { |
|
113 bundle = createWebKitBundle(); |
|
114 if (!bundle) |
|
115 return notFound; |
|
116 stringsBundle->bundle = bundle; |
|
117 } |
|
118 } |
|
119 CFStringRef keyString = CFStringCreateWithCharacters(0, key, (CFIndex)wcslen(reinterpret_cast<const wchar_t*>(key))); |
|
120 CFStringRef result = CFCopyLocalizedStringWithDefaultValue(keyString, 0, bundle, notFound, 0); |
|
121 CFRelease(keyString); |
|
122 ASSERT_WITH_MESSAGE(result != notFound, "could not find localizable string %s in bundle", key); |
|
123 return result; |
|
124 } |
|
125 |
|
126 LPCTSTR WebLocalizedLPCTSTR(WebLocalizableStringsBundle* stringsBundle, LPCTSTR key) |
|
127 { |
|
128 if (!key) |
|
129 return 0; |
|
130 String keyString(key); |
|
131 if (!stringsBundle && mainBundleLocStrings.contains(keyString)) |
|
132 return mainBundleLocStrings.get(keyString).charactersWithNullTermination(); |
|
133 if (stringsBundle && stringsBundle->bundle == WebKitLocalizableStringsBundle.bundle && frameworkLocStrings.contains(keyString)) |
|
134 return frameworkLocStrings.get(keyString).charactersWithNullTermination(); |
|
135 |
|
136 CFStringRef cfStr = WebLocalizedString(stringsBundle, reinterpret_cast<const UniChar*>(key)); |
|
137 String str(cfStr); |
|
138 if (cfStr) |
|
139 CFRelease(cfStr); |
|
140 for (unsigned int i=1; i<str.length(); i++) |
|
141 if (str[i] == '@' && (str[i - 1] == '%' || (i > 2 && str[i - 1] == '$' && str[i - 2] >= '1' && str[i - 2] <= '9' && str[i - 3] == '%'))) |
|
142 str.replace(i, 1, "s"); |
|
143 LPCTSTR lpszStr = str.charactersWithNullTermination(); |
|
144 |
|
145 if (!stringsBundle) |
|
146 mainBundleLocStrings.set(keyString, str); |
|
147 else if (stringsBundle) |
|
148 frameworkLocStrings.set(keyString, str); |
|
149 |
|
150 return lpszStr; |
|
151 } |