18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met:
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    documentation and/or other materials provided with the distribution.
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "WebKitDLL.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "WebLocalizableStrings.h"
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <WebCore/PlatformString.h>
32dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include <wtf/text/CString.h>
33f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick#include <wtf/text/StringHash.h>
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/Assertions.h>
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/HashMap.h>
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/RetainPtr.h>
38cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#include <wtf/StdLibExtras.h>
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <CoreFoundation/CoreFoundation.h>
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectclass LocalizedString;
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace WebCore;
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectWebLocalizableStringsBundle WebKitLocalizableStringsBundle = { "com.apple.WebKit", 0 };
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
47cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blocktypedef HashMap<String, LocalizedString*> LocalizedStringMap;
48cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
49cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockstatic Mutex& mainBundleLocStringsMutex()
50cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{
51cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    DEFINE_STATIC_LOCAL(Mutex, mutex, ());
52cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    return mutex;
53cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block}
54cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
55cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockstatic LocalizedStringMap& mainBundleLocStrings()
56cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{
57cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    DEFINE_STATIC_LOCAL(LocalizedStringMap, map, ());
58cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    return map;
59cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block}
60cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
61cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockstatic Mutex& frameworkLocStringsMutex()
62cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{
63cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    DEFINE_STATIC_LOCAL(Mutex, mutex, ());
64cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    return mutex;
65cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block}
66cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
67cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockstatic LocalizedStringMap frameworkLocStrings()
68cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{
69cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    DEFINE_STATIC_LOCAL(LocalizedStringMap, map, ());
70cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    return map;
71cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block}
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
73ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochclass LocalizedString {
74ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    WTF_MAKE_NONCOPYABLE(LocalizedString);
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectpublic:
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    LocalizedString(CFStringRef string)
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        : m_cfString(string)
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT_ARG(string, string);
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    operator LPCTSTR() const;
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    operator CFStringRef() const { return m_cfString; }
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectprivate:
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CFStringRef m_cfString;
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    mutable String m_string;
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectLocalizedString::operator LPCTSTR() const
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_string.isEmpty())
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return m_string.charactersWithNullTermination();
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_string = m_cfString;
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned int i = 1; i < m_string.length(); i++)
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_string[i] == '@' && (m_string[i - 1] == '%' || (i > 2 && m_string[i - 1] == '$' && m_string[i - 2] >= '1' && m_string[i - 2] <= '9' && m_string[i - 3] == '%')))
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_string.replace(i, 1, "s");
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_string.charactersWithNullTermination();
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic CFBundleRef createWebKitBundle()
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static CFBundleRef bundle;
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static bool initialized;
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (initialized)
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return bundle;
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    initialized = true;
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    WCHAR pathStr[MAX_PATH];
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    DWORD length = ::GetModuleFileNameW(gInstance, pathStr, MAX_PATH);
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!length || (length == MAX_PATH && GetLastError() == ERROR_INSUFFICIENT_BUFFER))
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool found = false;
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (int i = length - 1; i >= 0; i--) {
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // warning C6385: Invalid data: accessing 'pathStr', the readable size is '520' bytes, but '2000' bytes might be read
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        #pragma warning(suppress: 6385)
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (pathStr[i] == L'\\') {
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // warning C6386: Buffer overrun: accessing 'pathStr', the writable size is '520' bytes, but '1996' bytes might be written
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            #pragma warning(suppress: 6386)
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            pathStr[i] = 0;
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            found = true;
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!found)
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (wcscat_s(pathStr, MAX_PATH, L"\\WebKit.resources"))
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String bundlePathString(pathStr);
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CFStringRef bundlePathCFString = bundlePathString.createCFString();
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!bundlePathCFString)
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CFURLRef bundleURLRef = CFURLCreateWithFileSystemPath(0, bundlePathCFString, kCFURLWindowsPathStyle, true);
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CFRelease(bundlePathCFString);
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!bundleURLRef)
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bundle = CFBundleCreate(0, bundleURLRef);
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CFRelease(bundleURLRef);
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return bundle;
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic CFBundleRef cfBundleForStringsBundle(WebLocalizableStringsBundle* stringsBundle)
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!stringsBundle) {
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        static CFBundleRef mainBundle = CFBundleGetMainBundle();
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return mainBundle;
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    createWebKitBundle();
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!stringsBundle->bundle)
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        stringsBundle->bundle = CFBundleGetBundleWithIdentifier(RetainPtr<CFStringRef>(AdoptCF, CFStringCreateWithCString(0, stringsBundle->identifier, kCFStringEncodingASCII)).get());
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return stringsBundle->bundle;
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic CFStringRef copyLocalizedStringFromBundle(WebLocalizableStringsBundle* stringsBundle, const String& key)
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static CFStringRef notFound = CFSTR("localized string not found");
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CFBundleRef bundle = cfBundleForStringsBundle(stringsBundle);
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!bundle)
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return notFound;
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RetainPtr<CFStringRef> keyString(AdoptCF, key.createCFString());
1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CFStringRef result = CFCopyLocalizedStringWithDefaultValue(keyString.get(), 0, bundle, notFound, 0);
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT_WITH_MESSAGE(result != notFound, "could not find localizable string %s in bundle", key);
1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic LocalizedString* findCachedString(WebLocalizableStringsBundle* stringsBundle, const String& key)
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
182cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    if (!stringsBundle) {
183cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        MutexLocker lock(mainBundleLocStringsMutex());
184cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        return mainBundleLocStrings().get(key);
185cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    }
1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
187cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    if (stringsBundle->bundle == WebKitLocalizableStringsBundle.bundle) {
188cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        MutexLocker lock(frameworkLocStringsMutex());
189cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        return frameworkLocStrings().get(key);
190cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    }
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return 0;
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void cacheString(WebLocalizableStringsBundle* stringsBundle, const String& key, LocalizedString* value)
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!stringsBundle) {
198cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        MutexLocker lock(mainBundleLocStringsMutex());
199cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        mainBundleLocStrings().set(key, value);
2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
203cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    MutexLocker lock(frameworkLocStringsMutex());
204cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    frameworkLocStrings().set(key, value);
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic const LocalizedString& localizedString(WebLocalizableStringsBundle* stringsBundle, const String& key)
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    LocalizedString* string = findCachedString(stringsBundle, key);
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (string)
2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return *string;
2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    string = new LocalizedString(copyLocalizedStringFromBundle(stringsBundle, key));
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cacheString(stringsBundle, key, string);
2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return *string;
2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCFStringRef WebLocalizedStringUTF8(WebLocalizableStringsBundle* stringsBundle, LPCSTR key)
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!key)
2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return localizedString(stringsBundle, String::fromUTF8(key));
2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectLPCTSTR WebLocalizedLPCTSTRUTF8(WebLocalizableStringsBundle* stringsBundle, LPCSTR key)
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!key)
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return localizedString(stringsBundle, String::fromUTF8(key));
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// These functions are deprecated.
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCFStringRef WebLocalizedString(WebLocalizableStringsBundle* stringsBundle, LPCTSTR key)
2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!key)
2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return localizedString(stringsBundle, String(key));
2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectLPCTSTR WebLocalizedLPCTSTR(WebLocalizableStringsBundle* stringsBundle, LPCTSTR key)
2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!key)
2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return localizedString(stringsBundle, String(key));
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SetWebLocalizedStringMainBundle(CFBundleRef)
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
256