Title: [110414] trunk/Source/WebCore
Revision
110414
Author
[email protected]
Date
2012-03-12 01:38:05 -0700 (Mon, 12 Mar 2012)

Log Message

Use ICU C API instead of C++ API in LocalizedNumberICU
https://bugs.webkit.org/show_bug.cgi?id=80815
https://bugs.gentoo.org/show_bug.cgi?id=407401

Reviewed by Hajime Morita.

ICU 4.8 doesn't have kNumberStyle. We had better to use ICU C API in
general to avoid such issues.

This patch should not make any behavior change.

* platform/text/LocalizedNumberICU.cpp:
(WebCore::ICULocale::ICULocale):
Change the argument type: icu::Locale -> const char*
(WebCore::ICULocale::~ICULocale): Delete m_numberFormat with unum_close().
(WebCore::ICULocale::create): Do not create icu::Locale.
(WebCore::ICULocale::createForCurrentLocale): ditto.
(WebCore::ICULocale::setDecimalSymbol):
Use unum_getSymbol() instead of DecimalFormatSymbols::getSymbol().
(WebCore::ICULocale::setDecimalTextAttribute):
Added. A utility function to store prefixes and suffixes.
(WebCore::ICULocale::initializeDecimalFormat):
- unum_open(), instead of NumberFormat::createInstance().
- Use C API symbols.
- Cache positive/negative prefixes/suffixes.
(WebCore::ICULocale::convertToLocalizedNumber): Use cached prefixes and suffixes.
(WebCore::matches): Stop using template because we don't use UString anymore.
(WebCore::ICULocale::detectSignAndGetDigitRange):
- Use cached prefixes and suffixes.
- Use String::startsWith() and endsWith().
(WebCore::ICULocale::convertFromLocalizedNumber):
* platform/text/LocalizedNumberICU.h:
(ICULocale):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (110413 => 110414)


--- trunk/Source/WebCore/ChangeLog	2012-03-12 08:32:08 UTC (rev 110413)
+++ trunk/Source/WebCore/ChangeLog	2012-03-12 08:38:05 UTC (rev 110414)
@@ -1,3 +1,39 @@
+2012-03-12  Kent Tamura  <[email protected]>
+
+        Use ICU C API instead of C++ API in LocalizedNumberICU
+        https://bugs.webkit.org/show_bug.cgi?id=80815
+        https://bugs.gentoo.org/show_bug.cgi?id=407401
+
+        Reviewed by Hajime Morita.
+
+        ICU 4.8 doesn't have kNumberStyle. We had better to use ICU C API in
+        general to avoid such issues.
+
+        This patch should not make any behavior change.
+
+        * platform/text/LocalizedNumberICU.cpp:
+        (WebCore::ICULocale::ICULocale):
+        Change the argument type: icu::Locale -> const char*
+        (WebCore::ICULocale::~ICULocale): Delete m_numberFormat with unum_close().
+        (WebCore::ICULocale::create): Do not create icu::Locale.
+        (WebCore::ICULocale::createForCurrentLocale): ditto.
+        (WebCore::ICULocale::setDecimalSymbol):
+        Use unum_getSymbol() instead of DecimalFormatSymbols::getSymbol().
+        (WebCore::ICULocale::setDecimalTextAttribute):
+        Added. A utility function to store prefixes and suffixes.
+        (WebCore::ICULocale::initializeDecimalFormat):
+        - unum_open(), instead of NumberFormat::createInstance().
+        - Use C API symbols.
+        - Cache positive/negative prefixes/suffixes.
+        (WebCore::ICULocale::convertToLocalizedNumber): Use cached prefixes and suffixes.
+        (WebCore::matches): Stop using template because we don't use UString anymore.
+        (WebCore::ICULocale::detectSignAndGetDigitRange):
+        - Use cached prefixes and suffixes.
+        - Use String::startsWith() and endsWith().
+        (WebCore::ICULocale::convertFromLocalizedNumber):
+        * platform/text/LocalizedNumberICU.h:
+        (ICULocale):
+
 2012-03-11  Pavel Podivilov  <[email protected]>
 
         Web Inspector: decouple LiveLocation from RawSourceCode.

Modified: trunk/Source/WebCore/platform/text/LocalizedNumberICU.cpp (110413 => 110414)


--- trunk/Source/WebCore/platform/text/LocalizedNumberICU.cpp	2012-03-12 08:32:08 UTC (rev 110413)
+++ trunk/Source/WebCore/platform/text/LocalizedNumberICU.cpp	2012-03-12 08:38:05 UTC (rev 110414)
@@ -32,8 +32,6 @@
 #include "LocalizedNumberICU.h"
 
 #include "LocalizedNumber.h"
