15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2012 Google Inc. All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions are
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * met:
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     * Redistributions of source code must retain the above copyright
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     * Redistributions in binary form must reproduce the above
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * in the documentation and/or other materials provided with the
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * distribution.
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     * Neither the name of Google Inc. nor the names of its
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * contributors may be used to endorse or promote products derived from
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * this software without specific prior written permission.
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
321e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/text/LocaleWin.h"
335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include <limits>
351e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/DateComponents.h"
361e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/Language.h"
371e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/LayoutTestSupport.h"
381e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/text/DateTimeFormat.h"
397757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "wtf/CurrentTime.h"
407757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "wtf/DateMath.h"
417757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "wtf/HashMap.h"
427757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "wtf/OwnPtr.h"
437757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "wtf/PassOwnPtr.h"
44f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)#include "wtf/text/StringBuffer.h"
457757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "wtf/text/StringBuilder.h"
467757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "wtf/text/StringHash.h"
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
48c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)typedef LCID (WINAPI* LocaleNameToLCIDPtr)(LPCWSTR, DWORD);
51926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)typedef HashMap<String, LCID> NameToLCIDMap;
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static String extractLanguageCode(const String& locale)
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    size_t dashPosition = locale.find('-');
5606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (dashPosition == kNotFound)
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return locale;
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return locale.left(dashPosition);
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
61926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static String removeLastComponent(const String& name)
62926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
63926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    size_t lastSeparator = name.reverseFind('-');
6406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (lastSeparator == kNotFound)
65926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return emptyString();
66926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return name.left(lastSeparator);
67926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
68926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
69926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static void ensureNameToLCIDMap(NameToLCIDMap& map)
70926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
71926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!map.isEmpty())
72926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return;
73926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // http://www.microsoft.com/resources/msdn/goglobal/default.mspx
74926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // We add only locales used in layout tests for now.
75926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    map.add("ar", 0x0001);
76926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    map.add("ar-eg", 0x0C01);
77926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    map.add("de", 0x0007);
78926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    map.add("de-de", 0x0407);
79926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    map.add("el", 0x0008);
80926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    map.add("el-gr", 0x0408);
81926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    map.add("en", 0x0009);
82926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    map.add("en-gb", 0x0809);
83926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    map.add("en-us", 0x0409);
84926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    map.add("fr", 0x000C);
85926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    map.add("fr-fr", 0x040C);
86926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    map.add("he", 0x000D);
87926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    map.add("he-il", 0x040D);
88926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    map.add("hi", 0x0039);
89926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    map.add("hi-in", 0x0439);
90926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    map.add("ja", 0x0011);
91926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    map.add("ja-jp", 0x0411);
92926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    map.add("ko", 0x0012);
93926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    map.add("ko-kr", 0x0412);
94926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    map.add("ru", 0x0019);
95926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    map.add("ru-ru", 0x0419);
96926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    map.add("zh-cn", 0x0804);
97926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    map.add("zh-tw", 0x0404);
98926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
99926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
100926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// Fallback implementation of LocaleNameToLCID API. This is used for
101926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// testing on Windows XP.
102926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// FIXME: Remove this, ensureNameToLCIDMap, and removeLastComponent when we drop
103926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// Windows XP support.
104926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static LCID WINAPI convertLocaleNameToLCID(LPCWSTR name, DWORD)
105926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
106926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!name || !name[0])
107926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return LOCALE_USER_DEFAULT;
108926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    DEFINE_STATIC_LOCAL(NameToLCIDMap, map, ());
109926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ensureNameToLCIDMap(map);
110926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    String localeName = String(name).replace('_', '-');
1111e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    localeName = localeName.lower();
112926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    do {
113926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        NameToLCIDMap::const_iterator iterator = map.find(localeName);
114926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (iterator != map.end())
115926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            return iterator->value;
116926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        localeName = removeLastComponent(localeName);
117926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    } while (!localeName.isEmpty());
118926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return LOCALE_USER_DEFAULT;
119926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
120926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
12151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)static LCID LCIDFromLocaleInternal(LCID userDefaultLCID, const String& userDefaultLanguageCode, LocaleNameToLCIDPtr localeNameToLCID, const String& locale)
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String localeLanguageCode = extractLanguageCode(locale);
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (equalIgnoringCase(localeLanguageCode, userDefaultLanguageCode))
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return userDefaultLCID;
126591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    return localeNameToLCID(locale.charactersWithNullTermination().data(), 0);
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
129a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)static LCID LCIDFromLocale(const String& locale, bool defaultsForLocale)
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // LocaleNameToLCID() is available since Windows Vista.
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LocaleNameToLCIDPtr localeNameToLCID = reinterpret_cast<LocaleNameToLCIDPtr>(::GetProcAddress(::GetModuleHandle(L"kernel32"), "LocaleNameToLCID"));
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!localeNameToLCID)
134926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        localeNameToLCID = convertLocaleNameToLCID;
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // According to MSDN, 9 is enough for LOCALE_SISO639LANGNAME.
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const size_t languageCodeBufferSize = 9;
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    WCHAR lowercaseLanguageCode[languageCodeBufferSize];
139c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    ::GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME | (defaultsForLocale ? LOCALE_NOUSEROVERRIDE : 0), lowercaseLanguageCode, languageCodeBufferSize);
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String userDefaultLanguageCode = String(lowercaseLanguageCode);
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
142a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    LCID lcid = LCIDFromLocaleInternal(LOCALE_USER_DEFAULT, userDefaultLanguageCode, localeNameToLCID, locale);
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!lcid)
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        lcid = LCIDFromLocaleInternal(LOCALE_USER_DEFAULT, userDefaultLanguageCode, localeNameToLCID, defaultLanguage());
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return lcid;
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
148a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)PassOwnPtr<Locale> Locale::create(const String& locale)
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
150c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    // Whether the default settings for the locale should be used, ignoring user overrides.
151197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    bool defaultsForLocale = LayoutTestSupport::isRunningLayoutTest();
152c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    return LocaleWin::create(LCIDFromLocale(locale, defaultsForLocale), defaultsForLocale);
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
155c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)inline LocaleWin::LocaleWin(LCID lcid, bool defaultsForLocale)
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : m_lcid(lcid)
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_didInitializeNumberData(false)
158c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    , m_defaultsForLocale(defaultsForLocale)
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DWORD value = 0;
161c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    getLocaleInfo(LOCALE_IFIRSTDAYOFWEEK | (defaultsForLocale ? LOCALE_NOUSEROVERRIDE : 0), value);
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // 0:Monday, ..., 6:Sunday.
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // We need 1 for Monday, 0 for Sunday.
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_firstDayOfWeek = (value + 1) % 7;
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
167c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)PassOwnPtr<LocaleWin> LocaleWin::create(LCID lcid, bool defaultsForLocale)
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
169c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    return adoptPtr(new LocaleWin(lcid, defaultsForLocale));
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LocaleWin::~LocaleWin()
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String LocaleWin::getLocaleInfoString(LCTYPE type)
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
178c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    int bufferSizeWithNUL = ::GetLocaleInfo(m_lcid, type | (m_defaultsForLocale ? LOCALE_NOUSEROVERRIDE : 0), 0, 0);
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (bufferSizeWithNUL <= 0)
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return String();
181f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    StringBuffer<UChar> buffer(bufferSizeWithNUL);
182c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    ::GetLocaleInfo(m_lcid, type | (m_defaultsForLocale ? LOCALE_NOUSEROVERRIDE : 0), buffer.characters(), bufferSizeWithNUL);
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    buffer.shrink(bufferSizeWithNUL - 1);
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return String::adopt(buffer);
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void LocaleWin::getLocaleInfo(LCTYPE type, DWORD& result)
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ::GetLocaleInfo(m_lcid, type | LOCALE_RETURN_NUMBER, reinterpret_cast<LPWSTR>(&result), sizeof(DWORD) / sizeof(TCHAR));
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void LocaleWin::ensureShortMonthLabels()
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_shortMonthLabels.isEmpty())
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const LCTYPE types[12] = {
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LOCALE_SABBREVMONTHNAME1,
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LOCALE_SABBREVMONTHNAME2,
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LOCALE_SABBREVMONTHNAME3,
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LOCALE_SABBREVMONTHNAME4,
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LOCALE_SABBREVMONTHNAME5,
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LOCALE_SABBREVMONTHNAME6,
2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LOCALE_SABBREVMONTHNAME7,
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LOCALE_SABBREVMONTHNAME8,
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LOCALE_SABBREVMONTHNAME9,
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LOCALE_SABBREVMONTHNAME10,
2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LOCALE_SABBREVMONTHNAME11,
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LOCALE_SABBREVMONTHNAME12,
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    };
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_shortMonthLabels.reserveCapacity(WTF_ARRAY_LENGTH(types));
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (unsigned i = 0; i < WTF_ARRAY_LENGTH(types); ++i) {
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_shortMonthLabels.append(getLocaleInfoString(types[i]));
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (m_shortMonthLabels.last().isEmpty()) {
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_shortMonthLabels.shrink(0);
2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_shortMonthLabels.reserveCapacity(WTF_ARRAY_LENGTH(WTF::monthName));
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            for (unsigned m = 0; m < WTF_ARRAY_LENGTH(WTF::monthName); ++m)
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                m_shortMonthLabels.append(WTF::monthName[m]);
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// -------------------------------- Tokenized date format
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static unsigned countContinuousLetters(const String& format, unsigned index)
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned count = 1;
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    UChar reference = format[index];
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (index + 1 < format.length()) {
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (format[++index] != reference)
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ++count;
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return count;
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void commitLiteralToken(StringBuilder& literalBuffer, StringBuilder& converted)
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (literalBuffer.length() <= 0)
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DateTimeFormat::quoteAndAppendLiteral(literalBuffer.toString(), converted);
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    literalBuffer.clear();
2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// This function converts Windows date/time pattern format [1][2] into LDML date
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// format pattern [3].
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// i.e.
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//   We set h, H, m, s, d, dd, M, or y as is. They have same meaning in both of
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//   Windows and LDML.
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//   We need to convert the following patterns:
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//     t -> a
2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//     tt -> a
2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//     ddd -> EEE
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//     dddd -> EEEE
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//     g -> G
2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//     gg -> ignore
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// [1] http://msdn.microsoft.com/en-us/library/dd317787(v=vs.85).aspx
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// [2] http://msdn.microsoft.com/en-us/library/dd318148(v=vs.85).aspx
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// [3] LDML http://unicode.org/reports/tr35/tr35-6.html#Date_Format_Patterns
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static String convertWindowsDateTimeFormat(const String& format)
2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StringBuilder converted;
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StringBuilder literalBuffer;
2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool inQuote = false;
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool lastQuoteCanBeLiteral = false;
2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (unsigned i = 0; i < format.length(); ++i) {
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        UChar ch = format[i];
2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (inQuote) {
2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (ch == '\'') {
2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                inQuote = false;
2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                ASSERT(i);
2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (lastQuoteCanBeLiteral && format[i - 1] == '\'') {
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    literalBuffer.append('\'');
2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    lastQuoteCanBeLiteral = false;
2771e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                } else {
2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    lastQuoteCanBeLiteral = true;
2791e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                }
2801e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            } else {
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                literalBuffer.append(ch);
2821e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            }
2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (ch == '\'') {
2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            inQuote = true;
2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (lastQuoteCanBeLiteral && i > 0 && format[i - 1] == '\'') {
2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                literalBuffer.append(ch);
2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                lastQuoteCanBeLiteral = false;
2911e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            } else {
2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                lastQuoteCanBeLiteral = true;
2931e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            }
2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else if (isASCIIAlpha(ch)) {
2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            commitLiteralToken(literalBuffer, converted);
2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            unsigned symbolStart = i;
2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            unsigned count = countContinuousLetters(format, i);
2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            i += count - 1;
2991e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            if (ch == 'h' || ch == 'H' || ch == 'm' || ch == 's' || ch == 'M' || ch == 'y') {
3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                converted.append(format, symbolStart, count);
3011e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            } else if (ch == 'd') {
3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (count <= 2)
3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    converted.append(format, symbolStart, count);
3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                else if (count == 3)
3059e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)                    converted.appendLiteral("EEE");
3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                else
3079e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)                    converted.appendLiteral("EEEE");
3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            } else if (ch == 'g') {
3091e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                if (count == 1) {
3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    converted.append('G');
3111e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                } else {
3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    // gg means imperial era in Windows.
3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    // Just ignore it.
3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
3151e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            } else if (ch == 't') {
3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                converted.append('a');
3171e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            } else {
3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                literalBuffer.append(format, symbolStart, count);
3191e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            }
3201e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        } else {
3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            literalBuffer.append(ch);
3221e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    commitLiteralToken(literalBuffer, converted);
3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return converted.toString();
3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void LocaleWin::ensureMonthLabels()
3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_monthLabels.isEmpty())
3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const LCTYPE types[12] = {
3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LOCALE_SMONTHNAME1,
3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LOCALE_SMONTHNAME2,
3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LOCALE_SMONTHNAME3,
3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LOCALE_SMONTHNAME4,
3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LOCALE_SMONTHNAME5,
3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LOCALE_SMONTHNAME6,
3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LOCALE_SMONTHNAME7,
3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LOCALE_SMONTHNAME8,
3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LOCALE_SMONTHNAME9,
3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LOCALE_SMONTHNAME10,
3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LOCALE_SMONTHNAME11,
3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LOCALE_SMONTHNAME12,
3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    };
3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_monthLabels.reserveCapacity(WTF_ARRAY_LENGTH(types));
3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (unsigned i = 0; i < WTF_ARRAY_LENGTH(types); ++i) {
3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_monthLabels.append(getLocaleInfoString(types[i]));
3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (m_monthLabels.last().isEmpty()) {
3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_monthLabels.shrink(0);
3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_monthLabels.reserveCapacity(WTF_ARRAY_LENGTH(WTF::monthFullName));
3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            for (unsigned m = 0; m < WTF_ARRAY_LENGTH(WTF::monthFullName); ++m)
3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                m_monthLabels.append(WTF::monthFullName[m]);
3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void LocaleWin::ensureWeekDayShortLabels()
3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_weekDayShortLabels.isEmpty())
3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const LCTYPE types[7] = {
3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LOCALE_SABBREVDAYNAME7, // Sunday
3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LOCALE_SABBREVDAYNAME1, // Monday
3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LOCALE_SABBREVDAYNAME2,
3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LOCALE_SABBREVDAYNAME3,
3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LOCALE_SABBREVDAYNAME4,
3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LOCALE_SABBREVDAYNAME5,
3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LOCALE_SABBREVDAYNAME6
3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    };
3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_weekDayShortLabels.reserveCapacity(WTF_ARRAY_LENGTH(types));
3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (unsigned i = 0; i < WTF_ARRAY_LENGTH(types); ++i) {
3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_weekDayShortLabels.append(getLocaleInfoString(types[i]));
3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (m_weekDayShortLabels.last().isEmpty()) {
3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_weekDayShortLabels.shrink(0);
3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_weekDayShortLabels.reserveCapacity(WTF_ARRAY_LENGTH(WTF::weekdayName));
3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            for (unsigned w = 0; w < WTF_ARRAY_LENGTH(WTF::weekdayName); ++w) {
3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // weekdayName starts with Monday.
3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                m_weekDayShortLabels.append(WTF::weekdayName[(w + 6) % 7]);
3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const Vector<String>& LocaleWin::monthLabels()
3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ensureMonthLabels();
3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_monthLabels;
3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const Vector<String>& LocaleWin::weekDayShortLabels()
3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ensureWeekDayShortLabels();
3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_weekDayShortLabels;
3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned LocaleWin::firstDayOfWeek()
4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_firstDayOfWeek;
4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool LocaleWin::isRTL()
4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    WTF::Unicode::Direction dir = WTF::Unicode::direction(monthLabels()[0][0]);
4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return dir == WTF::Unicode::RightToLeft || dir == WTF::Unicode::RightToLeftArabic;
4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String LocaleWin::dateFormat()
4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_dateFormat.isNull())
4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_dateFormat = convertWindowsDateTimeFormat(getLocaleInfoString(LOCALE_SSHORTDATE));
4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_dateFormat;
4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String LocaleWin::dateFormat(const String& windowsFormat)
4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return convertWindowsDateTimeFormat(windowsFormat);
4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String LocaleWin::monthFormat()
4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_monthFormat.isNull())
4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_monthFormat = convertWindowsDateTimeFormat(getLocaleInfoString(LOCALE_SYEARMONTH));
4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_monthFormat;
4275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
429926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)String LocaleWin::shortMonthFormat()
430926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
431926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (m_shortMonthFormat.isNull())
432926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        m_shortMonthFormat = convertWindowsDateTimeFormat(getLocaleInfoString(LOCALE_SYEARMONTH)).replace("MMMM", "MMM");
433926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return m_shortMonthFormat;
434926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
435926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String LocaleWin::timeFormat()
4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_timeFormatWithSeconds.isNull())
4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_timeFormatWithSeconds = convertWindowsDateTimeFormat(getLocaleInfoString(LOCALE_STIMEFORMAT));
4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_timeFormatWithSeconds;
4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String LocaleWin::shortTimeFormat()
4445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_timeFormatWithoutSeconds.isNull())
4465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return m_timeFormatWithoutSeconds;
4475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String format = getLocaleInfoString(LOCALE_SSHORTTIME);
4485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Vista or older Windows doesn't support LOCALE_SSHORTTIME.
4495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (format.isEmpty()) {
4505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        format = getLocaleInfoString(LOCALE_STIMEFORMAT);
4515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        StringBuilder builder;
4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        builder.append(getLocaleInfoString(LOCALE_STIME));
4539e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        builder.appendLiteral("ss");
4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        size_t pos = format.reverseFind(builder.toString());
45506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        if (pos != kNotFound)
4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            format.remove(pos, builder.length());
4575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_timeFormatWithoutSeconds = convertWindowsDateTimeFormat(format);
4595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_timeFormatWithoutSeconds;
4605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
462926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)String LocaleWin::dateTimeFormatWithSeconds()
463926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
464926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!m_dateTimeFormatWithSeconds.isNull())
465926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return m_dateTimeFormatWithSeconds;
466926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    StringBuilder builder;
467926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    builder.append(dateFormat());
468926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    builder.append(' ');
469926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    builder.append(timeFormat());
470926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    m_dateTimeFormatWithSeconds = builder.toString();
471926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return m_dateTimeFormatWithSeconds;
472926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
473926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
474926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)String LocaleWin::dateTimeFormatWithoutSeconds()
475926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
476926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!m_dateTimeFormatWithoutSeconds.isNull())
477926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return m_dateTimeFormatWithoutSeconds;
478926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    StringBuilder builder;
479926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    builder.append(dateFormat());
480926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    builder.append(' ');
481926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    builder.append(shortTimeFormat());
482926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    m_dateTimeFormatWithoutSeconds = builder.toString();
483926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return m_dateTimeFormatWithoutSeconds;
484926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
485926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
4865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const Vector<String>& LocaleWin::shortMonthLabels()
4875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ensureShortMonthLabels();
4895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_shortMonthLabels;
4905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const Vector<String>& LocaleWin::standAloneMonthLabels()
4935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Windows doesn't provide a way to get stand-alone month labels.
4955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return monthLabels();
4965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const Vector<String>& LocaleWin::shortStandAloneMonthLabels()
4995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Windows doesn't provide a way to get stand-alone month labels.
5015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return shortMonthLabels();
5025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const Vector<String>& LocaleWin::timeAMPMLabels()
5055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_timeAMPMLabels.isEmpty()) {
5075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_timeAMPMLabels.append(getLocaleInfoString(LOCALE_S1159));
5085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_timeAMPMLabels.append(getLocaleInfoString(LOCALE_S2359));
5095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_timeAMPMLabels;
5115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void LocaleWin::initializeLocaleData()
5145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_didInitializeNumberData)
5165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
5175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<String, DecimalSymbolsSize> symbols;
5195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    enum DigitSubstitution {
5205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        DigitSubstitutionContext = 0,
5215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        DigitSubstitution0to9 = 1,
5225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        DigitSubstitutionNative = 2,
5235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    };
5245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DWORD digitSubstitution = DigitSubstitution0to9;
5255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    getLocaleInfo(LOCALE_IDIGITSUBSTITUTION, digitSubstitution);
5265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (digitSubstitution == DigitSubstitution0to9) {
5275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        symbols.append("0");
5285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        symbols.append("1");
5295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        symbols.append("2");
5305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        symbols.append("3");
5315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        symbols.append("4");
5325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        symbols.append("5");
5335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        symbols.append("6");
5345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        symbols.append("7");
5355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        symbols.append("8");
5365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        symbols.append("9");
5375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else {
5385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        String digits = getLocaleInfoString(LOCALE_SNATIVEDIGITS);
5395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(digits.length() >= 10);
5405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (unsigned i = 0; i < 10; ++i)
5415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            symbols.append(digits.substring(i, 1));
5425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(symbols.size() == DecimalSeparatorIndex);
5445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    symbols.append(getLocaleInfoString(LOCALE_SDECIMAL));
5455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(symbols.size() == GroupSeparatorIndex);
5465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    symbols.append(getLocaleInfoString(LOCALE_STHOUSAND));
5475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(symbols.size() == DecimalSymbolsSize);
5485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String negativeSign = getLocaleInfoString(LOCALE_SNEGATIVESIGN);
5505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    enum NegativeFormat {
5515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        NegativeFormatParenthesis = 0,
5525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        NegativeFormatSignPrefix = 1,
5535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        NegativeFormatSignSpacePrefix = 2,
5545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        NegativeFormatSignSuffix = 3,
5555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        NegativeFormatSpaceSignSuffix = 4,
5565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    };
5575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DWORD negativeFormat = NegativeFormatSignPrefix;
5585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    getLocaleInfo(LOCALE_INEGNUMBER, negativeFormat);
5595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String negativePrefix = emptyString();
5605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String negativeSuffix = emptyString();
5615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    switch (negativeFormat) {
5625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case NegativeFormatParenthesis:
5635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        negativePrefix = "(";
5645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        negativeSuffix = ")";
5655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
5665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case NegativeFormatSignSpacePrefix:
5675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        negativePrefix = negativeSign + " ";
5685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
5695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case NegativeFormatSignSuffix:
5705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        negativeSuffix = negativeSign;
5715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
5725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case NegativeFormatSpaceSignSuffix:
5735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        negativeSuffix = " " + negativeSign;
5745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
5755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case NegativeFormatSignPrefix: // Fall through.
5765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    default:
5775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        negativePrefix = negativeSign;
5785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
5795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_didInitializeNumberData = true;
5815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    setLocaleData(symbols, emptyString(), emptyString(), negativePrefix, negativeSuffix);
5825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
585