• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (C) 1997-2006, International Business Machines Corporation and others. All Rights Reserved.
3 ********************************************************************************
4 *
5 * File MSGFMT.H
6 *
7 * Modification History:
8 *
9 *   Date        Name        Description
10 *   02/19/97    aliu        Converted from java.
11 *   03/20/97    helena      Finished first cut of implementation.
12 *   07/22/98    stephen     Removed operator!= (defined in Format)
13 *   08/19/2002  srl         Removing Javaisms
14 ********************************************************************************
15 */
16 
17 #ifndef MSGFMT_H
18 #define MSGFMT_H
19 
20 #include "unicode/utypes.h"
21 
22 /**
23  * \file
24  * \brief C++ API: Formats messages in a language-neutral way.
25  */
26 
27 #if !UCONFIG_NO_FORMATTING
28 
29 #include "unicode/format.h"
30 #include "unicode/locid.h"
31 #include "unicode/parseerr.h"
32 
33 U_NAMESPACE_BEGIN
34 
35 class NumberFormat;
36 class DateFormat;
37 
38 /**
39  *
40  * A MessageFormat produces concatenated messages in a
41  * language-neutral way.  It should be used for all string
42  * concatenations that are visible to end users.
43  * <P>
44  * A MessageFormat contains an array of <EM>subformats</EM> arranged
45  * within a <EM>template string</EM>.  Together, the subformats and
46  * template string determine how the MessageFormat will operate during
47  * formatting and parsing.
48  * <P>
49  * Typically, both the subformats and the template string are
50  * specified at once in a <EM>pattern</EM>.  By using different
51  * patterns for different locales, messages may be localized.
52  * <P>
53  * During formatting, the MessageFormat takes an array of arguments
54  * and produces a user-readable string.  Each argument is a
55  * Formattable object; they may be passed in in an array, or as a
56  * single Formattable object which itself contains an array.  Each
57  * argument is matched up with its corresponding subformat, which then
58  * formats it into a string.  The resultant strings are then assembled
59  * within the string template of the MessageFormat to produce the
60  * final output string.
61  * <P>
62  * During parsing, an input string is matched against the string
63  * template of the MessageFormat to produce an array of Formattable
64  * objects.  Plain text of the template string is matched directly
65  * against intput text.  At each position in the template string where
66  * a subformat is located, the subformat is called to parse the
67  * corresponding segment of input text to produce an output argument.
68  * In this way, an array of arguments is created which together
69  * constitute the parse result.
70  * <P>
71  * Parsing may fail or produce unexpected results in a number of
72  * circumstances.
73  * <UL>
74  * <LI>If one of the arguments does not occur in the pattern, it
75  * will be returned as a default Formattable.
76  * <LI>If the format of an argument is loses information, such as with
77  * a choice format where a large number formats to "many", then the
78  * parse may not correspond to the originally formatted argument.
79  * <LI>MessageFormat does not handle ChoiceFormat recursion during
80  * parsing; such parses will fail.
81  * <LI>Parsing will not always find a match (or the correct match) if
82  * some part of the parse is ambiguous.  For example, if the pattern
83  * "{1},{2}" is used with the string arguments {"a,b", "c"}, it will
84  * format as "a,b,c".  When the result is parsed, it will return {"a",
85  * "b,c"}.
86  * <LI>If a single argument is formatted more than once in the string,
87  * then the rightmost subformat in the pattern string will produce the
88  * parse result; prior subformats with the same argument index will
89  * have no effect.
90  * </UL>
91  * Here are some examples of usage:
92  * <P>
93  * Example 1:
94  * <pre>
95  * \code
96  *     UErrorCode success = U_ZERO_ERROR;
97  *     GregorianCalendar cal(success);
98  *     Formattable arguments[] = {
99  *         7L,
100  *         Formattable( (Date) cal.getTime(success), Formattable::kIsDate),
101  *         "a disturbance in the Force"
102  *     };
103  *
104  *     UnicodeString result;
105  *     MessageFormat::format(
106  *          "At {1,time} on {1,date}, there was {2} on planet {0,number}.",
107  *          arguments, 3, result, success );
108  *
109  *     cout << "result: " << result << endl;
110  *     //<output>: At 4:34:20 PM on 23-Mar-98, there was a disturbance
111  *     //             in the Force on planet 7.
112  * \endcode
113  * </pre>
114  * Typically, the message format will come from resources, and the
115  * arguments will be dynamically set at runtime.
116  * <P>
117  * Example 2:
118  * <pre>
119  *  \code
120  *     success = U_ZERO_ERROR;
121  *     Formattable testArgs[] = {3L, "MyDisk"};
122  *
123  *     MessageFormat form(
124  *         "The disk \"{1}\" contains {0} file(s).", success );
125  *
126  *     UnicodeString string;
127  *     FieldPosition fpos = 0;
128  *     cout << "format: " << form.format(testArgs, 2, string, fpos, success ) << endl;
129  *
130  *     // output, with different testArgs:
131  *     // output: The disk "MyDisk" contains 0 file(s).
132  *     // output: The disk "MyDisk" contains 1 file(s).
133  *     // output: The disk "MyDisk" contains 1,273 file(s).
134  *  \endcode
135  *  </pre>
136  *
137  *  The pattern is of the following form.  Legend:
138  *  <pre>
139  * \code
140  *       {optional item}
141  *       (group that may be repeated)*
142  * \endcode
143  *  </pre>
144  *  Do not confuse optional items with items inside quotes braces, such
145  *  as this: "{".  Quoted braces are literals.
146  *  <pre>
147  *  \code
148  *       messageFormatPattern := string ( "{" messageFormatElement "}" string )*
149  *
150  *       messageFormatElement := argumentIndex { "," elementFormat }
151  *
152  *       elementFormat := "time" { "," datetimeStyle }
153  *                      | "date" { "," datetimeStyle }
154  *                      | "number" { "," numberStyle }
155  *                      | "choice" "," choiceStyle
156  *
157  *       datetimeStyle := "short"
158  *                      | "medium"
159  *                      | "long"
160  *                      | "full"
161  *                      | dateFormatPattern
162  *
163  *       numberStyle :=   "currency"
164  *                      | "percent"
165  *                      | "integer"
166  *                      | numberFormatPattern
167  *
168  *       choiceStyle :=   choiceFormatPattern
169  * \endcode
170  * </pre>
171  * If there is no elementFormat, then the argument must be a string,
172  * which is substituted. If there is no dateTimeStyle or numberStyle,
173  * then the default format is used (e.g.  NumberFormat::createInstance(),
174  * DateFormat::createTimeInstance(DateFormat::kDefault, ...) or DateFormat::createDateInstance(DateFormat::kDefault, ...). For
175  * a ChoiceFormat, the pattern must always be specified, since there
176  * is no default.
177  * <P>
178  * In strings, single quotes can be used to quote syntax characters.
179  * A literal single quote is represented by '', both within and outside
180  * of single-quoted segments.  Inside a
181  * messageFormatElement, quotes are <EM>not</EM> removed. For example,
182  * {1,number,$'#',##} will produce a number format with the pound-sign
183  * quoted, with a result such as: "$#31,45".
184  * <P>
185  * If a pattern is used, then unquoted braces in the pattern, if any,
186  * must match: that is, "ab {0} de" and "ab '}' de" are ok, but "ab
187  * {0'}' de" and "ab } de" are not.
188  * <p>
189  * <dl><dt><b>Warning:</b><dd>The rules for using quotes within message
190  * format patterns unfortunately have shown to be somewhat confusing.
191  * In particular, it isn't always obvious to localizers whether single
192  * quotes need to be doubled or not. Make sure to inform localizers about
193  * the rules, and tell them (for example, by using comments in resource
194  * bundle source files) which strings will be processed by MessageFormat.
195  * Note that localizers may need to use single quotes in translated
196  * strings where the original version doesn't have them.
197  * <br>Note also that the simplest way to avoid the problem is to
198  * use the real apostrophe (single quote) character U+2019 (') for
199  * human-readable text, and to use the ASCII apostrophe (U+0027 ' )
200  * only in program syntax, like quoting in MessageFormat.
201  * See the annotations for U+0027 Apostrophe in The Unicode Standard.</p>
202  * </dl>
203  * <P>
204  * The argumentIndex is a non-negative integer, which corresponds to the
205  * index of the arguments presented in an array to be formatted.  The
206  * first argument has argumentIndex 0.
207  * <P>
208  * It is acceptable to have unused arguments in the array.  With missing
209  * arguments or arguments that are not of the right class for the
210  * specified format, a failing UErrorCode result is set.
211  * <P>
212  * For more sophisticated patterns, you can use a ChoiceFormat to get
213  * output:
214  * <pre>
215  * \code
216  *     UErrorCode success = U_ZERO_ERROR;
217  *     MessageFormat* form("The disk \"{1}\" contains {0}.", success);
218  *     double filelimits[] = {0,1,2};
219  *     UnicodeString filepart[] = {"no files","one file","{0,number} files"};
220  *     ChoiceFormat* fileform = new ChoiceFormat(filelimits, filepart, 3);
221  *     form.setFormat(1, *fileform); // NOT zero, see below
222  *
223  *     Formattable testArgs[] = {1273L, "MyDisk"};
224  *
225  *     UnicodeString string;
226  *     FieldPosition fpos = 0;
227  *     cout << form.format(testArgs, 2, string, fpos, success) << endl;
228  *
229  *     // output, with different testArgs
230  *     // output: The disk "MyDisk" contains no files.
231  *     // output: The disk "MyDisk" contains one file.
232  *     // output: The disk "MyDisk" contains 1,273 files.
233  * \endcode
234  * </pre>
235  * You can either do this programmatically, as in the above example,
236  * or by using a pattern (see ChoiceFormat for more information) as in:
237  * <pre>
238  * \code
239  *    form.applyPattern(
240  *      "There {0,choice,0#are no files|1#is one file|1<are {0,number,integer} files}.");
241  * \endcode
242  * </pre>
243  * <P>
244  * <EM>Note:</EM> As we see above, the string produced by a ChoiceFormat in
245  * MessageFormat is treated specially; occurences of '{' are used to
246  * indicated subformats, and cause recursion.  If you create both a
247  * MessageFormat and ChoiceFormat programmatically (instead of using
248  * the string patterns), then be careful not to produce a format that
249  * recurses on itself, which will cause an infinite loop.
250  * <P>
251  * <EM>Note:</EM> Subformats are numbered by their order in the pattern.
252  * This is <EM>not</EM> the same as the argumentIndex.
253  * <pre>
254  * \code
255  *    For example: with "abc{2}def{3}ghi{0}...",
256  *
257  *    format0 affects the first variable {2}
258  *    format1 affects the second variable {3}
259  *    format2 affects the second variable {0}
260  * \endcode
261  * </pre>
262  *
263  * <p><em>User subclasses are not supported.</em> While clients may write
264  * subclasses, such code will not necessarily work and will not be
265  * guaranteed to work stably from release to release.
266  */
267 class U_I18N_API MessageFormat : public Format {
268 public:
269     /**
270      * Enum type for kMaxFormat.
271      * @obsolete ICU 3.0.  The 10-argument limit was removed as of ICU 2.6,
272      * rendering this enum type obsolete.
273      */
274     enum EFormatNumber {
275         /**
276          * The maximum number of arguments.
277          * @obsolete ICU 3.0.  The 10-argument limit was removed as of ICU 2.6,
278          * rendering this constant obsolete.
279          */
280         kMaxFormat = 10
281     };
282 
283     /**
284      * Constructs a new MessageFormat using the given pattern and the
285      * default locale.
286      *
287      * @param pattern   Pattern used to construct object.
288      * @param status    Input/output error code.  If the
289      *                  pattern cannot be parsed, set to failure code.
290      * @stable ICU 2.0
291      */
292     MessageFormat(const UnicodeString& pattern,
293                   UErrorCode &status);
294 
295     /**
296      * Constructs a new MessageFormat using the given pattern and locale.
297      * @param pattern   Pattern used to construct object.
298      * @param newLocale The locale to use for formatting dates and numbers.
299      * @param status    Input/output error code.  If the
300      *                  pattern cannot be parsed, set to failure code.
301      * @stable ICU 2.0
302      */
303     MessageFormat(const UnicodeString& pattern,
304                   const Locale& newLocale,
305                         UErrorCode& status);
306     /**
307      * Constructs a new MessageFormat using the given pattern and locale.
308      * @param pattern   Pattern used to construct object.
309      * @param newLocale The locale to use for formatting dates and numbers.
310      * @param parseError Struct to recieve information on position
311      *                   of error within the pattern.
312      * @param status    Input/output error code.  If the
313      *                  pattern cannot be parsed, set to failure code.
314      * @stable ICU 2.0
315      */
316     MessageFormat(const UnicodeString& pattern,
317                   const Locale& newLocale,
318                   UParseError& parseError,
319                   UErrorCode& status);
320     /**
321      * Constructs a new MessageFormat from an existing one.
322      * @stable ICU 2.0
323      */
324     MessageFormat(const MessageFormat&);
325 
326     /**
327      * Assignment operator.
328      * @stable ICU 2.0
329      */
330     const MessageFormat& operator=(const MessageFormat&);
331 
332     /**
333      * Destructor.
334      * @stable ICU 2.0
335      */
336     virtual ~MessageFormat();
337 
338     /**
339      * Clones this Format object polymorphically.  The caller owns the
340      * result and should delete it when done.
341      * @stable ICU 2.0
342      */
343     virtual Format* clone(void) const;
344 
345     /**
346      * Returns true if the given Format objects are semantically equal.
347      * Objects of different subclasses are considered unequal.
348      * @param other  the object to be compared with.
349      * @return       true if the given Format objects are semantically equal.
350      * @stable ICU 2.0
351      */
352     virtual UBool operator==(const Format& other) const;
353 
354     /**
355      * Sets the locale. This locale is used for fetching default number or date
356      * format information.
357      * @param theLocale    the new locale value to be set.
358      * @stable ICU 2.0
359      */
360     virtual void setLocale(const Locale& theLocale);
361 
362     /**
363      * Gets the locale. This locale is used for fetching default number or date
364      * format information.
365      * @return    the locale of the object.
366      * @stable ICU 2.0
367      */
368     virtual const Locale& getLocale(void) const;
369 
370     /**
371      * Applies the given pattern string to this message format.
372      *
373      * @param pattern   The pattern to be applied.
374      * @param status    Input/output error code.  If the
375      *                  pattern cannot be parsed, set to failure code.
376      * @stable ICU 2.0
377      */
378     virtual void applyPattern(const UnicodeString& pattern,
379                               UErrorCode& status);
380     /**
381      * Applies the given pattern string to this message format.
382      *
383      * @param pattern    The pattern to be applied.
384      * @param parseError Struct to recieve information on position
385      *                   of error within pattern.
386      * @param status    Input/output error code.  If the
387      *                  pattern cannot be parsed, set to failure code.
388      * @stable ICU 2.0
389      */
390     virtual void applyPattern(const UnicodeString& pattern,
391                              UParseError& parseError,
392                              UErrorCode& status);
393 
394     /**
395      * Returns a pattern that can be used to recreate this object.
396      *
397      * @param appendTo  Output parameter to receive the pattern.
398      *                  Result is appended to existing contents.
399      * @return          Reference to 'appendTo' parameter.
400      * @stable ICU 2.0
401      */
402     virtual UnicodeString& toPattern(UnicodeString& appendTo) const;
403 
404     /**
405      * Sets subformats.
406      * See the class description about format numbering.
407      * The caller should not delete the Format objects after this call.
408      * <EM>The array formatsToAdopt is not itself adopted.</EM> Its
409      * ownership is retained by the caller. If the call fails because
410      * memory cannot be allocated, then the formats will be deleted
411      * by this method, and this object will remain unchanged.
412      *
413      * @stable ICU 2.0
414      * @param formatsToAdopt    the format to be adopted.
415      * @param count             the size of the array.
416      */
417     virtual void adoptFormats(Format** formatsToAdopt, int32_t count);
418 
419     /**
420      * Sets subformats.
421      * See the class description about format numbering.
422      * Each item in the array is cloned into the internal array.
423      * If the call fails because memory cannot be allocated, then this
424      * object will remain unchanged.
425      *
426      * @stable ICU 2.0
427      * @param newFormats the new format to be set.
428      * @param cnt        the size of the array.
429      */
430     virtual void setFormats(const Format** newFormats,int32_t cnt);
431 
432 
433     /**
434      * Sets one subformat.
435      * See the class description about format numbering.
436      * The caller should not delete the Format object after this call.
437      * If the number is over the number of formats already set,
438      * the item will be deleted and ignored.
439      * @stable ICU 2.0
440      * @param formatNumber     index of the subformat.
441      * @param formatToAdopt    the format to be adopted.
442      */
443     virtual void adoptFormat(int32_t formatNumber, Format* formatToAdopt);
444 
445     /**
446      * Sets one subformat.
447      * See the class description about format numbering.
448      * If the number is over the number of formats already set,
449      * the item will be ignored.
450      * @param formatNumber     index of the subformat.
451      * @param format    the format to be set.
452      * @stable ICU 2.0
453      */
454     virtual void setFormat(int32_t formatNumber, const Format& format);
455 
456     /**
457      * Gets an array of subformats of this object.  The returned array
458      * should not be deleted by the caller, nor should the pointers
459      * within the array.  The array and its contents remain valid only
460      * until the next call to any method of this class is made with
461      * this object.  See the class description about format numbering.
462      * @param count output parameter to receive the size of the array
463      * @return an array of count Format* objects, or NULL if out of
464      * memory.  Any or all of the array elements may be NULL.
465      * @stable ICU 2.0
466      */
467     virtual const Format** getFormats(int32_t& count) const;
468 
469     /**
470      * Formats the given array of arguments into a user-readable string.
471      * Does not take ownership of the Formattable* array or its contents.
472      *
473      * @param source    An array of objects to be formatted.
474      * @param count     The number of elements of 'source'.
475      * @param appendTo  Output parameter to receive result.
476      *                  Result is appended to existing contents.
477      * @param ignore    Not used; inherited from base class API.
478      * @param status    Input/output error code.  If the
479      *                  pattern cannot be parsed, set to failure code.
480      * @return          Reference to 'appendTo' parameter.
481      * @stable ICU 2.0
482      */
483     UnicodeString& format(  const Formattable* source,
484                             int32_t count,
485                             UnicodeString& appendTo,
486                             FieldPosition& ignore,
487                             UErrorCode& status) const;
488 
489     /**
490      * Formats the given array of arguments into a user-readable string
491      * using the given pattern.
492      *
493      * @param pattern   The pattern.
494      * @param arguments An array of objects to be formatted.
495      * @param count     The number of elements of 'source'.
496      * @param appendTo  Output parameter to receive result.
497      *                  Result is appended to existing contents.
498      * @param status    Input/output error code.  If the
499      *                  pattern cannot be parsed, set to failure code.
500      * @return          Reference to 'appendTo' parameter.
501      * @stable ICU 2.0
502      */
503     static UnicodeString& format(   const UnicodeString& pattern,
504                                     const Formattable* arguments,
505                                     int32_t count,
506                                     UnicodeString& appendTo,
507                                     UErrorCode& status);
508 
509     /**
510      * Formats the given array of arguments into a user-readable
511      * string.  The array must be stored within a single Formattable
512      * object of type kArray. If the Formattable object type is not of
513      * type kArray, then returns a failing UErrorCode.
514      *
515      * @param obj       A Formattable of type kArray containing
516      *                  arguments to be formatted.
517      * @param appendTo  Output parameter to receive result.
518      *                  Result is appended to existing contents.
519      * @param pos       On input: an alignment field, if desired.
520      *                  On output: the offsets of the alignment field.
521      * @param status    Input/output error code.  If the
522      *                  pattern cannot be parsed, set to failure code.
523      * @return          Reference to 'appendTo' parameter.
524      * @stable ICU 2.0
525      */
526     virtual UnicodeString& format(const Formattable& obj,
527                                   UnicodeString& appendTo,
528                                   FieldPosition& pos,
529                                   UErrorCode& status) const;
530 
531     /**
532      * Formats the given array of arguments into a user-readable
533      * string.  The array must be stored within a single Formattable
534      * object of type kArray. If the Formattable object type is not of
535      * type kArray, then returns a failing UErrorCode.
536      *
537      * @param obj       The object to format
538      * @param appendTo  Output parameter to receive result.
539      *                  Result is appended to existing contents.
540      * @param status    Input/output error code.  If the
541      *                  pattern cannot be parsed, set to failure code.
542      * @return          Reference to 'appendTo' parameter.
543      * @stable ICU 2.0
544      */
545     UnicodeString& format(const Formattable& obj,
546                           UnicodeString& appendTo,
547                           UErrorCode& status) const;
548 
549     /**
550      * Parses the given string into an array of output arguments.
551      *
552      * @param source    String to be parsed.
553      * @param pos       On input, starting position for parse. On output,
554      *                  final position after parse.  Unchanged if parse
555      *                  fails.
556      * @param count     Output parameter to receive the number of arguments
557      *                  parsed.
558      * @return an array of parsed arguments.  The caller owns both
559      * the array and its contents.
560      * @stable ICU 2.0
561      */
562     virtual Formattable* parse( const UnicodeString& source,
563                                 ParsePosition& pos,
564                                 int32_t& count) const;
565 
566     /**
567      * Parses the given string into an array of output arguments.
568      *
569      * @param source    String to be parsed.
570      * @param count     Output param to receive size of returned array.
571      * @param status    Input/output error code.  If the
572      *                  pattern cannot be parsed, set to failure code.
573      * @return an array of parsed arguments.  The caller owns both
574      * the array and its contents.
575      * @stable ICU 2.0
576      */
577     virtual Formattable* parse( const UnicodeString& source,
578                                 int32_t& count,
579                                 UErrorCode& status) const;
580 
581     /**
582      * Parses the given string into an array of output arguments
583      * stored within a single Formattable of type kArray.
584      *
585      * @param source    The string to be parsed into an object.
586      * @param result    Formattable to be set to the parse result.
587      *                  If parse fails, return contents are undefined.
588      * @param pos       On input, starting position for parse. On output,
589      *                  final position after parse.  Unchanged if parse
590      *                  fails.
591      * @stable ICU 2.0
592      */
593     virtual void parseObject(const UnicodeString& source,
594                              Formattable& result,
595                              ParsePosition& pos) const;
596 
597     /**
598      * Convert an 'apostrophe-friendly' pattern into a standard
599      * pattern.  Standard patterns treat all apostrophes as
600      * quotes, which is problematic in some languages, e.g.
601      * French, where apostrophe is commonly used.  This utility
602      * assumes that only an unpaired apostrophe immediately before
603      * a brace is a true quote.  Other unpaired apostrophes are paired,
604      * and the resulting standard pattern string is returned.
605      *
606      * <p><b>Note</b> it is not guaranteed that the returned pattern
607      * is indeed a valid pattern.  The only effect is to convert
608      * between patterns having different quoting semantics.
609      *
610      * @param pattern the 'apostrophe-friendly' patttern to convert
611      * @param status    Input/output error code.  If the pattern
612      *                  cannot be parsed, the failure code is set.
613      * @return the standard equivalent of the original pattern
614      * @stable ICU 3.4
615      */
616     static UnicodeString autoQuoteApostrophe(const UnicodeString& pattern,
617         UErrorCode& status);
618 
619     /**
620      * Returns a unique class ID POLYMORPHICALLY.  Pure virtual override.
621      * This method is to implement a simple version of RTTI, since not all
622      * C++ compilers support genuine RTTI.  Polymorphic operator==() and
623      * clone() methods call this method.
624      *
625      * @return          The class ID for this object. All objects of a
626      *                  given class have the same class ID.  Objects of
627      *                  other classes have different class IDs.
628      * @stable ICU 2.0
629      */
630     virtual UClassID getDynamicClassID(void) const;
631 
632     /**
633      * Return the class ID for this class.  This is useful only for
634      * comparing to a return value from getDynamicClassID().  For example:
635      * <pre>
636      * .   Base* polymorphic_pointer = createPolymorphicObject();
637      * .   if (polymorphic_pointer->getDynamicClassID() ==
638      * .      Derived::getStaticClassID()) ...
639      * </pre>
640      * @return          The class ID for all objects of this class.
641      * @stable ICU 2.0
642      */
643     static UClassID U_EXPORT2 getStaticClassID(void);
644 
645 private:
646 
647     Locale              fLocale;
648     UnicodeString       fPattern;
649     Format**            formatAliases; // see getFormats
650     int32_t             formatAliasesCapacity;
651 
652     MessageFormat(); // default constructor not implemented
653 
654     /*
655      * A structure representing one subformat of this MessageFormat.
656      * Each subformat has a Format object, an offset into the plain
657      * pattern text fPattern, and an argument number.  The argument
658      * number corresponds to the array of arguments to be formatted.
659      * @internal
660      */
661     class Subformat {
662     public:
663         /**
664          * @internal
665          */
666         Format* format; // formatter
667         /**
668          * @internal
669          */
670         int32_t offset; // offset into fPattern
671         /**
672          * @internal
673          */
674         int32_t arg;    // 0-based argument number
675 
676         /**
677          * Clone that.format and assign it to this.format
678          * Do NOT delete this.format
679          * @internal
680          */
681         Subformat& operator=(const Subformat& that) {
682             format = that.format ? that.format->clone() : NULL;
683             offset = that.offset;
684             arg = that.arg;
685             return *this;
686         }
687 
688         /**
689          * @internal
690          */
691         UBool operator==(const Subformat& that) const {
692             // Do cheap comparisons first
693             return offset == that.offset &&
694                    arg == that.arg &&
695                    ((format == that.format) || // handles NULL
696                     (*format == *that.format));
697         }
698 
699         /**
700          * @internal
701          */
702         UBool operator!=(const Subformat& that) const {
703             return !operator==(that);
704         }
705     };
706 
707     /**
708      * A MessageFormat contains an array of subformats.  This array
709      * needs to grow dynamically if the MessageFormat is modified.
710      */
711     Subformat* subformats;
712     int32_t    subformatCount;
713     int32_t    subformatCapacity;
714 
715     /**
716      * A MessageFormat formats an array of arguments.  Each argument
717      * has an expected type, based on the pattern.  For example, if
718      * the pattern contains the subformat "{3,number,integer}", then
719      * we expect argument 3 to have type Formattable::kLong.  This
720      * array needs to grow dynamically if the MessageFormat is
721      * modified.
722      */
723     Formattable::Type* argTypes;
724     int32_t            argTypeCount;
725     int32_t            argTypeCapacity;
726 
727     // Variable-size array management
728     UBool allocateSubformats(int32_t capacity);
729     UBool allocateArgTypes(int32_t capacity);
730 
731     /**
732      * Default Format objects used when no format is specified and a
733      * numeric or date argument is formatted.  These are volatile
734      * cache objects maintained only for performance.  They do not
735      * participate in operator=(), copy constructor(), nor
736      * operator==().
737      */
738     NumberFormat* defaultNumberFormat;
739     DateFormat*   defaultDateFormat;
740 
741     /**
742      * Method to retrieve default formats (or NULL on failure).
743      * These are semantically const, but may modify *this.
744      */
745     const NumberFormat* getDefaultNumberFormat(UErrorCode&) const;
746     const DateFormat*   getDefaultDateFormat(UErrorCode&) const;
747 
748     /**
749      * Finds the word s, in the keyword list and returns the located index.
750      * @param s the keyword to be searched for.
751      * @param list the list of keywords to be searched with.
752      * @return the index of the list which matches the keyword s.
753      */
754     static int32_t findKeyword( const UnicodeString& s,
755                                 const UChar * const *list);
756 
757     /**
758      * Formats the array of arguments and copies the result into the
759      * result buffer, updates the field position.
760      *
761      * @param arguments The formattable objects array.
762      * @param cnt       The array count.
763      * @param appendTo  Output parameter to receive result.
764      *                  Result is appended to existing contents.
765      * @param status    Field position status.
766      * @param recursionProtection
767      *                  Initially zero. Bits 0..9 are used to indicate
768      *                  that a parameter has already been seen, to
769      *                  avoid recursion.  Currently unused.
770      * @param success   The error code status.
771      * @return          Reference to 'appendTo' parameter.
772      */
773     UnicodeString&  format( const Formattable* arguments,
774                             int32_t cnt,
775                             UnicodeString& appendTo,
776                             FieldPosition& status,
777                             int32_t recursionProtection,
778                             UErrorCode& success) const;
779 
780     void             makeFormat(int32_t offsetNumber,
781                                 UnicodeString* segments,
782                                 UParseError& parseError,
783                                 UErrorCode& success);
784 
785     /**
786      * Convenience method that ought to be in NumberFormat
787      */
788     NumberFormat* createIntegerFormat(const Locale& locale, UErrorCode& status) const;
789 
790     /**
791      * Checks the range of the source text to quote the special
792      * characters, { and ' and copy to target buffer.
793      * @param source
794      * @param start the text offset to start the process of in the source string
795      * @param end the text offset to end the process of in the source string
796      * @param appendTo  Output parameter to receive result.
797      *                  Result is appended to existing contents.
798      */
799     static void copyAndFixQuotes(const UnicodeString& appendTo, int32_t start, int32_t end, UnicodeString& target);
800 
801     /**
802      * Returns array of argument types in the parsed pattern
803      * for use in C API.  Only for the use of umsg_vformat().  Not
804      * for public consumption.
805      * @param listCount  Output parameter to receive the size of array
806      * @return           The array of formattable types in the pattern
807      * @internal
808      */
getArgTypeList(int32_t & listCount)809     const Formattable::Type* getArgTypeList(int32_t& listCount) const {
810         listCount = argTypeCount;
811         return argTypes;
812     }
813 
814     friend class MessageFormatAdapter; // getFormatTypeList() access
815 };
816 
817 inline UnicodeString&
format(const Formattable & obj,UnicodeString & appendTo,UErrorCode & status)818 MessageFormat::format(const Formattable& obj,
819                       UnicodeString& appendTo,
820                       UErrorCode& status) const {
821     return Format::format(obj, appendTo, status);
822 }
823 U_NAMESPACE_END
824 
825 #endif /* #if !UCONFIG_NO_FORMATTING */
826 
827 #endif // _MSGFMT
828 //eof
829 
830