-#include <unicode/decimfmt.h>
-#include <unicode/numfmt.h>
 #include <wtf/PassOwnPtr.h>
 #include <wtf/text/StringBuilder.h>
 
@@ -41,72 +39,106 @@
 
 namespace WebCore {
 
-ICULocale::ICULocale(const Locale& locale)
+ICULocale::ICULocale(const char* locale)
     : m_locale(locale)
+    , m_numberFormat(0)
     , m_didCreateDecimalFormat(false)
 {
 }
 
+ICULocale::~ICULocale()
+{
+    unum_close(m_numberFormat);
+}
+
 PassOwnPtr<ICULocale> ICULocale::create(const char* localeString)
 {
-    return adoptPtr(new ICULocale(Locale::createCanonical(localeString)));
+    return adoptPtr(new ICULocale(localeString));
 }
 
 PassOwnPtr<ICULocale> ICULocale::createForCurrentLocale()
 {
-    return adoptPtr(new ICULocale(Locale::getDefault()));
+    return adoptPtr(new ICULocale(0));
 }
 
-void ICULocale::setDecimalSymbol(unsigned index, DecimalFormatSymbols::ENumberFormatSymbol symbol)
+void ICULocale::setDecimalSymbol(unsigned index, UNumberFormatSymbol symbol)
 {
-    UnicodeString ustring = m_decimalFormat->getDecimalFormatSymbols()->getSymbol(symbol);
-    m_decimalSymbols[index] = String(ustring.getBuffer(), ustring.length());
+    UErrorCode status = U_ZERO_ERROR;
+    int32_t bufferLength = unum_getSymbol(m_numberFormat, symbol, 0, 0, &status);
+    ASSERT(U_SUCCESS(status) || status == U_BUFFER_OVERFLOW_ERROR);
+    if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR)
+        return;
+    Vector<UChar> buffer(bufferLength);
+    status = U_ZERO_ERROR;
+    unum_getSymbol(m_numberFormat, symbol, buffer.data(), bufferLength, &status);
+    if (U_FAILURE(status))
+        return;
+    m_decimalSymbols[index] = String::adopt(buffer);
 }
 
