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