Coverage Report

Created: 2025-06-24 06:43

/src/icu/source/i18n/unicode/msgfmt.h
Line
Count
Source (jump to first uncovered line)
1
// © 2016 and later: Unicode, Inc. and others.
2
// License & terms of use: http://www.unicode.org/copyright.html
3
/*
4
* Copyright (C) 2007-2013, International Business Machines Corporation and
5
* others. All Rights Reserved.
6
********************************************************************************
7
*
8
* File MSGFMT.H
9
*
10
* Modification History:
11
*
12
*   Date        Name        Description
13
*   02/19/97    aliu        Converted from java.
14
*   03/20/97    helena      Finished first cut of implementation.
15
*   07/22/98    stephen     Removed operator!= (defined in Format)
16
*   08/19/2002  srl         Removing Javaisms
17
*******************************************************************************/
18
19
#ifndef MSGFMT_H
20
#define MSGFMT_H
21
22
#include "unicode/utypes.h"
23
24
#if U_SHOW_CPLUSPLUS_API
25
26
/**
27
 * \file
28
 * \brief C++ API: Formats messages in a language-neutral way.
29
 */
30
31
#if !UCONFIG_NO_FORMATTING
32
33
#include "unicode/format.h"
34
#include "unicode/locid.h"
35
#include "unicode/messagepattern.h"
36
#include "unicode/parseerr.h"
37
#include "unicode/plurfmt.h"
38
#include "unicode/plurrule.h"
39
40
U_CDECL_BEGIN
41
// Forward declaration.
42
struct UHashtable;
43
typedef struct UHashtable UHashtable; /**< @internal */
44
U_CDECL_END
45
46
U_NAMESPACE_BEGIN
47
48
class AppendableWrapper;
49
class DateFormat;
50
class NumberFormat;
51
52
/**
53
 * <p>MessageFormat prepares strings for display to users,
54
 * with optional arguments (variables/placeholders).
55
 * The arguments can occur in any order, which is necessary for translation
56
 * into languages with different grammars.
57
 *
58
 * <p>A MessageFormat is constructed from a <em>pattern</em> string
59
 * with arguments in {curly braces} which will be replaced by formatted values.
60
 *
61
 * <p><code>MessageFormat</code> differs from the other <code>Format</code>
62
 * classes in that you create a <code>MessageFormat</code> object with one
63
 * of its constructors (not with a <code>createInstance</code> style factory
64
 * method). Factory methods aren't necessary because <code>MessageFormat</code>
65
 * itself doesn't implement locale-specific behavior. Any locale-specific
66
 * behavior is defined by the pattern that you provide and the
67
 * subformats used for inserted arguments.
68
 *
69
 * <p>Arguments can be named (using identifiers) or numbered (using small ASCII-digit integers).
70
 * Some of the API methods work only with argument numbers and throw an exception
71
 * if the pattern has named arguments (see {@link #usesNamedArguments()}).
72
 *
73
 * <p>An argument might not specify any format type. In this case,
74
 * a numeric value is formatted with a default (for the locale) NumberFormat,
75
 * and a date/time value is formatted with a default (for the locale) DateFormat.
76
 *
77
 * <p>An argument might specify a "simple" type for which the specified
78
 * Format object is created, cached and used.
79
 *
80
 * <p>An argument might have a "complex" type with nested MessageFormat sub-patterns.
81
 * During formatting, one of these sub-messages is selected according to the argument value
82
 * and recursively formatted.
83
 *
84
 * <p>After construction, a custom Format object can be set for
85
 * a top-level argument, overriding the default formatting and parsing behavior
86
 * for that argument.
87
 * However, custom formatting can be achieved more simply by writing
88
 * a typeless argument in the pattern string
89
 * and supplying it with a preformatted string value.
90
 *
91
 * <p>When formatting, MessageFormat takes a collection of argument values
92
 * and writes an output string.
93
 * The argument values may be passed as an array
94
 * (when the pattern contains only numbered arguments)
95
 * or as an array of names and and an array of arguments (which works for both named
96
 * and numbered arguments).
97
 *
98
 * <p>Each argument is matched with one of the input values by array index or argument name
99
 * and formatted according to its pattern specification
100
 * (or using a custom Format object if one was set).
101
 * A numbered pattern argument is matched with an argument name that contains that number
102
 * as an ASCII-decimal-digit string (without leading zero).
103
 *
104
 * <h4><a name="patterns">Patterns and Their Interpretation</a></h4>
105
 *
106
 * <code>MessageFormat</code> uses patterns of the following form:
107
 * <pre>
108
 * message = messageText (argument messageText)*
109
 * argument = noneArg | simpleArg | complexArg
110
 * complexArg = choiceArg | pluralArg | selectArg | selectordinalArg
111
 *
112
 * noneArg = '{' argNameOrNumber '}'
113
 * simpleArg = '{' argNameOrNumber ',' argType [',' argStyle] '}'
114
 * choiceArg = '{' argNameOrNumber ',' "choice" ',' choiceStyle '}'
115
 * pluralArg = '{' argNameOrNumber ',' "plural" ',' pluralStyle '}'
116
 * selectArg = '{' argNameOrNumber ',' "select" ',' selectStyle '}'
117
 * selectordinalArg = '{' argNameOrNumber ',' "selectordinal" ',' pluralStyle '}'
118
 *
119
 * choiceStyle: see {@link ChoiceFormat}
120
 * pluralStyle: see {@link PluralFormat}
121
 * selectStyle: see {@link SelectFormat}
122
 *
123
 * argNameOrNumber = argName | argNumber
124
 * argName = [^[[:Pattern_Syntax:][:Pattern_White_Space:]]]+
125
 * argNumber = '0' | ('1'..'9' ('0'..'9')*)
126
 *
127
 * argType = "number" | "date" | "time" | "spellout" | "ordinal" | "duration"
128
 * argStyle = "short" | "medium" | "long" | "full" | "integer" | "currency" | "percent" | argStyleText | "::" argSkeletonText
129
 * </pre>
130
 *
131
 * <ul>
132
 *   <li>messageText can contain quoted literal strings including syntax characters.
133
 *       A quoted literal string begins with an ASCII apostrophe and a syntax character
134
 *       (usually a {curly brace}) and continues until the next single apostrophe.
135
 *       A double ASCII apostrophe inside or outside of a quoted string represents
136
 *       one literal apostrophe.
137
 *   <li>Quotable syntax characters are the {curly braces} in all messageText parts,
138
 *       plus the '#' sign in a messageText immediately inside a pluralStyle,
139
 *       and the '|' symbol in a messageText immediately inside a choiceStyle.
140
 *   <li>See also {@link #UMessagePatternApostropheMode}
141
 *   <li>In argStyleText, every single ASCII apostrophe begins and ends quoted literal text,
142
 *       and unquoted {curly braces} must occur in matched pairs.
143
 * </ul>
144
 *
145
 * <p>Recommendation: Use the real apostrophe (single quote) character
146
 * \htmlonly&#x2019;\endhtmlonly (U+2019) for
147
 * human-readable text, and use the ASCII apostrophe ' (U+0027)
148
 * only in program syntax, like quoting in MessageFormat.
149
 * See the annotations for U+0027 Apostrophe in The Unicode Standard.
150
 *
151
 * <p>The <code>choice</code> argument type is deprecated.
152
 * Use <code>plural</code> arguments for proper plural selection,
153
 * and <code>select</code> arguments for simple selection among a fixed set of choices.
154
 *
155
 * <p>The <code>argType</code> and <code>argStyle</code> values are used to create
156
 * a <code>Format</code> instance for the format element. The following
157
 * table shows how the values map to Format instances. Combinations not
158
 * shown in the table are illegal. Any <code>argStyleText</code> must
159
 * be a valid pattern string for the Format subclass used.
160
 *
161
 * <p><table border=1>
162
 *    <tr>
163
 *       <th>argType
164
 *       <th>argStyle
165
 *       <th>resulting Format object
166
 *    <tr>
167
 *       <td colspan=2><i>(none)</i>
168
 *       <td><code>null</code>
169
 *    <tr>
170
 *       <td rowspan=6><code>number</code>
171
 *       <td><i>(none)</i>
172
 *       <td><code>NumberFormat.createInstance(getLocale(), status)</code>
173
 *    <tr>
174
 *       <td><code>integer</code>
175
 *       <td><code>NumberFormat.createInstance(getLocale(), kNumberStyle, status)</code>
176
 *    <tr>
177
 *       <td><code>currency</code>
178
 *       <td><code>NumberFormat.createCurrencyInstance(getLocale(), status)</code>
179
 *    <tr>
180
 *       <td><code>percent</code>
181
 *       <td><code>NumberFormat.createPercentInstance(getLocale(), status)</code>
182
 *    <tr>
183
 *       <td><i>argStyleText</i>
184
 *       <td><code>new DecimalFormat(argStyleText, new DecimalFormatSymbols(getLocale(), status), status)</code>
185
 *    <tr>
186
 *       <td><i>argSkeletonText</i>
187
 *       <td><code>NumberFormatter::forSkeleton(argSkeletonText, status).locale(getLocale()).toFormat(status)</code>
188
 *    <tr>
189
 *       <td rowspan=7><code>date</code>
190
 *       <td><i>(none)</i>
191
 *       <td><code>DateFormat.createDateInstance(kDefault, getLocale(), status)</code>
192
 *    <tr>
193
 *       <td><code>short</code>
194
 *       <td><code>DateFormat.createDateInstance(kShort, getLocale(), status)</code>
195
 *    <tr>
196
 *       <td><code>medium</code>
197
 *       <td><code>DateFormat.createDateInstance(kDefault, getLocale(), status)</code>
198
 *    <tr>
199
 *       <td><code>long</code>
200
 *       <td><code>DateFormat.createDateInstance(kLong, getLocale(), status)</code>
201
 *    <tr>
202
 *       <td><code>full</code>
203
 *       <td><code>DateFormat.createDateInstance(kFull, getLocale(), status)</code>
204
 *    <tr>
205
 *       <td><i>argStyleText</i>
206
 *       <td><code>new SimpleDateFormat(argStyleText, getLocale(), status)</code>
207
 *    <tr>
208
 *       <td><i>argSkeletonText</i>
209
 *       <td><code>DateFormat::createInstanceForSkeleton(argSkeletonText, getLocale(), status)</code>
210
 *    <tr>
211
 *       <td rowspan=6><code>time</code>
212
 *       <td><i>(none)</i>
213
 *       <td><code>DateFormat.createTimeInstance(kDefault, getLocale(), status)</code>
214
 *    <tr>
215
 *       <td><code>short</code>
216
 *       <td><code>DateFormat.createTimeInstance(kShort, getLocale(), status)</code>
217
 *    <tr>
218
 *       <td><code>medium</code>
219
 *       <td><code>DateFormat.createTimeInstance(kDefault, getLocale(), status)</code>
220
 *    <tr>
221
 *       <td><code>long</code>
222
 *       <td><code>DateFormat.createTimeInstance(kLong, getLocale(), status)</code>
223
 *    <tr>
224
 *       <td><code>full</code>
225
 *       <td><code>DateFormat.createTimeInstance(kFull, getLocale(), status)</code>
226
 *    <tr>
227
 *       <td><i>argStyleText</i>
228
 *       <td><code>new SimpleDateFormat(argStyleText, getLocale(), status)</code>
229
 *    <tr>
230
 *       <td><code>spellout</code>
231
 *       <td><i>argStyleText (optional)</i>
232
 *       <td><code>new RuleBasedNumberFormat(URBNF_SPELLOUT, getLocale(), status)
233
 *           <br/>&nbsp;&nbsp;&nbsp;&nbsp;.setDefaultRuleset(argStyleText, status);</code>
234
 *    <tr>
235
 *       <td><code>ordinal</code>
236
 *       <td><i>argStyleText (optional)</i>
237
 *       <td><code>new RuleBasedNumberFormat(URBNF_ORDINAL, getLocale(), status)
238
 *           <br/>&nbsp;&nbsp;&nbsp;&nbsp;.setDefaultRuleset(argStyleText, status);</code>
239
 *    <tr>
240
 *       <td><code>duration</code>
241
 *       <td><i>argStyleText (optional)</i>
242
 *       <td><code>new RuleBasedNumberFormat(URBNF_DURATION, getLocale(), status)
243
 *           <br/>&nbsp;&nbsp;&nbsp;&nbsp;.setDefaultRuleset(argStyleText, status);</code>
244
 * </table>
245
 * <p>
246
 *
247
 * <h4>Argument formatting</h4>
248
 *
249
 * <p>Arguments are formatted according to their type, using the default
250
 * ICU formatters for those types, unless otherwise specified.</p>
251
 *
252
 * <p>There are also several ways to control the formatting.</p>
253
 *
254
 * <p>We recommend you use default styles, predefined style values, skeletons,
255
 * or preformatted values, but not pattern strings or custom format objects.</p>
256
 *
257
 * <p>For more details, see the
258
 * <a href="https://unicode-org.github.io/icu/userguide/format_parse/messages">ICU User Guide</a>.</p>
259
 *
260
 * <h4>Usage Information</h4>
261
 *
262
 * <p>Here are some examples of usage:
263
 * Example 1:
264
 *
265
 * <pre>
266
 * \code
267
 *     UErrorCode success = U_ZERO_ERROR;
268
 *     GregorianCalendar cal(success);
269
 *     Formattable arguments[] = {
270
 *         7L,
271
 *         Formattable( (Date) cal.getTime(success), Formattable::kIsDate),
272
 *         "a disturbance in the Force"
273
 *     };
274
 *
275
 *     UnicodeString result;
276
 *     MessageFormat::format(
277
 *          "At {1,time,::jmm} on {1,date,::dMMMM}, there was {2} on planet {0,number}.",
278
 *          arguments, 3, result, success );
279
 *
280
 *     cout << "result: " << result << endl;
281
 *     //<output>: At 4:34 PM on March 23, there was a disturbance
282
 *     //             in the Force on planet 7.
283
 * \endcode
284
 * </pre>
285
 *
286
 * Typically, the message format will come from resources, and the
287
 * arguments will be dynamically set at runtime.
288
 *
289
 * <p>Example 2:
290
 *
291
 * <pre>
292
 *  \code
293
 *     success = U_ZERO_ERROR;
294
 *     Formattable testArgs[] = {3L, "MyDisk"};
295
 *
296
 *     MessageFormat form(
297
 *         "The disk \"{1}\" contains {0} file(s).", success );
298
 *
299
 *     UnicodeString string;
300
 *     FieldPosition fpos = 0;
301
 *     cout << "format: " << form.format(testArgs, 2, string, fpos, success ) << endl;
302
 *
303
 *     // output, with different testArgs:
304
 *     // output: The disk "MyDisk" contains 0 file(s).
305
 *     // output: The disk "MyDisk" contains 1 file(s).
306
 *     // output: The disk "MyDisk" contains 1,273 file(s).
307
 *  \endcode
308
 *  </pre>
309
 *
310
 *
311
 * <p>For messages that include plural forms, you can use a plural argument:
312
 * <pre>
313
 * \code
314
 *  success = U_ZERO_ERROR;
315
 *  MessageFormat msgFmt(
316
 *       "{num_files, plural, "
317
 *       "=0{There are no files on disk \"{disk_name}\".}"
318
 *       "=1{There is one file on disk \"{disk_name}\".}"
319
 *       "other{There are # files on disk \"{disk_name}\".}}",
320
 *      Locale("en"),
321
 *      success);
322
 *  FieldPosition fpos = 0;
323
 *  Formattable testArgs[] = {0L, "MyDisk"};
324
 *  UnicodeString testArgsNames[] = {"num_files", "disk_name"};
325
 *  UnicodeString result;
326
 *  cout << msgFmt.format(testArgs, testArgsNames, 2, result, fpos, 0, success);
327
 *  testArgs[0] = 3L;
328
 *  cout << msgFmt.format(testArgs, testArgsNames, 2, result, fpos, 0, success);
329
 * \endcode
330
 * <em>output</em>:
331
 * There are no files on disk "MyDisk".
332
 * There are 3 files on "MyDisk".
333
 * </pre>
334
 * See {@link PluralFormat} and {@link PluralRules} for details.
335
 *
336
 * <h4><a name="synchronization">Synchronization</a></h4>
337
 *
338
 * <p>MessageFormats are not synchronized.
339
 * It is recommended to create separate format instances for each thread.
340
 * If multiple threads access a format concurrently, it must be synchronized
341
 * externally.
342
 *
343
 * @stable ICU 2.0
344
 */
