]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/i18n/unicode/msgfmt.h
ICU-400.42.tar.gz
[apple/icu.git] / icuSources / i18n / unicode / msgfmt.h
index 815cabbb94458ba445fa0d7eaf9e988b5906c86c..67e17cf0ef8ca2035075e2c868522a1fc057d497 100644 (file)
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 1997-2006, International Business Machines Corporation and others. All Rights Reserved.
+* Copyright (C) 2007-2008, International Business Machines Corporation and others. All Rights Reserved.
 ********************************************************************************
 *
 * File MSGFMT.H
@@ -29,6 +29,7 @@
 #include "unicode/format.h"
 #include "unicode/locid.h"
 #include "unicode/parseerr.h"
+#include "unicode/uchar.h"
 
 U_NAMESPACE_BEGIN
 
@@ -58,6 +59,42 @@ class DateFormat;
  * formats it into a string.  The resultant strings are then assembled
  * within the string template of the MessageFormat to produce the
  * final output string.
+ * <p>
+ * <strong>Note:</strong>
+ * In ICU 4.0 MessageFormat supports named arguments.  If a named argument
+ * is used, all arguments must be named.  Names start with a character in 
+ * <code>UCHAR_ID_START</code> and continue with characters in 
+ * <code>UCHARID_CONTINUE</code>, in particular they do not start with a digit.
+ * If named arguments are used, {@link #usesNamedArguments()} will return true.
+ * <p>
+ * The other new methods supporting named arguments are 
+ * {@link #getFormatNames(UErrorCode& status)},
+ * {@link #getFormat(const UnicodeString& formatName, UErrorCode& status)}
+ * {@link #setFormat(const UnicodeString& formatName, const Format& format, UErrorCode& status)},
+ * {@link #adoptFormat(const UnicodeString& formatName, Format* formatToAdopt, UErrorCode& status)},
+ * {@link #format(const Formattable* arguments, const UnicodeString *argumentNames, int32_t cnt, UnicodeString& appendTo, FieldPosition& status, int32_t recursionProtection, UErrorCode& success)},
+ * {@link #format(const UnicodeString* argumentNames, const Formattable* arguments, int32_t count, UnicodeString& appendTo,UErrorCode& status)}.
+ * These methods are all compatible with patterns that do not used named arguments-- 
+ * in these cases the keys in the input or output use <code>UnicodeString</code>s 
+ * that name the argument indices, e.g. "0", "1", "2"... etc.
+ * <p>
+ * When named arguments are used, certain methods on MessageFormat that take or
+ * return arrays do not perform any action, since it is not possible to
+ * identify positions in an array using a name.  UErrorCode is set to
+ * U_ARGUMENT_TYPE_MISMATCH if there is a status/success field in the method.
+ * These methods are 
+ * {@link #adoptFormats(Format** newFormats, int32_t count)},
+ * {@link #setFormats(const Format** newFormats,int32_t count)},
+ * {@link #adoptFormat(int32_t n, Format *newFormat)},
+ * {@link #getFormats(int32_t& cnt)},
+ * {@link #format(const Formattable* source,int32_t cnt,UnicodeString& appendTo, FieldPosition& ignore, UErrorCode& success)},
+ * {@link #format(const UnicodeString& pattern,const Formattable* arguments,int32_t cnt,UnicodeString& appendTo,UErrorCode& success)},
+ * {@link #format(const Formattable& source, UnicodeString& appendTo,FieldPosition& ignore, UErrorCode& success)},
+ * {@link #format(const Formattable* arguments, int32_t cnt, UnicodeString& appendTo, FieldPosition& status, int32_t recursionProtection,UErrorCode& success)},
+ * {@link #parse(const UnicodeString& source, ParsePosition& pos,int32_t& count)},
+ * {@link #parse(const UnicodeString& source, int32_t& cnt, UErrorCode& status)}
+ * <p>
+ *
  * <P>
  * During parsing, an input string is matched against the string
  * template of the MessageFormat to produce an array of Formattable
@@ -147,7 +184,7 @@ class DateFormat;
  *  \code
  *       messageFormatPattern := string ( "{" messageFormatElement "}" string )*
  *
- *       messageFormatElement := argumentIndex { "," elementFormat }
+ *       messageFormatElement := argumentIndex | argumentName { "," elementFormat }
  *
  *       elementFormat := "time" { "," datetimeStyle }
  *                      | "date" { "," datetimeStyle }
@@ -166,6 +203,8 @@ class DateFormat;
  *                      | numberFormatPattern
  *
  *       choiceStyle :=   choiceFormatPattern
+ * 
+ *       pluralStyle := pluralFormatPattern
  * \endcode
  * </pre>
  * If there is no elementFormat, then the argument must be a string,
@@ -427,7 +466,7 @@ public:
      * @param newFormats the new format to be set.
      * @param cnt        the size of the array.
      */
-    virtual void setFormats(const Format** newFormats,int32_t cnt);
+    virtual void setFormats(const Format** newFormats, int32_t cnt);
 
 
     /**
@@ -453,6 +492,63 @@ public:
      */
     virtual void setFormat(int32_t formatNumber, const Format& format);
 
+    /**
+     * Gets format names. This function returns formatNames in StringEnumerations
+     * which can be used with getFormat() and setFormat() to export formattable 
+     * array from current MessageFormat to another.  It is caller's resposibility 
+     * to delete the returned formatNames.
+     * @param status  output param set to success/failure code.
+     * @draft ICU 4.0
+     */
+    virtual StringEnumeration* getFormatNames(UErrorCode& status);
+    
+    /**
+     * Gets subformat pointer for given format name.   
+     * This function supports both named and numbered
+     * arguments-- if numbered, the formatName is the
+     * corresponding UnicodeStrings (e.g. "0", "1", "2"...).
+     * The returned Format object should not be deleted by the caller,
+     * nor should the ponter of other object .  The pointer and its 
+     * contents remain valid only until the next call to any method
+     * of this class is made with this object. 
+     * @param formatName the name or number specifying a format
+     * @param status  output param set to success/failure code.
+     * @draft ICU 4.0
+     */
+    virtual Format* getFormat(const UnicodeString& formatName, UErrorCode& status);
+    
+    /**
+     * Sets one subformat for given format name.
+     * See the class description about format name. 
+     * This function supports both named and numbered
+     * arguments-- if numbered, the formatName is the
+     * corresponding UnicodeStrings (e.g. "0", "1", "2"...).
+     * If there is no matched formatName or wrong type,
+     * the item will be ignored.
+     * @param formatName  Name of the subformat.
+     * @param format      the format to be set.
+     * @param status  output param set to success/failure code.
+     * @draft ICU 4.0
+     */
+    virtual void setFormat(const UnicodeString& formatName, const Format& format, UErrorCode& status);
+    
+    /**
+     * Sets one subformat for given format name.
+     * See the class description about format name. 
+     * This function supports both named and numbered
+     * arguments-- if numbered, the formatName is the
+     * corresponding UnicodeStrings (e.g. "0", "1", "2"...).
+     * If there is no matched formatName or wrong type,
+     * the item will be ignored.
+     * The caller should not delete the Format object after this call.
+     * @param formatName  Name of the subformat.
+     * @param formatToAdopt  Format to be adopted.
+     * @param status      output param set to success/failure code.
+     * @draft ICU 4.0
+     */
+    virtual void adoptFormat(const UnicodeString& formatName, Format* formatToAdopt, UErrorCode& status);
+
+
     /**
      * Gets an array of subformats of this object.  The returned array
      * should not be deleted by the caller, nor should the pointers
@@ -500,11 +596,11 @@ public:
      * @return          Reference to 'appendTo' parameter.
      * @stable ICU 2.0
      */
-    static UnicodeString& format(   const UnicodeString& pattern,
-                                    const Formattable* arguments,
-                                    int32_t count,
-                                    UnicodeString& appendTo,
-                                    UErrorCode& status);
+    static UnicodeString& format(const UnicodeString& pattern,
+                                 const Formattable* arguments,
+                                 int32_t count,
+                                 UnicodeString& appendTo,
+                                 UErrorCode& status);
 
     /**
      * Formats the given array of arguments into a user-readable
@@ -545,7 +641,31 @@ public:
     UnicodeString& format(const Formattable& obj,
                           UnicodeString& appendTo,
                           UErrorCode& status) const;
+    
 
+    /**
+     * Formats the given array of arguments into a user-defined argument name
+     * array. This function supports both named and numbered
+     * arguments-- if numbered, the formatName is the
+     * corresponding UnicodeStrings (e.g. "0", "1", "2"...).
+     *
+     * @param argumentNames argument name array
+     * @param arguments An array of objects to be formatted.
+     * @param count     The number of elements of 'argumentNames' and 
+     *                  arguments.  The number of argumentNames and arguments
+     *                  must be the same.
+     * @param appendTo  Output parameter to receive result.
+     *                  Result is appended to existing contents.
+     * @param status    Input/output error code.  If the
+     *                  pattern cannot be parsed, set to failure code.
+     * @return          Reference to 'appendTo' parameter.
+     * @stable ICU 4.0
+     */
+    UnicodeString& format(const UnicodeString* argumentNames,
+                          const Formattable* arguments,
+                          int32_t count,
+                          UnicodeString& appendTo,
+                          UErrorCode& status) const;
     /**
      * Parses the given string into an array of output arguments.
      *
@@ -569,9 +689,12 @@ public:
      * @param source    String to be parsed.
      * @param count     Output param to receive size of returned array.
      * @param status    Input/output error code.  If the
-     *                  pattern cannot be parsed, set to failure code.
+     *                  pattern cannot be parsed, set to failure code. 
+     *                  If the MessageFormat is named argument, the status is 
+     *                  set to U_ARGUMENT_TYPE_MISMATCH.
      * @return an array of parsed arguments.  The caller owns both
-     * the array and its contents.
+     * the array and its contents. Return NULL if status is not U_ZERO_ERROR.
+     * 
      * @stable ICU 2.0
      */
     virtual Formattable* parse( const UnicodeString& source,
@@ -615,7 +738,16 @@ public:
      */
     static UnicodeString autoQuoteApostrophe(const UnicodeString& pattern, 
         UErrorCode& status);
-
+    
+    /**
+     * Returns true if this MessageFormat uses named arguments,
+     * and false otherwise.  See class description.
+     *
+     * @return true if named arguments are used.
+     * @draft ICU 4.0
+     */
+    UBool usesNamedArguments() const;
+    
     /**
      * Returns a unique class ID POLYMORPHICALLY.  Pure virtual override.
      * This method is to implement a simple version of RTTI, since not all
@@ -648,6 +780,8 @@ private:
     UnicodeString       fPattern;
     Format**            formatAliases; // see getFormats
     int32_t             formatAliasesCapacity;
+    UProperty           idStart;
+    UProperty           idContinue;
 
     MessageFormat(); // default constructor not implemented
 
@@ -658,51 +792,7 @@ private:
      * number corresponds to the array of arguments to be formatted.
      * @internal
      */
-    class Subformat {
-    public:
-        /**
-         * @internal 
-         */
-        Format* format; // formatter
-        /**
-         * @internal 
-         */
-        int32_t offset; // offset into fPattern
-        /**
-         * @internal 
-         */
-        int32_t arg;    // 0-based argument number
-
-        /**
-         * Clone that.format and assign it to this.format
-         * Do NOT delete this.format
-         * @internal
-         */
-        Subformat& operator=(const Subformat& that) {
-            format = that.format ? that.format->clone() : NULL;
-            offset = that.offset;
-            arg = that.arg;
-            return *this;
-        }
-
-        /**
-         * @internal 
-         */
-        UBool operator==(const Subformat& that) const {
-            // Do cheap comparisons first
-            return offset == that.offset &&
-                   arg == that.arg &&
-                   ((format == that.format) || // handles NULL
-                    (*format == *that.format));
-        }
-
-        /**
-         * @internal
-         */
-        UBool operator!=(const Subformat& that) const {
-            return !operator==(that);
-        }
-    };
+    class Subformat;
 
     /**
      * A MessageFormat contains an array of subformats.  This array
@@ -724,6 +814,12 @@ private:
     int32_t            argTypeCount;
     int32_t            argTypeCapacity;
 
+    /**
+      * Is true iff all argument names are non-negative numbers.
+      * 
+      */
+    UBool isArgNumeric;
+
     // Variable-size array management
     UBool allocateSubformats(int32_t capacity);
     UBool allocateArgTypes(int32_t capacity);
@@ -776,6 +872,14 @@ private:
                             FieldPosition& status,
                             int32_t recursionProtection,
                             UErrorCode& success) const;
+    
+    UnicodeString&  format( const Formattable* arguments, 
+                            const UnicodeString *argumentNames,
+                            int32_t cnt,
+                            UnicodeString& appendTo,
+                            FieldPosition& status,
+                            int32_t recursionProtection,
+                            UErrorCode& success) const;
 
     void             makeFormat(int32_t offsetNumber,
                                 UnicodeString* segments,
@@ -810,7 +914,14 @@ private:
         listCount = argTypeCount;
         return argTypes; 
     }
-
+    
+    /**
+     * Returns FALSE if the argument name is not legal.
+     * @param  argName   argument name.
+     * @return TRUE if the argument name is legal, otherwise return FALSE.
+     */
+    UBool isLegalArgName(const UnicodeString& argName) const;
+    
     friend class MessageFormatAdapter; // getFormatTypeList() access
 };