+void ICULocale::setDecimalTextAttribute(String& destination, UNumberFormatTextAttribute tag)
+{
+    UErrorCode status = U_ZERO_ERROR;
+    int32_t bufferLength = unum_getTextAttribute(m_numberFormat, tag, 0, 0, &status);
+    ASSERT(U_SUCCESS(status) || status == U_BUFFER_OVERFLOW_ERROR);
+    if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR)
+        return;
+    Vector<UChar> buffer(bufferLength);
+    status = U_ZERO_ERROR;
+    unum_getTextAttribute(m_numberFormat, tag, buffer.data(), bufferLength, &status);
+    ASSERT(U_SUCCESS(status));
+    if (U_FAILURE(status))
+        return;
+    destination = String::adopt(buffer);
+}
+
 void ICULocale::initializeDecimalFormat()
 {
     if (m_didCreateDecimalFormat)
         return;
     m_didCreateDecimalFormat = true;
     UErrorCode status = U_ZERO_ERROR;
-    NumberFormat* format = NumberFormat::createInstance(m_locale, NumberFormat::kNumberStyle, status);
+    m_numberFormat = unum_open(UNUM_DECIMAL, 0, 0, m_locale.data(), 0, &status);
     if (!U_SUCCESS(status))
         return;
-    m_decimalFormat = adoptPtr(static_cast<DecimalFormat*>(format));
 
-    setDecimalSymbol(0, DecimalFormatSymbols::kZeroDigitSymbol);
-    setDecimalSymbol(1, DecimalFormatSymbols::kOneDigitSymbol);
-    setDecimalSymbol(2, DecimalFormatSymbols::kTwoDigitSymbol);
-    setDecimalSymbol(3, DecimalFormatSymbols::kThreeDigitSymbol);
-    setDecimalSymbol(4, DecimalFormatSymbols::kFourDigitSymbol);
-    setDecimalSymbol(5, DecimalFormatSymbols::kFiveDigitSymbol);
-    setDecimalSymbol(6, DecimalFormatSymbols::kSixDigitSymbol);
-    setDecimalSymbol(7, DecimalFormatSymbols::kSevenDigitSymbol);
-    setDecimalSymbol(8, DecimalFormatSymbols::kEightDigitSymbol);
-    setDecimalSymbol(9, DecimalFormatSymbols::kNineDigitSymbol);
-    setDecimalSymbol(DecimalSeparatorIndex, DecimalFormatSymbols::kDecimalSeparatorSymbol);
-    setDecimalSymbol(GroupSeparatorIndex, DecimalFormatSymbols::kGroupingSeparatorSymbol);
+    setDecimalSymbol(0, UNUM_ZERO_DIGIT_SYMBOL);
+    setDecimalSymbol(1, UNUM_ONE_DIGIT_SYMBOL);
+    setDecimalSymbol(2, UNUM_TWO_DIGIT_SYMBOL);
+    setDecimalSymbol(3, UNUM_THREE_DIGIT_SYMBOL);
+    setDecimalSymbol(4, UNUM_FOUR_DIGIT_SYMBOL);
+    setDecimalSymbol(5, UNUM_FIVE_DIGIT_SYMBOL);
+    setDecimalSymbol(6, UNUM_SIX_DIGIT_SYMBOL);
+    setDecimalSymbol(7, UNUM_SEVEN_DIGIT_SYMBOL);
+    setDecimalSymbol(8, UNUM_EIGHT_DIGIT_SYMBOL);
+    setDecimalSymbol(9, UNUM_NINE_DIGIT_SYMBOL);
+    setDecimalSymbol(DecimalSeparatorIndex, UNUM_DECIMAL_SEPARATOR_SYMBOL);
+    setDecimalSymbol(GroupSeparatorIndex, UNUM_GROUPING_SEPARATOR_SYMBOL);
+    setDecimalTextAttribute(m_positivePrefix, UNUM_POSITIVE_PREFIX);
+    setDecimalTextAttribute(m_positiveSuffix, UNUM_POSITIVE_SUFFIX);
+    setDecimalTextAttribute(m_negativePrefix, UNUM_NEGATIVE_PREFIX);
+    setDecimalTextAttribute(m_negativeSuffix, UNUM_NEGATIVE_SUFFIX);
+    ASSERT(!m_positivePrefix.isEmpty() || !m_positiveSuffix.isEmpty() || !m_negativePrefix.isEmpty() || !m_negativeSuffix.isEmpty());
 }
 
 String ICULocale::convertToLocalizedNumber(const String& input)
 {
     initializeDecimalFormat();
-    if (!m_decimalFormat || input.isEmpty())
+    if (!m_numberFormat || input.isEmpty())
         return input;
 
     unsigned i = 0;
     bool isNegative = false;
     UnicodeString ustring;
+    StringBuilder builder;
+    builder.reserveCapacity(input.length());
 
     if (input[0] == '-') {
         ++i;
         isNegative = true;
-        m_decimalFormat->getNegativePrefix(ustring);
+        builder.append(m_negativePrefix);
     } else
-        m_decimalFormat->getPositivePrefix(ustring);
-    StringBuilder builder;
-    builder.reserveCapacity(input.length());
-    builder.append(ustring.getBuffer(), ustring.length());
+        builder.append(m_positivePrefix);
 
     for (; i < input.length(); ++i) {
         switch (input[i]) {
@@ -130,73 +162,45 @@
         }
     }
 
-    if (isNegative)
-        m_decimalFormat->getNegativeSuffix(ustring);
-    else
-        m_decimalFormat->getPositiveSuffix(ustring);
-    builder.append(ustring.getBuffer(), ustring.length());
+    builder.append(isNegative ? m_negativeSuffix : m_positiveSuffix);
 
     return builder.toString();
 }
 