345
class U_I18N_API MessageFormat : public Format {
346
public:
347
#ifndef U_HIDE_OBSOLETE_API
348
    /**
349
     * Enum type for kMaxFormat.
350
     * @obsolete ICU 3.0.  The 10-argument limit was removed as of ICU 2.6,
351
     * rendering this enum type obsolete.
352
     */
353
    enum EFormatNumber {
354
        /**
355
         * The maximum number of arguments.
356
         * @obsolete ICU 3.0.  The 10-argument limit was removed as of ICU 2.6,
357
         * rendering this constant obsolete.
358
         */
359
        kMaxFormat = 10
360
    };
361
#endif  /* U_HIDE_OBSOLETE_API */
362
363
    /**
364
     * Constructs a new MessageFormat using the given pattern and the
365
     * default locale.
366
     *
367
     * @param pattern   Pattern used to construct object.
368
     * @param status    Input/output error code.  If the
369
     *                  pattern cannot be parsed, set to failure code.
370
     * @stable ICU 2.0
371
     */
372
    MessageFormat(const UnicodeString& pattern,
373
                  UErrorCode &status);
374
375
    /**
376
     * Constructs a new MessageFormat using the given pattern and locale.
377
     * @param pattern   Pattern used to construct object.
378
     * @param newLocale The locale to use for formatting dates and numbers.
379
     * @param status    Input/output error code.  If the
380
     *                  pattern cannot be parsed, set to failure code.
381
     * @stable ICU 2.0
382
     */
383
    MessageFormat(const UnicodeString& pattern,
384
                  const Locale& newLocale,
385
                        UErrorCode& status);
386
    /**
387
     * Constructs a new MessageFormat using the given pattern and locale.
388
     * @param pattern   Pattern used to construct object.
389
     * @param newLocale The locale to use for formatting dates and numbers.
390
     * @param parseError Struct to receive information on the position
391
     *                   of an error within the pattern.
392
     * @param status    Input/output error code.  If the
393
     *                  pattern cannot be parsed, set to failure code.
394
     * @stable ICU 2.0
395
     */
396
    MessageFormat(const UnicodeString& pattern,
397
                  const Locale& newLocale,
398
                  UParseError& parseError,
399
                  UErrorCode& status);
400
    /**
401
     * Constructs a new MessageFormat from an existing one.
402
     * @stable ICU 2.0
403
     */
404
    MessageFormat(const MessageFormat&);
405
406
    /**
407
     * Assignment operator.
408
     * @stable ICU 2.0
409
     */
410
    const MessageFormat& operator=(const MessageFormat&);
411
412
    /**
413
     * Destructor.
414
     * @stable ICU 2.0
415
     */
416
    virtual ~MessageFormat();
417
418
    /**
419
     * Clones this Format object polymorphically.  The caller owns the
420
     * result and should delete it when done.
421
     * @stable ICU 2.0
422
     */
423
    virtual MessageFormat* clone() const;
424
425
    /**
426
     * Returns true if the given Format objects are semantically equal.
427
     * Objects of different subclasses are considered unequal.
428
     * @param other  the object to be compared with.
429
     * @return       true if the given Format objects are semantically equal.
430
     * @stable ICU 2.0
431
     */
432
    virtual bool operator==(const Format& other) const;
433
434
    /**
435
     * Sets the locale to be used for creating argument Format objects.
436
     * @param theLocale    the new locale value to be set.
437
     * @stable ICU 2.0
438
     */
439
    virtual void setLocale(const Locale& theLocale);
440
441
    /**
442
     * Gets the locale used for creating argument Format objects.
443
     * format information.
444
     * @return    the locale of the object.
445
     * @stable ICU 2.0
446
     */
447
    virtual const Locale& getLocale(void) const;
448
449
    /**
450
     * Applies the given pattern string to this message format.
451
     *
452
     * @param pattern   The pattern to be applied.
453
     * @param status    Input/output error code.  If the
454
     *                  pattern cannot be parsed, set to failure code.
455
     * @stable ICU 2.0
456
     */
457
    virtual void applyPattern(const UnicodeString& pattern,
458
                              UErrorCode& status);
459
    /**
460
     * Applies the given pattern string to this message format.
461
     *
462
     * @param pattern    The pattern to be applied.
463
     * @param parseError Struct to receive information on the position
464
     *                   of an error within the pattern.
465
     * @param status    Input/output error code.  If the
466
     *                  pattern cannot be parsed, set to failure code.
467
     * @stable ICU 2.0
468
     */
469
    virtual void applyPattern(const UnicodeString& pattern,
470
                             UParseError& parseError,
471
                             UErrorCode& status);
472
473
    /**
474
     * Sets the UMessagePatternApostropheMode and the pattern used by this message format.
475
     * Parses the pattern and caches Format objects for simple argument types.
476
     * Patterns and their interpretation are specified in the
477
     * <a href="#patterns">class description</a>.
478
     * <p>
479
     * This method is best used only once on a given object to avoid confusion about the mode,
480
     * and after constructing the object with an empty pattern string to minimize overhead.
481
     *
482
     * @param pattern    The pattern to be applied.
483
     * @param aposMode   The new apostrophe mode.
484
     * @param parseError Struct to receive information on the position
485
     *                   of an error within the pattern.
486
     *                   Can be NULL.
487
     * @param status    Input/output error code.  If the
488
     *                  pattern cannot be parsed, set to failure code.
489
     * @stable ICU 4.8
490
     */
491
    virtual void applyPattern(const UnicodeString& pattern,
492
                              UMessagePatternApostropheMode aposMode,
493
                              UParseError* parseError,
494
                              UErrorCode& status);
495
496
    /**
497
     * @return this instance's UMessagePatternApostropheMode.
498
     * @stable ICU 4.8
499
     */
500
0
    UMessagePatternApostropheMode getApostropheMode() const {
501
0
        return msgPattern.getApostropheMode();
502
0
    }
503
504
    /**
505
     * Returns a pattern that can be used to recreate this object.
506
     *
507
     * @param appendTo  Output parameter to receive the pattern.
508
     *                  Result is appended to existing contents.
509
     * @return          Reference to 'appendTo' parameter.
510
     * @stable ICU 2.0
511
     */
512
    virtual UnicodeString& toPattern(UnicodeString& appendTo) const;
513
514
    /**
515
     * Sets subformats.
516
     * See the class description about format numbering.
517
     * The caller should not delete the Format objects after this call.
518
     * <EM>The array formatsToAdopt is not itself adopted.</EM> Its
519
     * ownership is retained by the caller. If the call fails because
520
     * memory cannot be allocated, then the formats will be deleted
521
     * by this method, and this object will remain unchanged.
522
     *
523
     * <p>If this format uses named arguments, the new formats are discarded
524
     * and this format remains unchanged.
525
     *
526
     * @stable ICU 2.0
527
     * @param formatsToAdopt    the format to be adopted.
528
     * @param count             the size of the array.
529
     */
530
    virtual void adoptFormats(Format** formatsToAdopt, int32_t count);
531
532
    /**
533
     * Sets subformats.
534
     * See the class description about format numbering.
535
     * Each item in the array is cloned into the internal array.
536
     * If the call fails because memory cannot be allocated, then this
537
     * object will remain unchanged.
538
     *
539
     * <p>If this format uses named arguments, the new formats are discarded
540
     * and this format remains unchanged.
541
     *
542
     * @stable ICU 2.0
543
     * @param newFormats the new format to be set.
544
     * @param cnt        the size of the array.
545
     */
546
    virtual void setFormats(const Format** newFormats, int32_t cnt);
547
548
549
    /**
550
     * Sets one subformat.
551
     * See the class description about format numbering.
552
     * The caller should not delete the Format object after this call.
553
     * If the number is over the number of formats already set,
554
     * the item will be deleted and ignored.
555
     *
556
     * <p>If this format uses named arguments, the new format is discarded
557
     * and this format remains unchanged.
558
     *
559
     * @stable ICU 2.0
560
     * @param formatNumber     index of the subformat.
561
     * @param formatToAdopt    the format to be adopted.
562
     */
563
    virtual void adoptFormat(int32_t formatNumber, Format* formatToAdopt);
564
565
    /**
566
     * Sets one subformat.
567
     * See the class description about format numbering.
568
     * If the number is over the number of formats already set,
569
     * the item will be ignored.
570
     * @param formatNumber     index of the subformat.
571
     * @param format    the format to be set.
572
     * @stable ICU 2.0
573
     */
574
    virtual void setFormat(int32_t formatNumber, const Format& format);
575
576
    /**
577
     * Gets format names. This function returns formatNames in StringEnumerations
578
     * which can be used with getFormat() and setFormat() to export formattable
579
     * array from current MessageFormat to another.  It is the caller's responsibility
580
     * to delete the returned formatNames.
581
     * @param status  output param set to success/failure code.
582
     * @stable ICU 4.0
583
     */
584
    virtual StringEnumeration* getFormatNames(UErrorCode& status);
585
586
    /**
587
     * Gets subformat pointer for given format name.
588
     * This function supports both named and numbered
589
     * arguments. If numbered, the formatName is the
590
     * corresponding UnicodeStrings (e.g. "0", "1", "2"...).
591
     * The returned Format object should not be deleted by the caller,
592
     * nor should the pointer of other object .  The pointer and its
593
     * contents remain valid only until the next call to any method
594
     * of this class is made with this object.
595
     * @param formatName the name or number specifying a format
596
     * @param status  output param set to success/failure code.
597
     * @stable ICU 4.0
598
     */
599
    virtual Format* getFormat(const UnicodeString& formatName, UErrorCode& status);
600
601
    /**
602
     * Sets one subformat for given format name.
603
     * See the class description about format name.
604
     * This function supports both named and numbered
605
     * arguments-- if numbered, the formatName is the
606
     * corresponding UnicodeStrings (e.g. "0", "1", "2"...).
607
     * If there is no matched formatName or wrong type,
608
     * the item will be ignored.
609
     * @param formatName  Name of the subformat.
610
     * @param format      the format to be set.
611
     * @param status  output param set to success/failure code.
612
     * @stable ICU 4.0
613
     */
614
    virtual void setFormat(const UnicodeString& formatName, const Format& format, UErrorCode& status);
615
616
    /**
617
     * Sets one subformat for given format name.
618
     * See the class description about format name.
619
     * This function supports both named and numbered
620
     * arguments-- if numbered, the formatName is the
621
     * corresponding UnicodeStrings (e.g. "0", "1", "2"...).
622
     * If there is no matched formatName or wrong type,
623
     * the item will be ignored.
624
     * The caller should not delete the Format object after this call.
625
     * @param formatName  Name of the subformat.
626
     * @param formatToAdopt  Format to be adopted.
627
     * @param status      output param set to success/failure code.
628
     * @stable ICU 4.0
629
     */
630
    virtual void adoptFormat(const UnicodeString& formatName, Format* formatToAdopt, UErrorCode& status);
631
632
    /**
633
     * Gets an array of subformats of this object.  The returned array
634
     * should not be deleted by the caller, nor should the pointers
635
     * within the array.  The array and its contents remain valid only
636
     * until the next call to this format. See the class description
637
     * about format numbering.
638
     *
639
     * @param count output parameter to receive the size of the array
640
     * @return an array of count Format* objects, or NULL if out of
641
     * memory.  Any or all of the array elements may be NULL.
642
     * @stable ICU 2.0
643
     */
644
    virtual const Format** getFormats(int32_t& count) const;
645
646
647
    using Format::format;
648
649
    /**
650
     * Formats the given array of arguments into a user-readable string.
651
     * Does not take ownership of the Formattable* array or its contents.
652
     *
653
     * <p>If this format uses named arguments, appendTo is unchanged and
654
     * status is set to U_ILLEGAL_ARGUMENT_ERROR.
655
     *
656
     * @param source    An array of objects to be formatted.
657
     * @param count     The number of elements of 'source'.
658
     * @param appendTo  Output parameter to receive result.
659
     *                  Result is appended to existing contents.
660
     * @param ignore    Not used; inherited from base class API.
661
     * @param status    Input/output error code.  If the
662
     *                  pattern cannot be parsed, set to failure code.
663
     * @return          Reference to 'appendTo' parameter.
664
     * @stable ICU 2.0
665
     */
666
    UnicodeString& format(const Formattable* source,
667
                          int32_t count,
668
                          UnicodeString& appendTo,
669
                          FieldPosition& ignore,
670
                          UErrorCode& status) const;
671
672
    /**
673
     * Formats the given array of arguments into a user-readable string
674
     * using the given pattern.
675
     *
676
     * <p>If this format uses named arguments, appendTo is unchanged and
677
     * status is set to U_ILLEGAL_ARGUMENT_ERROR.
678
     *
679
     * @param pattern   The pattern.
680
     * @param arguments An array of objects to be formatted.
681
     * @param count     The number of elements of 'source'.
682
     * @param appendTo  Output parameter to receive result.
683
     *                  Result is appended to existing contents.
684
     * @param status    Input/output error code.  If the
685
     *                  pattern cannot be parsed, set to failure code.
686
     * @return          Reference to 'appendTo' parameter.
687
     * @stable ICU 2.0
688
     */
689
    static UnicodeString& format(const UnicodeString& pattern,
690
                                 const Formattable* arguments,
691
                                 int32_t count,
692
                                 UnicodeString& appendTo,
693
                                 UErrorCode& status);
694
695
    /**
696
     * Formats the given array of arguments into a user-readable
697
     * string.  The array must be stored within a single Formattable
698
     * object of type kArray. If the Formattable object type is not of
699
     * type kArray, then returns a failing UErrorCode.
700
     *
701
     * <p>If this format uses named arguments, appendTo is unchanged and
702
     * status is set to U_ILLEGAL_ARGUMENT_ERROR.
703
     *
704
     * @param obj       A Formattable of type kArray containing
705
     *                  arguments to be formatted.
706
     * @param appendTo  Output parameter to receive result.
707
     *                  Result is appended to existing contents.
708
     * @param pos       On input: an alignment field, if desired.
709
     *                  On output: the offsets of the alignment field.
710
     * @param status    Input/output error code.  If the
711
     *                  pattern cannot be parsed, set to failure code.
712
     * @return          Reference to 'appendTo' parameter.
713
     * @stable ICU 2.0
714
     */
715
    virtual UnicodeString& format(const Formattable& obj,
716
                                  UnicodeString& appendTo,
717
                                  FieldPosition& pos,
718
                                  UErrorCode& status) const;
719
720
    /**
721
     * Formats the given array of arguments into a user-defined argument name
722
     * array. This function supports both named and numbered
723
     * arguments-- if numbered, the formatName is the
724
     * corresponding UnicodeStrings (e.g. "0", "1", "2"...).
725
     *
726
     * @param argumentNames argument name array
727
     * @param arguments An array of objects to be formatted.
728
     * @param count     The number of elements of 'argumentNames' and
729
     *                  arguments.  The number of argumentNames and arguments
730
     *                  must be the same.
731
     * @param appendTo  Output parameter to receive result.
732
     *                  Result is appended to existing contents.
733
     * @param status    Input/output error code.  If the
734
     *                  pattern cannot be parsed, set to failure code.
735
     * @return          Reference to 'appendTo' parameter.
736
     * @stable ICU 4.0
737
     */
738
    UnicodeString& format(const UnicodeString* argumentNames,
739
                          const Formattable* arguments,
740
                          int32_t count,
741
                          UnicodeString& appendTo,
742
                          UErrorCode& status) const;
743
    /**
744
     * Parses the given string into an array of output arguments.
745
     *
746
     * @param source    String to be parsed.
747
     * @param pos       On input, starting position for parse. On output,
748
     *                  final position after parse.  Unchanged if parse
749
     *                  fails.
750
     * @param count     Output parameter to receive the number of arguments
751
     *                  parsed.
752
     * @return an array of parsed arguments.  The caller owns both
753
     * the array and its contents.
754
     * @stable ICU 2.0
755
     */
756
    virtual Formattable* parse(const UnicodeString& source,
757
                               ParsePosition& pos,
758
                               int32_t& count) const;
759
760
    /**
761
     * Parses the given string into an array of output arguments.
762
     *
763
     * <p>If this format uses named arguments, status is set to
764
     * U_ARGUMENT_TYPE_MISMATCH.
765
     *
766
     * @param source    String to be parsed.
767
     * @param count     Output param to receive size of returned array.
768
     * @param status    Input/output error code.  If the
769
     *                  pattern cannot be parsed, set to failure code.
770
     * @return an array of parsed arguments.  The caller owns both
771
     * the array and its contents. Returns NULL if status is not U_ZERO_ERROR.
772
     *
773
     * @stable ICU 2.0
774
     */
775
    virtual Formattable* parse(const UnicodeString& source,
776
                               int32_t& count,
777
                               UErrorCode& status) const;
778
779
    /**
780
     * Parses the given string into an array of output arguments
781
     * stored within a single Formattable of type kArray.
782
     *
783
     * @param source    The string to be parsed into an object.
784
     * @param result    Formattable to be set to the parse result.
785
     *                  If parse fails, return contents are undefined.
786
     * @param pos       On input, starting position for parse. On output,
787
     *                  final position after parse.  Unchanged if parse
788
     *                  fails.
789
     * @stable ICU 2.0
790
     */
791
    virtual void parseObject(const UnicodeString& source,
792
                             Formattable& result,
793
                             ParsePosition& pos) const;
794
795
    /**
796
     * Convert an 'apostrophe-friendly' pattern into a standard
797
     * pattern.  Standard patterns treat all apostrophes as
798
     * quotes, which is problematic in some languages, e.g.
799
     * French, where apostrophe is commonly used.  This utility
800
     * assumes that only an unpaired apostrophe immediately before
801
     * a brace is a true quote.  Other unpaired apostrophes are paired,
802
     * and the resulting standard pattern string is returned.
803
     *
804
     * <p><b>Note</b> it is not guaranteed that the returned pattern
805
     * is indeed a valid pattern.  The only effect is to convert
806
     * between patterns having different quoting semantics.
807
     *
808
     * @param pattern the 'apostrophe-friendly' patttern to convert
809
     * @param status    Input/output error code.  If the pattern
810
     *                  cannot be parsed, the failure code is set.
811
     * @return the standard equivalent of the original pattern
812
     * @stable ICU 3.4
813
     */
814
    static UnicodeString autoQuoteApostrophe(const UnicodeString& pattern,
815
        UErrorCode& status);
816
817
818
    /**
819
     * Returns true if this MessageFormat uses named arguments,
820
     * and false otherwise.  See class description.
821
     *
822
     * @return true if named arguments are used.
823
     * @stable ICU 4.0
824
     */
825
    UBool usesNamedArguments() const;
826
827
828
#ifndef U_HIDE_INTERNAL_API
829
    /**
830
     * This API is for ICU internal use only.
831
     * Please do not use it.
832
     *
833
     * Returns argument types count in the parsed pattern.
834
     * Used to distinguish pattern "{0} d" and "d".
835
     *
836
     * @return           The number of formattable types in the pattern
837
     * @internal
838
     */
839
    int32_t getArgTypeCount() const;
840
#endif  /* U_HIDE_INTERNAL_API */
841
842
    /**
843
     * Returns a unique class ID POLYMORPHICALLY.  Pure virtual override.
844
     * This method is to implement a simple version of RTTI, since not all
845
     * C++ compilers support genuine RTTI.  Polymorphic operator==() and
846
     * clone() methods call this method.
847
     *
848
     * @return          The class ID for this object. All objects of a
849
     *                  given class have the same class ID.  Objects of
850
     *                  other classes have different class IDs.
851
     * @stable ICU 2.0
852
     */
853
    virtual UClassID getDynamicClassID(void) const;
854
855
    /**
856
     * Return the class ID for this class.  This is useful only for
857
     * comparing to a return value from getDynamicClassID().  For example:
858
     * <pre>
859
     * .   Base* polymorphic_pointer = createPolymorphicObject();
860
     * .   if (polymorphic_pointer->getDynamicClassID() ==
861
     * .      Derived::getStaticClassID()) ...
862
     * </pre>
863
     * @return          The class ID for all objects of this class.
864
     * @stable ICU 2.0
865
     */
866
    static UClassID U_EXPORT2 getStaticClassID(void);
867
868
#ifndef U_HIDE_INTERNAL_API
869
    /**
870
     * Compares two Format objects. This is used for constructing the hash
871
     * tables.
872
     *
873
     * @param left pointer to a Format object. Must not be NULL.
874
     * @param right pointer to a Format object. Must not be NULL.
875
     *
876
     * @return whether the two objects are the same
877
     * @internal
878
     */
879
    static UBool equalFormats(const void* left, const void* right);
880
#endif  /* U_HIDE_INTERNAL_API */
881
882
private:
883
884
    Locale              fLocale;
885
    MessagePattern      msgPattern;
886
    Format**            formatAliases; // see getFormats
887
    int32_t             formatAliasesCapacity;
888
889
    MessageFormat(); // default constructor not implemented
890
891
     /**
892
      * This provider helps defer instantiation of a PluralRules object
893
      * until we actually need to select a keyword.
894
      * For example, if the number matches an explicit-value selector like "=1"
895
      * we do not need any PluralRules.
896
      */
897
    class U_I18N_API PluralSelectorProvider : public PluralFormat::PluralSelector {
898
    public:
899
        PluralSelectorProvider(const MessageFormat &mf, UPluralType type);
900
        virtual ~PluralSelectorProvider();
901
        virtual UnicodeString select(void *ctx, double number, UErrorCode& ec) const;
902
903
        void reset();
904
    private:
905
        const MessageFormat &msgFormat;
906
        PluralRules* rules;
907
        UPluralType type;
908
    };
909
910
    /**
911
     * A MessageFormat formats an array of arguments.  Each argument
912
     * has an expected type, based on the pattern.  For example, if
913
     * the pattern contains the subformat "{3,number,integer}", then
914
     * we expect argument 3 to have type Formattable::kLong.  This
915
     * array needs to grow dynamically if the MessageFormat is
916
     * modified.
917
     */
918
    Formattable::Type* argTypes;
919
    int32_t            argTypeCount;
920
    int32_t            argTypeCapacity;
921
922
    /**
923
     * true if there are different argTypes for the same argument.
924
     * This only matters when the MessageFormat is used in the plain C (umsg_xxx) API
925
     * where the pattern argTypes determine how the va_arg list is read.
926
     */
927
    UBool hasArgTypeConflicts;
928
929
    // Variable-size array management
930
    UBool allocateArgTypes(int32_t capacity, UErrorCode& status);
931
932
    /**
933
     * Default Format objects used when no format is specified and a
934
     * numeric or date argument is formatted.  These are volatile
935
     * cache objects maintained only for performance.  They do not
936
     * participate in operator=(), copy constructor(), nor
937
     * operator==().
938
     */
939
    NumberFormat* defaultNumberFormat;
940
    DateFormat*   defaultDateFormat;
941
942
    UHashtable* cachedFormatters;
943
    UHashtable* customFormatArgStarts;
944
945
    PluralSelectorProvider pluralProvider;
946
    PluralSelectorProvider ordinalProvider;
947
948
    /**
949
     * Method to retrieve default formats (or NULL on failure).
950
     * These are semantically const, but may modify *this.
951
     */
952
    const NumberFormat* getDefaultNumberFormat(UErrorCode&) const;
953
    const DateFormat*   getDefaultDateFormat(UErrorCode&) const;
954
955
    /**
956
     * Finds the word s, in the keyword list and returns the located index.
957
     * @param s the keyword to be searched for.
958
     * @param list the list of keywords to be searched with.
959
     * @return the index of the list which matches the keyword s.
960
     */
961
    static int32_t findKeyword( const UnicodeString& s,
962
                                const char16_t * const *list);
963
964
    /**
965
     * Thin wrapper around the format(... AppendableWrapper ...) variant.
966
     * Wraps the destination UnicodeString into an AppendableWrapper and
967
     * supplies default values for some other parameters.
968
     */
969
    UnicodeString& format(const Formattable* arguments,
970
                          const UnicodeString *argumentNames,
971
                          int32_t cnt,
972
                          UnicodeString& appendTo,
973
                          FieldPosition* pos,
974
                          UErrorCode& status) const;
975
976
    /**
977
     * Formats the arguments and writes the result into the
978
     * AppendableWrapper, updates the field position.
979
     *
980
     * @param msgStart      Index to msgPattern part to start formatting from.
981
     * @param plNumber      NULL except when formatting a plural argument sub-message
982
     *                      where a '#' is replaced by the format string for this number.
983
     * @param arguments     The formattable objects array. (Must not be NULL.)
984
     * @param argumentNames NULL if numbered values are used. Otherwise the same
985
     *                      length as "arguments", and each entry is the name of the
986
     *                      corresponding argument in "arguments".
987
     * @param cnt           The length of arguments (and of argumentNames if that is not NULL).
988
     * @param appendTo      Output parameter to receive the result.
989
     *                      The result string is appended to existing contents.
990
     * @param pos           Field position status.
991
     * @param success       The error code status.
992
     */
993
    void format(int32_t msgStart,
994
                const void *plNumber,
995
                const Formattable* arguments,
996
                const UnicodeString *argumentNames,
997
                int32_t cnt,
998
                AppendableWrapper& appendTo,
999
                FieldPosition* pos,
1000
                UErrorCode& success) const;
1001
1002
    UnicodeString getArgName(int32_t partIndex);
1003
1004
    void setArgStartFormat(int32_t argStart, Format* formatter, UErrorCode& status);
1005
1006
    void setCustomArgStartFormat(int32_t argStart, Format* formatter, UErrorCode& status);
1007
1008
    int32_t nextTopLevelArgStart(int32_t partIndex) const;
1009
1010
    UBool argNameMatches(int32_t partIndex, const UnicodeString& argName, int32_t argNumber);
1011
1012
    void cacheExplicitFormats(UErrorCode& status);
1013
1014
    int32_t skipLeadingSpaces(UnicodeString& style);
1015
1016
    Format* createAppropriateFormat(UnicodeString& type,
1017
                                    UnicodeString& style,
1018
                                    Formattable::Type& formattableType,
1019
                                    UParseError& parseError,
1020
                                    UErrorCode& ec);
1021
1022
    const Formattable* getArgFromListByName(const Formattable* arguments,
1023
                                            const UnicodeString *argumentNames,
1024
                                            int32_t cnt, UnicodeString& name) const;
1025
1026
    Formattable* parse(int32_t msgStart,
1027
                       const UnicodeString& source,
1028
                       ParsePosition& pos,
1029
                       int32_t& count,
1030
                       UErrorCode& ec) const;
1031
1032
    FieldPosition* updateMetaData(AppendableWrapper& dest, int32_t prevLength,
1033
                                  FieldPosition* fp, const Formattable* argId) const;
1034
1035
    /**
1036
     * Finds the "other" sub-message.
1037
     * @param partIndex the index of the first PluralFormat argument style part.
1038
     * @return the "other" sub-message start part index.
1039
     */
1040
    int32_t findOtherSubMessage(int32_t partIndex) const;
1041
1042
    /**
1043
     * Returns the ARG_START index of the first occurrence of the plural number in a sub-message.
1044
     * Returns -1 if it is a REPLACE_NUMBER.
1045
     * Returns 0 if there is neither.
1046
     */
1047
    int32_t findFirstPluralNumberArg(int32_t msgStart, const UnicodeString &argName) const;
1048
1049
    Format* getCachedFormatter(int32_t argumentNumber) const;
1050
1051
    UnicodeString getLiteralStringUntilNextArgument(int32_t from) const;
1052
1053
    void copyObjects(const MessageFormat& that, UErrorCode& ec);
1054
1055
    void formatComplexSubMessage(int32_t msgStart,
1056
                                 const void *plNumber,
1057
                                 const Formattable* arguments,
1058
                                 const UnicodeString *argumentNames,
1059
                                 int32_t cnt,
1060
                                 AppendableWrapper& appendTo,
1061
                                 UErrorCode& success) const;
1062
1063
    /**
1064
     * Convenience method that ought to be in NumberFormat
1065
     */
1066
    NumberFormat* createIntegerFormat(const Locale& locale, UErrorCode& status) const;
1067
1068
    /**
1069
     * Returns array of argument types in the parsed pattern
1070
     * for use in C API.  Only for the use of umsg_vformat().  Not
1071
     * for public consumption.
1072
     * @param listCount  Output parameter to receive the size of array
1073
     * @return           The array of formattable types in the pattern
1074
     */
1075
0
    const Formattable::Type* getArgTypeList(int32_t& listCount) const {
1076
0
        listCount = argTypeCount;
1077
0
        return argTypes;
1078
0
    }
1079
1080
    /**
1081
     * Resets the internal MessagePattern, and other associated caches.
1082
     */
1083
    void resetPattern();
1084
1085
    /**
1086
     * A DummyFormatter that we use solely to store a NULL value. UHash does
1087
     * not support storing NULL values.
1088
     */
1089
    class U_I18N_API DummyFormat : public Format {
1090
    public:
1091
        virtual bool operator==(const Format&) const;
1092
        virtual DummyFormat* clone() const;
1093
        virtual UnicodeString& format(const Formattable& obj,
1094
                              UnicodeString& appendTo,
1095
                              UErrorCode& status) const;
1096
        virtual UnicodeString& format(const Formattable&,
1097
                                      UnicodeString& appendTo,
1098
                                      FieldPosition&,
1099
                                      UErrorCode& status) const;
1100
        virtual UnicodeString& format(const Formattable& obj,
1101
                                      UnicodeString& appendTo,
1102
                                      FieldPositionIterator* posIter,
1103
                                      UErrorCode& status) const;
1104
        virtual void parseObject(const UnicodeString&,
1105
                                 Formattable&,
1106
                                 ParsePosition&) const;
1107
    };
1108
1109
    friend class MessageFormatAdapter; // getFormatTypeList() access
1110
};
1111
1112
U_NAMESPACE_END
1113
1114
#endif /* #if !UCONFIG_NO_FORMATTING */
1115
1116
#endif /* U_SHOW_CPLUSPLUS_API */
1117
1118
#endif // _MSGFMT
1119
//eof