[haiku-commits] r36176 - in haiku/branches/developer/zooey/posix-locale/src: system/libroot/posix/locale tests/system/libroot/posix

Author: zooey
Date: 2010-04-12 01:56:02 +0200 (Mon, 12 Apr 2010)
New Revision: 36176
Changeset: http://dev.haiku-os.org/changeset/36176/haiku

Modified:
   
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/ICULocaleBackend.cpp
   
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/ICULocaleBackend.h
   
haiku/branches/developer/zooey/posix-locale/src/tests/system/libroot/posix/locale_test.cpp
Log:
* finished implementation of monetary locale data fetching

Modified: 
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/ICULocaleBackend.cpp
===================================================================
--- 
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/ICULocaleBackend.cpp
    2010-04-11 23:00:25 UTC (rev 36175)
+++ 
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/ICULocaleBackend.cpp
    2010-04-11 23:56:02 UTC (rev 36176)
@@ -205,9 +205,9 @@
 
        if (result == B_OK) {
                UErrorCode icuStatus = U_ZERO_ERROR;
+               UChar currencySeparatorChar = CHAR_MAX;
                DecimalFormat* currencyFormat = dynamic_cast<DecimalFormat*>(
-                       NumberFormat::createInstance(locale, 
DecimalFormat::kCurrencyStyle,
-                               icuStatus));
+                       NumberFormat::createCurrencyInstance(locale, 
icuStatus));
                if (!U_SUCCESS(icuStatus))
                        return B_UNSUPPORTED;
                if (!currencyFormat)
@@ -242,19 +242,6 @@
                        }
                }
                if (result == B_OK) {
-                       result = _SetLocaleconvEntry(formatSymbols, 
sIntCurrSymbol,
-                               DecimalFormatSymbols::kIntlCurrencySymbol);
-               }
-               if (result == B_OK) {
-                       result = _SetLocaleconvEntry(formatSymbols, 
sCurrencySymbol,
-                               DecimalFormatSymbols::kCurrencySymbol);
-                       if (sCurrencySymbol[0] == '\0') {
-                               // fall back to the international currency 
symbol
-                               result = _SetLocaleconvEntry(formatSymbols, 
sCurrencySymbol,
-                                       
DecimalFormatSymbols::kIntlCurrencySymbol);
-                       }
-               }
-               if (result == B_OK) {
                        result = _SetLocaleconvEntry(formatSymbols, 
sPositiveSign,
                                DecimalFormatSymbols::kPlusSignSymbol);
                }
@@ -268,7 +255,70 @@
                        sLocaleConv.frac_digits
                                = currencyFormat->getMinimumFractionDigits();
                }
+               if (result == B_OK) {
+                       UnicodeString positivePrefix, positiveSuffix, 
negativePrefix,
+                               negativeSuffix;
+                       currencyFormat->getPositivePrefix(positivePrefix);
+                       currencyFormat->getPositiveSuffix(positiveSuffix);
+                       currencyFormat->getNegativePrefix(negativePrefix);
+                       currencyFormat->getNegativeSuffix(negativeSuffix);
+                       UnicodeString currencySymbol = formatSymbols->getSymbol(
+                               DecimalFormatSymbols::kCurrencySymbol);
+                       UnicodeString plusSymbol = formatSymbols->getSymbol(
+                               DecimalFormatSymbols::kPlusSignSymbol);
+                       UnicodeString minusSymbol = formatSymbols->getSymbol(
+                               DecimalFormatSymbols::kMinusSignSymbol);
 
+                       int32 positiveCurrencyFlags = 
_DetermineCurrencyPosAndSeparator(
+                               positivePrefix, positiveSuffix, plusSymbol, 
currencySymbol,
+                               currencySeparatorChar
+                       );
+                       sLocaleConv.p_cs_precedes
+                               = (positiveCurrencyFlags & kCsPrecedesFlag) ? 1 
: 0;
+                       sLocaleConv.p_sep_by_space
+                               = (positiveCurrencyFlags & kSepBySpaceFlag) ? 1 
: 0;
+
+                       int32 negativeCurrencyFlags = 
_DetermineCurrencyPosAndSeparator(
+                               negativePrefix, negativeSuffix, minusSymbol, 
currencySymbol,
+                               currencySeparatorChar
+                       );
+                       sLocaleConv.n_cs_precedes
+                               = (negativeCurrencyFlags & kCsPrecedesFlag) ? 1 
: 0;
+                       sLocaleConv.n_sep_by_space
+                               = (negativeCurrencyFlags & kSepBySpaceFlag) ? 1 
: 0;
+
+                       sLocaleConv.p_sign_posn = 
_DetermineSignPos(positivePrefix,
+                               positiveSuffix, plusSymbol, currencySymbol);
+                       sLocaleConv.n_sign_posn = 
_DetermineSignPos(negativePrefix,
+                               negativeSuffix, minusSymbol, currencySymbol);
+                       if (sLocaleConv.p_sign_posn == CHAR_MAX) {
+                               // usually there is no positive sign indicator, 
so we
+                               // remove the character ...
+                               sPositiveSign[0] = '\0';
+                               // ... and adopt the sign pos of the negative 
sign symbol
+                               sLocaleConv.p_sign_posn = 
sLocaleConv.n_sign_posn;
+                       }
+               }
+               if (result == B_OK) {
+                       UnicodeString intCurrencySymbol = 
formatSymbols->getSymbol(
+                               DecimalFormatSymbols::kIntlCurrencySymbol);
+                       if (currencySeparatorChar != CHAR_MAX)
+                               intCurrencySymbol += currencySeparatorChar;
+                       result = 
_ConvertUnicodeStringToLocaleconvEntry(intCurrencySymbol,
+                               sIntCurrSymbol);
+               }
+               if (result == B_OK) {
+                       result = _SetLocaleconvEntry(formatSymbols, 
sCurrencySymbol,
+                               DecimalFormatSymbols::kCurrencySymbol);
+                       if (sCurrencySymbol[0] == '\0') {
+                               // fall back to the international currency 
symbol
+                               result = _SetLocaleconvEntry(formatSymbols, 
sCurrencySymbol,
+                                       
DecimalFormatSymbols::kIntlCurrencySymbol);
+                               sCurrencySymbol[3] = '\0';
+                                       // drop separator char that's contained 
in int-curr-symbol
+                       }
+               }
+
                delete currencyFormat;
        }
 