-template <class StringType> static bool matches(const String& text, unsigned position, const StringType& part)
+static bool matches(const String& text, unsigned position, const String& part)
 {
     if (part.isEmpty())
         return true;
     if (position + part.length() > text.length())
         return false;
-    for (unsigned i = 0; i < static_cast<unsigned>(part.length()); ++i) {
+    for (unsigned i = 0; i < part.length(); ++i) {
         if (text[position + i] != part[i])
             return false;
     }
     return true;
 }
 
-static bool endsWith(const String& text, const UnicodeString& suffix)
-{
-    if (suffix.length() <= 0)
-        return true;
-    unsigned suffixLength = static_cast<unsigned>(suffix.length());
-    if (suffixLength > text.length())
-        return false;
-    unsigned start = text.length() - suffixLength;
-    for (unsigned i = 0; i < suffixLength; ++i) {
-        if (text[start + i] != suffix[i])
-            return false;
-    }
-    return true;
-}
-
 bool ICULocale::detectSignAndGetDigitRange(const String& input, bool& isNegative, unsigned& startIndex, unsigned& endIndex)
 {
     startIndex = 0;
     endIndex = input.length();
-    UnicodeString prefix;
-    m_decimalFormat->getNegativePrefix(prefix);
-    UnicodeString suffix;
-    m_decimalFormat->getNegativeSuffix(suffix);
-    if (prefix.isEmpty() && suffix.isEmpty()) {
-        m_decimalFormat->getPositivePrefix(prefix);
-        m_decimalFormat->getPositiveSuffix(suffix);
-        ASSERT(!(prefix.isEmpty() && suffix.isEmpty()));
-        if (matches(input, 0, prefix) && endsWith(input, suffix)) {
+    if (m_negativePrefix.isEmpty() && m_negativeSuffix.isEmpty()) {
+        if (input.startsWith(m_positivePrefix) && input.endsWith(m_positiveSuffix)) {
             isNegative = false;
-            startIndex = prefix.length();
-            endIndex -= suffix.length();
+            startIndex = m_positivePrefix.length();
+            endIndex -= m_positiveSuffix.length();
         } else
             isNegative = true;
     } else {
-        if (matches(input, 0, prefix) && endsWith(input, suffix)) {
+        if (input.startsWith(m_negativePrefix) && input.endsWith(m_negativeSuffix)) {
             isNegative = true;
-            startIndex = prefix.length();
-            endIndex -= suffix.length();
+            startIndex = m_negativePrefix.length();
+            endIndex -= m_negativeSuffix.length();
         } else {
             isNegative = false;
-            m_decimalFormat->getPositivePrefix(prefix);
-            m_decimalFormat->getPositiveSuffix(suffix);
-            if (matches(input, 0, prefix) && endsWith(input, suffix)) {
-                startIndex = prefix.length();
-                endIndex -= suffix.length();
+            if (input.startsWith(m_positivePrefix) && input.endsWith(m_positiveSuffix)) {
+                startIndex = m_positivePrefix.length();
+                endIndex -= m_positiveSuffix.length();
             } else
                 return false;
         }
@@ -219,7 +223,7 @@
 {
     initializeDecimalFormat();
     String input = localized.stripWhiteSpace();
-    if (!m_decimalFormat || input.isEmpty())
+    if (!m_numberFormat || input.isEmpty())
         return input;
 
     bool isNegative;

Modified: trunk/Source/WebCore/platform/text/LocalizedNumberICU.h (110413 => 110414)


--- trunk/Source/WebCore/platform/text/LocalizedNumberICU.h	2012-03-12 08:32:08 UTC (rev 110413)
+++ trunk/Source/WebCore/platform/text/LocalizedNumberICU.h	2012-03-12 08:38:05 UTC (rev 110414)
@@ -31,9 +31,10 @@
 #ifndef LocalizedNumberICU_h
 #define LocalizedNumberICU_h
 
-#include <unicode/decimfmt.h>
+#include <unicode/unum.h>
 #include <wtf/Forward.h>
 #include <wtf/OwnPtr.h>
+#include <wtf/text/CString.h>
 #include <wtf/text/WTFString.h>
 
 namespace WebCore {
@@ -43,19 +44,21 @@
 public:
     static PassOwnPtr<ICULocale> create(const char* localeString);
     static PassOwnPtr<ICULocale> createForCurrentLocale();
+    ~ICULocale();
     String convertToLocalizedNumber(const String&);
     String convertFromLocalizedNumber(const String&);
 
 private:
-    explicit ICULocale(const icu::Locale&);
-    void setDecimalSymbol(unsigned index, icu::DecimalFormatSymbols::ENumberFormatSymbol);
+    explicit ICULocale(const char*);
+    void setDecimalSymbol(unsigned index, UNumberFormatSymbol);
+    void setDecimalTextAttribute(String&, UNumberFormatTextAttribute);
     void initializeDecimalFormat();
 
     bool detectSignAndGetDigitRange(const String& input, bool& isNegative, unsigned& startIndex, unsigned& endIndex);
     unsigned matchedDecimalSymbolIndex(const String& input, unsigned& position);
 
-    icu::Locale m_locale;
-    OwnPtr<icu::DecimalFormat> m_decimalFormat;
+    CString m_locale;
+    UNumberFormat* m_numberFormat;
     enum {
         // 0-9 for digits.
         DecimalSeparatorIndex = 10,
@@ -63,6 +66,10 @@
         DecimalSymbolsSize
     };
     String m_decimalSymbols[DecimalSymbolsSize];
+    String m_positivePrefix;
+    String m_positiveSuffix;
+    String m_negativePrefix;
+    String m_negativeSuffix;
     bool m_didCreateDecimalFormat;
 };
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to