home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / Programming / ICU / include / msgfmt.h < prev    next >
C/C++ Source or Header  |  1999-11-12  |  23KB  |  574 lines

  1. /*
  2. ********************************************************************************
  3. *                                                                              *
  4. * COPYRIGHT:                                                                   *
  5. *   (C) Copyright Taligent, Inc.,  1997                                        *
  6. *   (C) Copyright International Business Machines Corporation,  1997-1999      *
  7. *   Copyright (C) 1999 Alan Liu and others. All rights reserved.               *
  8. *   Licensed Material - Program-Property of IBM - All Rights Reserved.         *
  9. *   US Government Users Restricted Rights - Use, duplication, or disclosure    *
  10. *   restricted by GSA ADP Schedule Contract with IBM Corp.                     *
  11. *                                                                              *
  12. ********************************************************************************
  13. *
  14. * File MSGFMT.H
  15. *
  16. * Modification History:
  17. *
  18. *   Date        Name        Description
  19. *   02/19/97    aliu        Converted from java.
  20. *   03/20/97    helena      Finished first cut of implementation.
  21. *    07/22/98    stephen        Removed operator!= (defined in Format)
  22. ********************************************************************************
  23. */
  24. // *****************************************************************************
  25. // This file was generated from the java source file MessageFormat.java
  26. // *****************************************************************************
  27.  
  28. #ifndef MSGFMT_H
  29. #define MSGFMT_H
  30.  
  31. #include "utypes.h"
  32. #include "format.h"
  33. #include "locid.h"
  34. class NumberFormat;
  35.  
  36. /**
  37.  * Provides means to produce concatenated messages in language-neutral way.
  38.  * Use this for all concatenations that show up to end users.
  39.  * <P>
  40.  * Takes a set of objects, formats them, then inserts the formatted
  41.  * strings into the pattern at the appropriate places.
  42.  * <P>
  43.  * Here are some examples of usage:
  44.  * Example 1:
  45.  * <pre>
  46.  * .    UErrorCode success = U_ZERO_ERROR;
  47.  * .    GregorianCalendar cal(success);
  48.  * .    Formattable arguments[] = {
  49.  * .        7L,
  50.  * .        Formattable( (Date) cal.getTime(success), Formattable::kIsDate),
  51.  * .        "a disturbance in the Force"
  52.  * .    };
  53.  * .    
  54.  * .    UnicodeString result;
  55.  * .    MessageFormat::format(
  56.  * .         "At {1,time} on {1,date}, there was {2} on planet {0,number}.",
  57.  * .         arguments, 3, result, success );
  58.  * .    
  59.  * .    cout << "result: " << result << endl;
  60.  * .    //<output>: At 4:34:20 PM on 23-Mar-98, there was a disturbance
  61.  * .    //             in the Force on planet 7.
  62.  * </pre>  
  63.  * Typically, the message format will come from resources, and the
  64.  * arguments will be dynamically set at runtime.
  65.  * <P>
  66.  * Example 2:
  67.  * <pre>
  68.  * .    success = U_ZERO_ERROR;
  69.  * .    Formattable testArgs[] = {3L, "MyDisk"};
  70.  * .   
  71.  * .    MessageFormat* form = new MessageFormat(
  72.  * .        "The disk \"{1}\" contains {0} file(s).", success );
  73.  * .        
  74.  * .    UnicodeString string;
  75.  * .    FieldPosition fpos = 0;
  76.  * .    cout << "format: " << form->format(testArgs, 2, string, fpos, success ) << endl;
  77.  * .
  78.  * .    // output, with different testArgs:
  79.  * .    // output: The disk "MyDisk" contains 0 file(s).
  80.  * .    // output: The disk "MyDisk" contains 1 file(s).
  81.  * .    // output: The disk "MyDisk" contains 1,273 file(s).
  82.  * .    de lete form;
  83.  *  </pre>
  84.  *
  85.  *  The pattern is of the following form.  Legend:
  86.  *  <pre>
  87.  * .      {optional item}
  88.  * .      (group that may be repeated)*
  89.  *  </pre>
  90.  *  Do not confuse optional items with items inside quotes braces, such
  91.  *  as this: "{".  Quoted braces are literals.
  92.  *  <pre>
  93.  * .      messageFormatPattern := string ( "{" messageFormatElement "}" string )*
  94.  * .       
  95.  * .      messageFormatElement := argument { "," elementFormat }
  96.  * .       
  97.  * .      elementFormat := "time" { "," datetimeStyle }
  98.  * .                     | "date" { "," datetimeStyle }
  99.  * .                     | "number" { "," numberStyle }
  100.  * .                     | "choice" "," choiceStyle
  101.  * .  
  102.  * .      datetimeStyle := "short"
  103.  * .                     | "medium"
  104.  * .                     | "long"
  105.  * .                     | "full"
  106.  * .                     | dateFormatPattern
  107.  * .
  108.  * .      numberStyle :=   "currency"
  109.  * .                     | "percent"
  110.  * .                     | "integer"
  111.  * .                     | numberFormatPattern
  112.  * . 
  113.  * .      choiceStyle :=   choiceFormatPattern
  114.  * </pre>
  115.  * If there is no elementFormat, then the argument must be a string,
  116.  * which is substituted. If there is no dateTimeStyle or numberStyle,
  117.  * then the default format is used (e.g.  NumberFormat.getInstance(),
  118.  * DateFormat.getDefaultTime() or DateFormat.getDefaultDate(). For
  119.  * a ChoiceFormat, the pattern must always be specified, since there
  120.  * is no default.
  121.  * <P>
  122.  * In strings, single quotes can be used to quote the "{" sign if
  123.  * necessary. A real single quote is represented by ''.  Inside a
  124.  * messageFormatElement, quotes are [not] removed. For example,
  125.  * {1,number,$'#',##} will produce a number format with the pound-sign
  126.  * quoted, with a result such as: "$#31,45".
  127.  * <P>
  128.  * If a pattern is used, then unquoted braces in the pattern, if any,
  129.  * must match: that is, "ab {0} de" and "ab '}' de" are ok, but "ab
  130.  * {0'}' de" and "ab } de" are not.
  131.  * <P>
  132.  * The argument is a number from 0 to 9, which corresponds to the
  133.  * arguments presented in an array to be formatted.
  134.  * <P>
  135.  * It is ok to have unused arguments in the array.  With missing
  136.  * arguments or arguments that are not of the right class for the
  137.  * specified format, a failing UErrorCode result is set.
  138.  * <P>
  139.  * For more sophisticated patterns, you can use a ChoiceFormat to get
  140.  * output such as:
  141.  * <pre>
  142.  * .    UErrorCode success = U_ZERO_ERROR;
  143.  * .    MessageFormat* form = new MessageFormat("The disk \"{1}\" contains {0}.", success);
  144.  * .    double filelimits[] = {0,1,2};
  145.  * .    UnicodeString filepart[] = {"no files","one file","{0,number} files"};
  146.  * .    ChoiceFormat* fileform = new ChoiceFormat(filelimits, filepart, 3);
  147.  * .    form->setFormat(1, *fileform); // NOT zero, see below
  148.  * .    
  149.  * .    Formattable testArgs[] = {1273L, "MyDisk"};
  150.  * .     
  151.  * .    UnicodeString string;
  152.  * .    FieldPosition fpos = 0;
  153.  * .    cout << form->format(testArgs, 2, string, fpos, success) << endl;
  154.  * .    
  155.  * .    // output, with different testArgs
  156.  * .    // output: The disk "MyDisk" contains no files.
  157.  * .    // output: The disk "MyDisk" contains one file.
  158.  * .    // output: The disk "MyDisk" contains 1,273 files.
  159.  * </pre>
  160.  * You can either do this programmatically, as in the above example,
  161.  * or by using a pattern (see ChoiceFormat for more information) as in:
  162.  * <pre>
  163.  * .   form->applyPattern(
  164.  * .     "There {0,choice,0#are no files|1#is one file|1<are {0,number,integer} files}.");
  165.  * </pre>
  166.  * <P>
  167.  * [Note:] As we see above, the string produced by a ChoiceFormat in
  168.  * MessageFormat is treated specially; occurances of '{' are used to
  169.  * indicated subformats, and cause recursion.  If you create both a
  170.  * MessageFormat and ChoiceFormat programmatically (instead of using
  171.  * the string patterns), then be careful not to produce a format that
  172.  * recurses on itself, which will cause an infinite loop.
  173.  * <P>
  174.  * [Note:] Formats are numbered by order of variable in the string.
  175.  * This is [not] the same as the argument numbering!
  176.  * <pre>
  177.  * .   For example: with "abc{2}def{3}ghi{0}...",
  178.  * .   
  179.  * .   format0 affects the first variable {2}
  180.  * .   format1 affects the second variable {3}
  181.  * .   format2 affects the second variable {0}
  182.  * </pre>
  183.  * and so on.
  184.  */
  185. class U_I18N_API MessageFormat : public Format {
  186. public:
  187.     enum EFormatNumber { kMaxFormat = 10 };
  188.     /**
  189.      * Construct a new MessageFormat using the given pattern.
  190.      *
  191.      * @param pattern   Pattern used to construct object.
  192.      * @param status    Output param to receive success code.  If the
  193.      *                  pattern cannot be parsed, set to failure code.
  194.      */
  195.     MessageFormat(const UnicodeString& pattern,
  196.                   UErrorCode &status);
  197.  
  198.     /**
  199.      * Constructor that allows locale specification.
  200.      * @param pattern   Pattern used to construct object.
  201.      * @param newLocale The locale to use for formatting dates and numbers.
  202.      * @param status    Output param to receive success code.  If the
  203.      *                  pattern cannot be parsed, set to failure code.
  204.      */
  205.     MessageFormat(const UnicodeString& pattern,
  206.                   const Locale& newLocale,
  207.                         UErrorCode& success);
  208.  
  209.     /**
  210.      * Copy constructor.
  211.      */
  212.     MessageFormat(const MessageFormat&);
  213.  
  214.     /**
  215.      * Assignment operator.
  216.      */
  217.     const MessageFormat& operator=(const MessageFormat&);
  218.  
  219.     /**
  220.      * Destructor.
  221.      */
  222.     virtual ~MessageFormat();
  223.  
  224.     /**
  225.      * Clone this Format object polymorphically. The caller owns the
  226.      * result and should delete it when done.
  227.      */
  228.     virtual Format* clone(void) const;
  229.  
  230.     /**
  231.      * Return true if the given Format objects are semantically equal.
  232.      * Objects of different subclasses are considered unequal.
  233.      */
  234.     virtual bool_t operator==(const Format& other) const;
  235.  
  236.     /**
  237.      * Sets the locale. This locale is used for fetching default number or date
  238.      * format information.
  239.      */
  240.     virtual void setLocale(const Locale& theLocale);
  241.  
  242.     /**
  243.      * Gets the locale. This locale is used for fetching default number or date
  244.      * format information.
  245.      */
  246.     virtual const Locale& getLocale(void) const;
  247.  
  248.     /**
  249.      * Apply the given pattern string to this message format.
  250.      *
  251.      * @param pattern   The pattern to be applied.
  252.      * @param status    Output param set to success/failure code on
  253.      *                  exit. If the pattern is invalid, this will be
  254.      *                  set to a failure result.
  255.      */
  256.     virtual void applyPattern(const UnicodeString& pattern,
  257.                               UErrorCode& status);
  258.  
  259.     /**
  260.      * Gets the pattern. See the class description.
  261.      */
  262.     virtual UnicodeString& toPattern(UnicodeString& result) const;
  263.  
  264.     /**
  265.      * Sets formats to use on parameters.
  266.      * See the class description about format numbering.
  267.      * The caller should not delete the Format objects after this call.
  268.      */
  269.     virtual void adoptFormats(Format** formatsToAdopt, int32_t count);
  270.  
  271.     /**
  272.      * Sets formats to use on parameters.
  273.      * See the class description about format numbering.
  274.      */
  275.     virtual void setFormats(const Format** newFormats,int32_t cnt);
  276.  
  277.  
  278.     /**
  279.      * Sets formats individually to use on parameters.
  280.      * See the class description about format numbering.
  281.      * The caller should not delete the Format object after this call.
  282.      */
  283.     virtual void adoptFormat(int32_t formatNumber, Format* formatToAdopt);
  284.  
  285.     /**
  286.      * Sets formats individually to use on parameters.
  287.      * See the class description about format numbering.
  288.      */
  289.     virtual void setFormat(int32_t variable, const Format& newFormat);
  290.  
  291.  
  292.     /**
  293.      * Gets formats that were set with setFormats.
  294.      * See the class description about format numbering.
  295.      */
  296.     virtual const Format** getFormats(int32_t& count) const;
  297.  
  298.     /**
  299.      * Returns pattern with formatted objects.  Does not take ownership
  300.      * of the Formattable* array; just reads it and uses it to generate
  301.      * the format string.
  302.      *
  303.      * @param source    An array of objects to be formatted & substituted.
  304.      * @param result    Where text is appended.
  305.      * @param ignore    No useful status is returned.
  306.      */
  307.     UnicodeString& format(  const Formattable* source,
  308.                             int32_t count,
  309.                             UnicodeString& result,
  310.                             FieldPosition& ignore,
  311.                             UErrorCode& success) const;
  312.  
  313.     /**
  314.      * Convenience routine.  Avoids explicit creation of
  315.      * MessageFormat, but doesn't allow future optimizations.
  316.      */
  317.     static UnicodeString& format(   const UnicodeString& pattern,
  318.                                     const Formattable* arguments,
  319.                                     int32_t count,
  320.                                     UnicodeString& result, 
  321.                                     UErrorCode& success);
  322.  
  323.     /**
  324.      * Format an object to produce a message.  This method handles
  325.      * Formattable objects of type kArray. If the Formattable
  326.      * object type is not of type kArray, then it returns a failing
  327.      * UErrorCode.
  328.      *
  329.      * @param obj           The object to format
  330.      * @param toAppendTo    Where the text is to be appended
  331.      * @param pos           On input: an alignment field, if desired.
  332.      *                      On output: the offsets of the alignment field.
  333.      * @param status        Output param filled with success/failure status.
  334.      * @return              The value passed in as toAppendTo (this allows chaining,
  335.      *                      as with UnicodeString::append())
  336.      */
  337.     virtual UnicodeString& format(const Formattable& obj,
  338.                                   UnicodeString& toAppendTo,
  339.                                   FieldPosition& pos,
  340.                                   UErrorCode& status) const;
  341.  
  342.     /**
  343.      * Redeclared Format method.
  344.      */
  345.     UnicodeString& format(const Formattable& obj,
  346.                           UnicodeString& result,
  347.                           UErrorCode& status) const;
  348.  
  349.     /**
  350.      * Parses the string.
  351.      * <P>
  352.      * Caveats: The parse may fail in a number of circumstances.  For
  353.      * example:
  354.      * <P>
  355.      * If one of the arguments does not occur in the pattern.
  356.      * <P>
  357.      * If the format of an argument is loses information, such as with
  358.      * a choice format where a large number formats to "many".
  359.      * <P>
  360.      * Does not yet handle recursion (where the substituted strings
  361.      * contain {n} references.)
  362.      * <P>
  363.      * Will not always find a match (or the correct match) if some
  364.      * part of the parse is ambiguous.  For example, if the pattern
  365.      * "{1},{2}" is used with the string arguments {"a,b", "c"}, it
  366.      * will format as "a,b,c".  When the result is parsed, it will
  367.      * return {"a", "b,c"}.
  368.      * <P>
  369.      * If a single argument is formatted twice in the string, then the
  370.      * later parse wins.
  371.      *
  372.      * @param source    String to be parsed.
  373.      * @param status    On input, starting position for parse. On output,
  374.      *                  final position after parse.
  375.      * @param count     Output param to receive size of returned array.
  376.      * @result          Array of Formattable objects, with length
  377.      *                  'count', owned by the caller.
  378.      */
  379.     virtual Formattable* parse( const UnicodeString& source,
  380.                                 ParsePosition& status,
  381.                                 int32_t& count) const;
  382.  
  383.     /**
  384.      * Parses the string. Does not yet handle recursion (where
  385.      * the substituted strings contain {n} references.)
  386.      *
  387.      * @param source    String to be parsed.
  388.      * @param count     Output param to receive size of returned array.
  389.      * @param status    Output param to receive success/error code.
  390.      * @result          Array of Formattable objects, with length
  391.      *                  'count', owned by the caller.
  392.      */
  393.     virtual Formattable* parse( const UnicodeString& source,
  394.                                 int32_t& count,
  395.                                 UErrorCode& status) const;
  396.  
  397.     /**
  398.      * Parse a string to produce an object.  This methods handles
  399.      * parsing of message strings into arrays of Formattable objects.
  400.      * Does not yet handle recursion (where the substituted strings
  401.      * contain %n references.)
  402.      * <P>
  403.      * Before calling, set parse_pos.index to the offset you want to
  404.      * start parsing at in the source. After calling, parse_pos.index
  405.      * is the end of the text you parsed.  If error occurs, index is
  406.      * unchanged.
  407.      * <P>
  408.      * When parsing, leading whitespace is discarded (with successful
  409.      * parse), while trailing whitespace is left as is.
  410.      * <P>
  411.      * See Format::parseObject() for more.
  412.      *
  413.      * @param source    The string to be parsed into an object.
  414.      * @param result    Formattable to be set to the parse result.
  415.      *                  If parse fails, return contents are undefined.
  416.      * @param parse_pos The position to start parsing at. Upon return
  417.      *                  this param is set to the position after the
  418.      *                  last character successfully parsed. If the
  419.      *                  source is not parsed successfully, this param
  420.      *                  will remain unchanged.
  421.      * @return          A newly created Formattable* object, or NULL
  422.      *                  on failure.  The caller owns this and should
  423.      *                  delete it when done.
  424.      */
  425.     virtual void parseObject(const UnicodeString& source,
  426.                              Formattable& result,
  427.                              ParsePosition& parse_pos) const;
  428.  
  429. public:
  430.     /**
  431.      * Returns a unique class ID POLYMORPHICALLY.  Pure virtual override.
  432.      * This method is to implement a simple version of RTTI, since not all
  433.      * C++ compilers support genuine RTTI.  Polymorphic operator==() and
  434.      * clone() methods call this method.
  435.      *
  436.      * @return          The class ID for this object. All objects of a
  437.      *                  given class have the same class ID.  Objects of
  438.      *                  other classes have different class IDs.
  439.      */
  440.     virtual UClassID getDynamicClassID(void) const;
  441.  
  442.     /**
  443.      * Return the class ID for this class.  This is useful only for
  444.      * comparing to a return value from getDynamicClassID().  For example:
  445.      * <pre>
  446.      * .   Base* polymorphic_pointer = createPolymorphicObject();
  447.      * .   if (polymorphic_pointer->getDynamicClassID() ==
  448.      * .      Derived::getStaticClassID()) ...
  449.      * </pre>
  450.      * @return          The class ID for all objects of this class.
  451.      */
  452.     static UClassID getStaticClassID(void) { return (UClassID)&fgClassID; }
  453.  
  454. private:
  455.     static char fgClassID;
  456.     static NumberFormat* fgNumberFormat;
  457.  
  458.     // fgNumberFormat is held in a cache of one.
  459.  
  460.     static NumberFormat* getNumberFormat(UErrorCode &status); // call this function to 'check out' a numberformat from the cache.
  461.     static void          releaseNumberFormat(NumberFormat *adopt); // call this function to 'return' the number format to the cache.
  462.  
  463.     Locale                 fLocale;
  464.     UnicodeString         fPattern;
  465.     // later, allow more than ten items
  466.     Format                 *fFormats[kMaxFormat];
  467.     int32_t             *fOffsets;
  468.     int32_t             fCount;
  469.     int32_t             *fArgumentNumbers;
  470.     int32_t             fMaxOffset;
  471.     
  472.     /**
  473.      * Internal routine used by format.
  474.      * @param recursionProtection Initially zero. Bits 0..9 are used to indicate
  475.      * that a parameter has already been seen, to avoid recursion.  Currently
  476.      * unused.
  477.      */
  478.     static const int32_t         fgListLength;
  479.     static const UnicodeString     fgTypeList[];
  480.     static const UnicodeString     fgModifierList[];
  481.     static const UnicodeString     fgDateModifierList[];
  482.  
  483.     /** 
  484.      * Finds the word s, in the keyword list and returns the located index.
  485.      * @param s the keyword to be searched for.
  486.      * @param list the list of keywords to be searched with.
  487.      * @return the index of the list which matches the keyword s.
  488.      */
  489.     static int32_t findKeyword( const UnicodeString& s, 
  490.                             const UnicodeString* list);
  491.  
  492.     /**
  493.      * Formats the array of arguments and copies the result into the result buffer,
  494.      * updates the field position.
  495.      * @param arguments the formattable objects array.
  496.      * @param cnt the array count.
  497.      * @param status field position status.
  498.      * @param recursionProtection Initially zero. Bits 0..9 are used to indicate
  499.      * that a parameter has already been seen, to avoid recursion.  Currently
  500.      * unused.
  501.      * @param success the error code status.
  502.      */
  503.     UnicodeString&  format( const Formattable* arguments, 
  504.                             int32_t cnt, 
  505.                             UnicodeString& result, 
  506.                             FieldPosition& status, 
  507.                             int32_t recursionProtection,
  508.                             UErrorCode& success) const;
  509.  
  510.     /**
  511.      * Checks the segments for the closest matched format instance and
  512.      * updates the format array with the new format instance.
  513.      * @param position the last processed offset in the pattern 
  514.      * @param offsetNumber the offset number of the last processed segment
  515.      * @param segments the string that contains the parsed pattern segments.
  516.      * @param success the error code
  517.      */
  518.     void            makeFormat( int32_t position, 
  519.                                 int32_t offsetNumber, 
  520.                                 UnicodeString* segments, 
  521.                                 UErrorCode& success);
  522.  
  523.     /**
  524.      * Convenience method that ought to be in NumberFormat
  525.      */
  526.     NumberFormat* createIntegerFormat(const Locale& locale, UErrorCode& status) const;
  527.  
  528.     /**
  529.      * Checks the range of the source text to quote the special
  530.      * characters, { and ' and copy to target buffer.
  531.      * @param source
  532.      * @param start the text offset to start the process of in the source string
  533.      * @param end the text offset to end the process of in the source string
  534.      * @param target the result buffer
  535.      */
  536.     static void copyAndFixQuotes(const UnicodeString& source, int32_t start, int32_t end, UnicodeString& target);
  537.  
  538.     /**
  539.      * Converts a string to an integer value using a default NumberFormat object
  540.      * which is static (shared by all MessageFormat instances).  This replaces
  541.      * a call to wtoi().
  542.      * @param string the source string to convert with
  543.      * @param status the error code.
  544.      * @return the converted number.
  545.      */
  546.     static int32_t stoi(const UnicodeString& string, UErrorCode& status);
  547.  
  548.     /**
  549.      * Converts an integer value to a string using a default NumberFormat object
  550.      * which is static (shared by all MessageFormat instances).  This replaces
  551.      * a call to wtoi().
  552.      * @param i the integer to format
  553.      * @param string the destination string
  554.      * @return a reference to string.
  555.      */
  556.     static UnicodeString& itos(int32_t i, UnicodeString& string);
  557. };
  558.  
  559. inline UClassID 
  560. MessageFormat::getDynamicClassID() const
  561.     return MessageFormat::getStaticClassID(); 
  562. }
  563.  
  564. inline UnicodeString&
  565. MessageFormat::format(const Formattable& obj,
  566.                       UnicodeString& result,
  567.                       UErrorCode& status) const {
  568.     return Format::format(obj, result, status);
  569. }
  570.  
  571. #endif // _MSGFMT
  572. //eof
  573.