@@ -276,6 +326,91 @@
 }
 
 
+int32
+MonetaryData::_DetermineCurrencyPosAndSeparator(const UnicodeString& prefix,
+       const UnicodeString& suffix, const UnicodeString& signSymbol,
+       const UnicodeString& currencySymbol, UChar& currencySeparatorChar)
+{
+       int32 result = 0;
+
+       int32 currencySymbolPos = prefix.indexOf(currencySymbol);
+       if (currencySymbolPos > -1) {
+               int32 signSymbolPos = prefix.indexOf(signSymbol);
+               result |= kCsPrecedesFlag;
+               // if a char is following the currency symbol, we assume it's
+               // the separator (usually space), but we need to take care to
+               // skip over the sign symbol, if found
+               int32 potentialSeparatorPos
+                       = currencySymbolPos + currencySymbol.length();
+               if (potentialSeparatorPos == signSymbolPos)
+                       potentialSeparatorPos++;
+               currencySeparatorChar = prefix.charAt(potentialSeparatorPos);
+               if (currencySeparatorChar != 0xFFFF)
+                       result |= kSepBySpaceFlag;
+       } else {
+               currencySymbolPos = suffix.indexOf(currencySymbol);
+               if (currencySymbolPos > -1) {
+                       int32 signSymbolPos = suffix.indexOf(signSymbol);
+                       // if a char is preceding the currency symbol, we assume
+                       // it's the separator (usually space), but we need to 
take
+                       // care to skip the sign symbol, if found
+                       int32 potentialSeparatorPos = currencySymbolPos - 1;
+                       if (potentialSeparatorPos == signSymbolPos)
+                               potentialSeparatorPos--;
+                       currencySeparatorChar = 
suffix.charAt(potentialSeparatorPos);
+                       if (currencySeparatorChar != 0xFFFF)
+                               result |= kSepBySpaceFlag;
+               }
+       }
+
+       return result;
+}
+
+
+/*
+ * This method determines the <>_sign_posn value according to the following
+ * map (where '$' indicated the currency symbol, '#' the number value, and
+ * '-' the sign symbol [or alternatively the paranthesis]):
+ *             ($#)    ->      0
+ *             (#$)    ->      0
+ *             -$#     ->      1
+ *             -#$             ->      1
+ *             $-#             ->      4
+ *             $#-             ->      2
+ *             #$-             ->      2
+ *             #-$             ->      3
+ */
+int32
+MonetaryData::_DetermineSignPos(const UnicodeString& prefix,
+       const UnicodeString& suffix, const UnicodeString& signSymbol,
+       const UnicodeString& currencySymbol)
+{
+       if (prefix.indexOf(UnicodeString("(", "")) >= 0
+               && suffix.indexOf(UnicodeString(")", "")) >= 0)
+               return 0;       // parentheses around currency and value
+
+       UnicodeString value("#", "");
+       UnicodeString prefixNumberSuffixString = prefix + value + suffix;
+       int32 signSymbolPos = prefixNumberSuffixString.indexOf(signSymbol);
+       if (signSymbolPos >= 0) {
+               int32 valuePos = prefixNumberSuffixString.indexOf(value);
+               int32 currencySymbolPos
+                       = prefixNumberSuffixString.indexOf(currencySymbol);
+
+               if (signSymbolPos < valuePos && signSymbolPos < 
currencySymbolPos)
+                       return 1;       // sign precedes currency and value
+               if (signSymbolPos > valuePos && signSymbolPos > 
currencySymbolPos)
+                       return 2;       // sign succeeds currency and value
+               if (signSymbolPos == currencySymbolPos - 1)
+                       return 3;       // sign immediately precedes currency
+               if (signSymbolPos == currencySymbolPos + 
currencySymbol.length())
+                       return 4;       // sign immediately succeeds currency
+       }
+
+       return CHAR_MAX;
+}
+
+
 status_t
 NumericData::SetTo(const Locale& locale, const char* posixLocaleName)
 {

Modified: 
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/ICULocaleBackend.h
===================================================================
--- 
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/ICULocaleBackend.h
      2010-04-11 23:00:25 UTC (rev 36175)
+++ 
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/ICULocaleBackend.h
      2010-04-11 23:56:02 UTC (rev 36176)
@@ -84,6 +84,21 @@
 public:
 virtual                status_t                        SetTo(const Locale& 
locale,
                                                                        const 
char* posixLocaleName);
+
+private:
+static         const int32                     kCsPrecedesFlag = 1 << 0;
+static         const int32                     kSepBySpaceFlag = 1 << 1;
+
+                       int32                           
_DetermineCurrencyPosAndSeparator(
+                                                                       const 
UnicodeString& prefix,
+                                                                       const 
UnicodeString& suffix,
+                                                                       const 
UnicodeString& signSymbol,
+                                                                       const 
UnicodeString& currencySymbol,
+                                                                       UChar& 
currencySeparatorChar);
+                       int32                           _DetermineSignPos(const 
UnicodeString& prefix,
+                                                                       const 
UnicodeString& suffix,
+                                                                       const 
UnicodeString& signSymbol,
+                                                                       const 
UnicodeString& currencySymbol);
 };
 
 

