]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/i18n/msgfmt.cpp
ICU-6.2.4.tar.gz
[apple/icu.git] / icuSources / i18n / msgfmt.cpp
index 477a72debac68cd80edd32985150b4b7e43e3f48..5e639b282ca166aea3bab7cd00f4262ec791f566 100644 (file)
@@ -1,6 +1,6 @@
 /*
 *******************************************************************************
-* Copyright (C) 1997-2003, International Business Machines Corporation and    *
+* Copyright (C) 1997-2004, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 *
 #include "unicode/ustring.h"
 #include "unicode/ucnv_err.h"
 #include "unicode/uchar.h"
+#include "unicode/rbnf.h"
 #include "ustrfmt.h"
 #include "cmemory.h"
-#include "uprops.h"
+#include "util.h"
 #include "uassert.h"
 
 // *****************************************************************************
 //---------------------------------------
 // static data
 
+static const UChar ID_EMPTY[]     = {
+    0 /* empty string, used for default so that null can mark end of list */
+};
+
 static const UChar ID_NUMBER[]    = {
     0x6E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0  /* "number" */
 };
@@ -60,14 +65,27 @@ static const UChar ID_TIME[]      = {
 static const UChar ID_CHOICE[]    = {
     0x63, 0x68, 0x6F, 0x69, 0x63, 0x65, 0  /* "choice" */
 };
+static const UChar ID_SPELLOUT[]  = {
+    0x73, 0x70, 0x65, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0 /* "spellout" */
+};
+static const UChar ID_ORDINAL[]   = {
+    0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0 /* "ordinal" */
+};
+static const UChar ID_DURATION[]  = {
+    0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0 /* "duration" */
+};
 
 // MessageFormat Type List  Number, Date, Time or Choice
 static const UChar * const TYPE_IDS[] = {
-    NULL,
+    ID_EMPTY,
     ID_NUMBER,
     ID_DATE,    
     ID_TIME,
-    ID_CHOICE
+    ID_CHOICE,
+    ID_SPELLOUT,
+    ID_ORDINAL,
+    ID_DURATION,
+    NULL,
 };
  
 static const UChar ID_CURRENCY[]  = {
@@ -82,13 +100,13 @@ static const UChar ID_INTEGER[]   = {
 
 // NumberFormat modifier list, default, currency, percent or integer
 static const UChar * const NUMBER_STYLE_IDS[] = {
-    NULL,
+    ID_EMPTY,
     ID_CURRENCY,
     ID_PERCENT,
     ID_INTEGER,
     NULL,
 };
+
 static const UChar ID_SHORT[]     = {
     0x73, 0x68, 0x6F, 0x72, 0x74, 0        /* "short" */
 };
@@ -104,11 +122,12 @@ static const UChar ID_FULL[]      = {
 
 // DateFormat modifier list, default, short, medium, long or full
 static const UChar * const DATE_STYLE_IDS[] = {
-    NULL,
+    ID_EMPTY,
     ID_SHORT,
     ID_MEDIUM,
     ID_LONG,
-    ID_FULL
+    ID_FULL,
+    NULL,
 };
  
 static const DateFormat::EStyle DATE_STYLES[] = {
@@ -119,14 +138,12 @@ static const DateFormat::EStyle DATE_STYLES[] = {
     DateFormat::kFull,
 };
 
-static const int32_t ID_LIST_LENGTH = 5;
-
 static const int32_t DEFAULT_INITIAL_CAPACITY = 10;
 
 U_NAMESPACE_BEGIN
 
 // -------------------------------------
-const char MessageFormat::fgClassID = 0; // Value is irrelevant
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(MessageFormat)
 
 //--------------------------------------------------------------------
 
@@ -187,6 +204,7 @@ MessageFormat::MessageFormat(const UnicodeString& pattern,
         return;
     }
     applyPattern(pattern, success);
+    setLocaleIDs(fLocale.getName(), fLocale.getName());
 }
  
 MessageFormat::MessageFormat(const UnicodeString& pattern,
@@ -210,6 +228,7 @@ MessageFormat::MessageFormat(const UnicodeString& pattern,
         return;
     }
     applyPattern(pattern, success);
+    setLocaleIDs(fLocale.getName(), fLocale.getName());
 }
 
 MessageFormat::MessageFormat(const UnicodeString& pattern,
@@ -234,6 +253,7 @@ MessageFormat::MessageFormat(const UnicodeString& pattern,
         return;
     }
     applyPattern(pattern, parseError, success);
+    setLocaleIDs(fLocale.getName(), fLocale.getName());
 }
 
 MessageFormat::MessageFormat(const MessageFormat& that)
@@ -389,7 +409,6 @@ MessageFormat::operator==(const Format& rhs) const
 
     // Check class ID before checking MessageFormat members
     if (!Format::operator==(rhs) ||
-        getDynamicClassID() != that.getDynamicClassID() ||
         fPattern != that.fPattern ||
         fLocale != that.fLocale) {
         return FALSE;
@@ -427,6 +446,7 @@ MessageFormat::setLocale(const Locale& theLocale)
         defaultDateFormat = NULL;
     }
     fLocale = theLocale;
+    setLocaleIDs(fLocale.getName(), fLocale.getName());
 }
  
 // -------------------------------------
@@ -975,15 +995,20 @@ MessageFormat::format(const Formattable* arguments,
             }
         }
         // If the obj data type is a number, use a NumberFormat instance.
-        else if ((type == Formattable::kDouble) || (type == Formattable::kLong)) {
+        else if ((type == Formattable::kDouble) || 
+                 (type == Formattable::kLong) ||
+                 (type == Formattable::kInt64)) {
+
             const NumberFormat* nf = getDefaultNumberFormat(success);
             if (nf == NULL) { 
                 return appendTo; 
             }
             if (type == Formattable::kDouble) {
                 nf->format(obj->getDouble(), appendTo);
-            } else {
+            } else if (type == Formattable::kLong) {
                 nf->format(obj->getLong(), appendTo);
+            } else {
+                nf->format(obj->getInt64(), appendTo);
             }
         }
         // If the obj data type is a Date instance, use a DateFormat instance.
@@ -1145,6 +1170,17 @@ MessageFormat::parseObject( const UnicodeString& source,
 }
   
 // -------------------------------------
+
+static Format* makeRBNF(URBNFRuleSetTag tag, const Locale& locale, const UnicodeString& defaultRuleSet, UErrorCode& ec) {
+    RuleBasedNumberFormat* fmt = new RuleBasedNumberFormat(tag, locale, ec);
+    if (U_SUCCESS(ec) && defaultRuleSet.length() > 0) {
+        fmt->setDefaultRuleSet(defaultRuleSet, ec);
+    if (U_FAILURE(ec)) { // ignore unrecognized default rule set
+        ec = U_ZERO_ERROR;
+    }
+    }
+    return fmt;
+}
  
 /**
  * Reads the segments[] array (see applyPattern()) and parses the
@@ -1238,6 +1274,18 @@ MessageFormat::makeFormat(int32_t formatNumber,
         fmt = new ChoiceFormat(segments[3], parseError, ec);
         break;
 
+    case 5: // spellout
+        argType = Formattable::kDouble;
+        fmt = makeRBNF(URBNF_SPELLOUT, fLocale, segments[3], ec);
+        break;
+    case 6: // ordinal
+        argType = Formattable::kDouble;
+        fmt = makeRBNF(URBNF_ORDINAL, fLocale, segments[3], ec);
+        break;
+    case 7: // duration
+        argType = Formattable::kDouble;
+        fmt = makeRBNF(URBNF_DURATION, fLocale, segments[3], ec);
+        break;
     default:
         argType = Formattable::kString;
         ec = U_ILLEGAL_ARGUMENT_ERROR;
@@ -1278,15 +1326,16 @@ int32_t MessageFormat::findKeyword(const UnicodeString& s,
                                    const UChar * const *list)
 {
     if (s.length() == 0)
-        return 0;
+        return 0; // default
 
     UnicodeString buffer = s;
     // Trims the space characters and turns all characters
     // in s to lower case.
     buffer.trim().toLower();
-    for (int32_t i = 0; i < ID_LIST_LENGTH; ++i) {
-        if (list[i] && !buffer.compare(list[i], u_strlen(list[i]))) 
+    for (int32_t i = 0; list[i]; ++i) {
+        if (!buffer.compare(list[i], u_strlen(list[i]))) {
             return i;
+        }
     }
     return -1;
 }