15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2011,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/PlatformLocale.h"
335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
341e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/text/DateTimeFormat.h"
359bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)#include "public/platform/Platform.h"
361e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "wtf/MainThread.h"
377757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "wtf/text/StringBuilder.h"
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore {
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)using blink::Platform;
4251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)using blink::WebLocalizedString;
439bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class DateTimeStringBuilder : private DateTimeFormat::TokenHandler {
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    WTF_MAKE_NONCOPYABLE(DateTimeStringBuilder);
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The argument objects must be alive until this object dies.
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DateTimeStringBuilder(Locale&, const DateComponents&);
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool build(const String&);
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String toString();
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // DateTimeFormat::TokenHandler functions.
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    virtual void visitField(DateTimeFormat::FieldType, int) OVERRIDE FINAL;
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    virtual void visitLiteral(const String&) OVERRIDE FINAL;
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String zeroPadString(const String&, size_t width);
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void appendNumber(int number, size_t width);
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StringBuilder m_builder;
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Locale& m_localizer;
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const DateComponents& m_date;
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DateTimeStringBuilder::DateTimeStringBuilder(Locale& localizer, const DateComponents& date)
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : m_localizer(localizer)
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_date(date)
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool DateTimeStringBuilder::build(const String& formatString)
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_builder.reserveCapacity(formatString.length());
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return DateTimeFormat::parse(formatString, *this);
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String DateTimeStringBuilder::zeroPadString(const String& string, size_t width)
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (string.length() >= width)
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return string;
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StringBuilder zeroPaddedStringBuilder;
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    zeroPaddedStringBuilder.reserveCapacity(width);
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i = string.length(); i < width; ++i)
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        zeroPaddedStringBuilder.append("0");
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    zeroPaddedStringBuilder.append(string);
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return zeroPaddedStringBuilder.toString();
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void DateTimeStringBuilder::appendNumber(int number, size_t width)
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String zeroPaddedNumberString = zeroPadString(String::number(number), width);
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_builder.append(m_localizer.convertToLocalizedNumber(zeroPaddedNumberString));
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void DateTimeStringBuilder::visitField(DateTimeFormat::FieldType fieldType, int numberOfPatternCharacters)
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    switch (fieldType) {
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case DateTimeFormat::FieldTypeYear:
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Always use padding width of 4 so it matches DateTimeEditElement.
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        appendNumber(m_date.fullYear(), 4);
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case DateTimeFormat::FieldTypeMonth:
1041e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (numberOfPatternCharacters == 3) {
105926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            m_builder.append(m_localizer.shortMonthLabels()[m_date.month()]);
1061e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        } else if (numberOfPatternCharacters == 4) {
107926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            m_builder.append(m_localizer.monthLabels()[m_date.month()]);
1081e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        } else {
109926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            // Always use padding width of 2 so it matches DateTimeEditElement.
110926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            appendNumber(m_date.month() + 1, 2);
111926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
112926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return;
113926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    case DateTimeFormat::FieldTypeMonthStandAlone:
1141e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (numberOfPatternCharacters == 3) {
115926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            m_builder.append(m_localizer.shortStandAloneMonthLabels()[m_date.month()]);
1161e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        } else if (numberOfPatternCharacters == 4) {
117926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            m_builder.append(m_localizer.standAloneMonthLabels()[m_date.month()]);
1181e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        } else {
119926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            // Always use padding width of 2 so it matches DateTimeEditElement.
120926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            appendNumber(m_date.month() + 1, 2);
121926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case DateTimeFormat::FieldTypeDayOfMonth:
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Always use padding width of 2 so it matches DateTimeEditElement.
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        appendNumber(m_date.monthDay(), 2);
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
127926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    case DateTimeFormat::FieldTypeWeekOfYear:
128926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // Always use padding width of 2 so it matches DateTimeEditElement.
129926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        appendNumber(m_date.week(), 2);
130926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return;
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case DateTimeFormat::FieldTypePeriod:
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_builder.append(m_localizer.timeAMPMLabels()[(m_date.hour() >= 12 ? 1 : 0)]);
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case DateTimeFormat::FieldTypeHour12: {
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int hour12 = m_date.hour() % 12;
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!hour12)
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            hour12 = 12;
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        appendNumber(hour12, numberOfPatternCharacters);
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case DateTimeFormat::FieldTypeHour23:
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        appendNumber(m_date.hour(), numberOfPatternCharacters);
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case DateTimeFormat::FieldTypeHour11:
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        appendNumber(m_date.hour() % 12, numberOfPatternCharacters);
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case DateTimeFormat::FieldTypeHour24: {
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int hour24 = m_date.hour();
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!hour24)
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            hour24 = 24;
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        appendNumber(hour24, numberOfPatternCharacters);
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case DateTimeFormat::FieldTypeMinute:
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        appendNumber(m_date.minute(), numberOfPatternCharacters);
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case DateTimeFormat::FieldTypeSecond:
1581e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (!m_date.millisecond()) {
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            appendNumber(m_date.second(), numberOfPatternCharacters);
1601e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        } else {
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            double second = m_date.second() + m_date.millisecond() / 1000.0;
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            String zeroPaddedSecondString = zeroPadString(String::format("%.03f", second), numberOfPatternCharacters + 4);
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_builder.append(m_localizer.convertToLocalizedNumber(zeroPaddedSecondString));
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    default:
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void DateTimeStringBuilder::visitLiteral(const String& text)
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(text.length());
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_builder.append(text);
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String DateTimeStringBuilder::toString()
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_builder.toString();
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
182bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)Locale& Locale::defaultLocale()
1831e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles){
1841e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    static Locale* locale = Locale::create(defaultLanguage()).leakPtr();
1851e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ASSERT(isMainThread());
186bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    return *locale;
1871e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)}
1881e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Locale::~Locale()
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1939bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)String Locale::queryString(WebLocalizedString::Name name)
1949bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles){
1959bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    // FIXME: Returns a string locazlied for this locale.
1969bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    return Platform::current()->queryLocalizedString(name);
1979bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)}
1989bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
1999bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)String Locale::queryString(WebLocalizedString::Name name, const String& parameter)
2009bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles){
2019bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    // FIXME: Returns a string locazlied for this locale.
2029bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    return Platform::current()->queryLocalizedString(name, parameter);
2039bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)}
2049bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
2059bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)String Locale::queryString(WebLocalizedString::Name name, const String& parameter1, const String& parameter2)
2069bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles){
2079bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    // FIXME: Returns a string locazlied for this locale.
2089bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    return Platform::current()->queryLocalizedString(name, parameter1, parameter2);
2099bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)}
2109bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
21106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)String Locale::validationMessageTooLongText(unsigned valueLength, int maxLength)
21206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){
21306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    return queryString(WebLocalizedString::ValidationTooLong, convertToLocalizedNumber(String::number(valueLength)), convertToLocalizedNumber(String::number(maxLength)));
21406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)}
21506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
2161e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)String Locale::weekFormatInLDML()
2171e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles){
2181e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    String templ = queryString(WebLocalizedString::WeekFormatTemplate);
2191e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    // Converts a string like "Week $2, $1" to an LDML date format pattern like
2201e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    // "'Week 'ww', 'yyyy".
2211e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    StringBuilder builder;
2221e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    unsigned literalStart = 0;
2231e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    unsigned length = templ.length();
2241e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    for (unsigned i = 0; i + 1 < length; ++i) {
2251e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (templ[i] == '$' && (templ[i + 1] == '1' || templ[i + 1] == '2')) {
2261e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            if (literalStart < i)
2271e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                DateTimeFormat::quoteAndAppendLiteral(templ.substring(literalStart, i - literalStart), builder);
2281e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            builder.append(templ[++i] == '1' ? "yyyy" : "ww");
2291e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            literalStart = i + 1;
2301e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
2311e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
2321e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (literalStart < length)
2331e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        DateTimeFormat::quoteAndAppendLiteral(templ.substring(literalStart, length - literalStart), builder);
2341e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    return builder.toString();
2351e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)}
2361e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Locale::setLocaleData(const Vector<String, DecimalSymbolsSize>& symbols, const String& positivePrefix, const String& positiveSuffix, const String& negativePrefix, const String& negativeSuffix)
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i = 0; i < symbols.size(); ++i) {
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(!symbols[i].isEmpty());
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_decimalSymbols[i] = symbols[i];
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_positivePrefix = positivePrefix;
2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_positiveSuffix = positiveSuffix;
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_negativePrefix = negativePrefix;
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_negativeSuffix = negativeSuffix;
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!m_positivePrefix.isEmpty() || !m_positiveSuffix.isEmpty() || !m_negativePrefix.isEmpty() || !m_negativeSuffix.isEmpty());
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_hasLocaleData = true;
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String Locale::convertToLocalizedNumber(const String& input)
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    initializeLocaleData();
2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_hasLocaleData || input.isEmpty())
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return input;
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned i = 0;
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isNegative = false;
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StringBuilder builder;
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    builder.reserveCapacity(input.length());
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (input[0] == '-') {
2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ++i;
2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        isNegative = true;
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        builder.append(m_negativePrefix);
2661e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    } else {
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        builder.append(m_positivePrefix);
2681e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (; i < input.length(); ++i) {
2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        switch (input[i]) {
2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case '0':
2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case '1':
2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case '2':
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case '3':
2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case '4':
2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case '5':
2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case '6':
2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case '7':
2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case '8':
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case '9':
2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            builder.append(m_decimalSymbols[input[i] - '0']);
2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case '.':
2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            builder.append(m_decimalSymbols[DecimalSeparatorIndex]);
2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        default:
2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT_NOT_REACHED();
2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    builder.append(isNegative ? m_negativeSuffix : m_positiveSuffix);
2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return builder.toString();
2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool matches(const String& text, unsigned position, const String& part)
2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (part.isEmpty())
3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (position + part.length() > text.length())
3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (unsigned i = 0; i < part.length(); ++i) {
3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (text[position + i] != part[i])
3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return false;
3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return true;
3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool Locale::detectSignAndGetDigitRange(const String& input, bool& isNegative, unsigned& startIndex, unsigned& endIndex)
3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    startIndex = 0;
3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    endIndex = input.length();
3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_negativePrefix.isEmpty() && m_negativeSuffix.isEmpty()) {
3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (input.startsWith(m_positivePrefix) && input.endsWith(m_positiveSuffix)) {
3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            isNegative = false;
3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            startIndex = m_positivePrefix.length();
3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            endIndex -= m_positiveSuffix.length();
3191e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        } else {
3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            isNegative = true;
3211e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else {
3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (input.startsWith(m_negativePrefix) && input.endsWith(m_negativeSuffix)) {
3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            isNegative = true;
3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            startIndex = m_negativePrefix.length();
3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            endIndex -= m_negativeSuffix.length();
3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else {
3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            isNegative = false;
3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (input.startsWith(m_positivePrefix) && input.endsWith(m_positiveSuffix)) {
3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                startIndex = m_positivePrefix.length();
3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                endIndex -= m_positiveSuffix.length();
3321e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            } else {
3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return false;
3341e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            }
3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return true;
3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned Locale::matchedDecimalSymbolIndex(const String& input, unsigned& position)
3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (unsigned symbolIndex = 0; symbolIndex < DecimalSymbolsSize; ++symbolIndex) {
3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (m_decimalSymbols[symbolIndex].length() && matches(input, position, m_decimalSymbols[symbolIndex])) {
3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            position += m_decimalSymbols[symbolIndex].length();
3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return symbolIndex;
3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return DecimalSymbolsSize;
3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String Locale::convertFromLocalizedNumber(const String& localized)
3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    initializeLocaleData();
35410f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    String input = localized.removeCharacters(isASCIISpace);
3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_hasLocaleData || input.isEmpty())
3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return input;
3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isNegative;
3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned startIndex;
3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned endIndex;
361926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!detectSignAndGetDigitRange(input, isNegative, startIndex, endIndex))
362926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return input;
3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StringBuilder builder;
3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    builder.reserveCapacity(input.length());
3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isNegative)
3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        builder.append("-");
3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (unsigned i = startIndex; i < endIndex;) {
3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        unsigned symbolIndex = matchedDecimalSymbolIndex(input, i);
3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (symbolIndex >= DecimalSymbolsSize)
371926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            return input;
3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (symbolIndex == DecimalSeparatorIndex)
3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            builder.append('.');
374926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        else if (symbolIndex == GroupSeparatorIndex)
375926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            return input;
376926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        else
3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            builder.append(static_cast<UChar>('0' + symbolIndex));
3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return builder.toString();
3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String Locale::localizedDecimalSeparator()
3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    initializeLocaleData();
3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_decimalSymbols[DecimalSeparatorIndex];
3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String Locale::formatDateTime(const DateComponents& date, FormatType formatType)
3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
392926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (date.type() == DateComponents::Invalid)
393926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return String();
3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DateTimeStringBuilder builder(*this, date);
396926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    switch (date.type()) {
397926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    case DateComponents::Time:
3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        builder.build(formatType == FormatTypeShort ? shortTimeFormat() : timeFormat());
399926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        break;
400926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    case DateComponents::Date:
4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        builder.build(dateFormat());
402926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        break;
403926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    case DateComponents::Month:
404926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        builder.build(formatType == FormatTypeShort ? shortMonthFormat() : monthFormat());
405926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        break;
40602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    case DateComponents::Week:
407926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        builder.build(weekFormatInLDML());
408926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        break;
409926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    case DateComponents::DateTime:
410926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    case DateComponents::DateTimeLocal:
411926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        builder.build(formatType == FormatTypeShort ? dateTimeFormatWithoutSeconds() : dateTimeFormatWithSeconds());
412926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        break;
413926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    case DateComponents::Invalid:
414926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        ASSERT_NOT_REACHED();
415926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        break;
416926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return builder.toString();
4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
421