Modified: 
haiku/branches/developer/zooey/posix-locale/src/tests/system/libroot/posix/locale_test.cpp
===================================================================
--- 
haiku/branches/developer/zooey/posix-locale/src/tests/system/libroot/posix/locale_test.cpp
  2010-04-11 23:00:25 UTC (rev 36175)
+++ 
haiku/branches/developer/zooey/posix-locale/src/tests/system/libroot/posix/locale_test.cpp
  2010-04-11 23:56:02 UTC (rev 36176)
@@ -58,9 +58,11 @@
                "de_DE.iso8859-1",
                "hr_HR.ISO-8859-2",
                "de_CH",
+               "gu_IN",
                "it_IT",
                "nl_NL",
                "nb_NO",
+               "nb_NO.utf-8",
                "POSIX",
                NULL
        };
@@ -85,6 +87,14 @@
                        printf("\n");
                        printf("\tlc.positive_sign: '%s'\n", lc->positive_sign);
                        printf("\tlc.negative_sign: '%s'\n", lc->negative_sign);
+                       printf("\tlc.frac_digits: '%x'\n", lc->frac_digits);
+                       printf("\tlc.int_frac_digits: '%x'\n", 
lc->int_frac_digits);
+                       printf("\tlc.p_cs_precedes: '%x'\n", lc->p_cs_precedes);
+                       printf("\tlc.p_sep_by_space: '%x'\n", 
lc->p_sep_by_space);
+                       printf("\tlc.n_cs_precedes: '%x'\n", lc->n_cs_precedes);
+                       printf("\tlc.n_sep_by_space: '%x'\n", 
lc->n_sep_by_space);
+                       printf("\tlc.p_sign_posn: '%x'\n", lc->p_sign_posn);
+                       printf("\tlc.n_sign_posn: '%x'\n", lc->n_sign_posn);
                }
        }
 }


Other related posts:

  • » [haiku-commits] r36176 - in haiku/branches/developer/zooey/posix-locale/src: system/libroot/posix/locale tests/system/libroot/posix - zooey