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’\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/> .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/> .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/> .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 override; 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 override; 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 nullptr. 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 */ getApostropheMode()500 UMessagePatternApostropheMode getApostropheMode() const { 501 return msgPattern.getApostropheMode(); 502 } 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 nullptr if out of 641 * memory. Any or all of the array elements may be nullptr. 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 override; 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 nullptr 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 override; 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 override; 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 nullptr. 874 * @param right pointer to a Format object. Must not be nullptr. 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() = delete; // 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 override; 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 nullptr 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 nullptr 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 nullptr.) 984 * @param argumentNames nullptr 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 nullptr). 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 Format* createAppropriateFormat(UnicodeString& type, 1015 UnicodeString& style, 1016 Formattable::Type& formattableType, 1017 UParseError& parseError, 1018 UErrorCode& ec); 1019 1020 const Formattable* getArgFromListByName(const Formattable* arguments, 1021 const UnicodeString *argumentNames, 1022 int32_t cnt, UnicodeString& name) const; 1023 1024 Formattable* parse(int32_t msgStart, 1025 const UnicodeString& source, 1026 ParsePosition& pos, 1027 int32_t& count, 1028 UErrorCode& ec) const; 1029 1030 FieldPosition* updateMetaData(AppendableWrapper& dest, int32_t prevLength, 1031 FieldPosition* fp, const Formattable* argId) const; 1032 1033 /** 1034 * Finds the "other" sub-message. 1035 * @param partIndex the index of the first PluralFormat argument style part. 1036 * @return the "other" sub-message start part index. 1037 */ 1038 int32_t findOtherSubMessage(int32_t partIndex) const; 1039 1040 /** 1041 * Returns the ARG_START index of the first occurrence of the plural number in a sub-message. 1042 * Returns -1 if it is a REPLACE_NUMBER. 1043 * Returns 0 if there is neither. 1044 */ 1045 int32_t findFirstPluralNumberArg(int32_t msgStart, const UnicodeString &argName) const; 1046 1047 Format* getCachedFormatter(int32_t argumentNumber) const; 1048 1049 UnicodeString getLiteralStringUntilNextArgument(int32_t from) const; 1050 1051 void copyObjects(const MessageFormat& that, UErrorCode& ec); 1052 1053 void formatComplexSubMessage(int32_t msgStart, 1054 const void *plNumber, 1055 const Formattable* arguments, 1056 const UnicodeString *argumentNames, 1057 int32_t cnt, 1058 AppendableWrapper& appendTo, 1059 UErrorCode& success) const; 1060 1061 /** 1062 * Convenience method that ought to be in NumberFormat 1063 */ 1064 NumberFormat* createIntegerFormat(const Locale& locale, UErrorCode& status) const; 1065 1066 /** 1067 * Returns array of argument types in the parsed pattern 1068 * for use in C API. Only for the use of umsg_vformat(). Not 1069 * for public consumption. 1070 * @param listCount Output parameter to receive the size of array 1071 * @return The array of formattable types in the pattern 1072 */ getArgTypeList(int32_t & listCount)1073 const Formattable::Type* getArgTypeList(int32_t& listCount) const { 1074 listCount = argTypeCount; 1075 return argTypes; 1076 } 1077 1078 /** 1079 * Resets the internal MessagePattern, and other associated caches. 1080 */ 1081 void resetPattern(); 1082 1083 /** 1084 * A DummyFormatter that we use solely to store a nullptr value. UHash does 1085 * not support storing nullptr values. 1086 */ 1087 class U_I18N_API DummyFormat : public Format { 1088 public: 1089 virtual bool operator==(const Format&) const override; 1090 virtual DummyFormat* clone() const override; 1091 virtual UnicodeString& format(const Formattable& obj, 1092 UnicodeString& appendTo, 1093 UErrorCode& status) const; 1094 virtual UnicodeString& format(const Formattable&, 1095 UnicodeString& appendTo, 1096 FieldPosition&, 1097 UErrorCode& status) const override; 1098 virtual UnicodeString& format(const Formattable& obj, 1099 UnicodeString& appendTo, 1100 FieldPositionIterator* posIter, 1101 UErrorCode& status) const override; 1102 virtual void parseObject(const UnicodeString&, 1103 Formattable&, 1104 ParsePosition&) const override; 1105 }; 1106 1107 friend class MessageFormatAdapter; // getFormatTypeList() access 1108 }; 1109 1110 U_NAMESPACE_END 1111 1112 #endif /* #if !UCONFIG_NO_FORMATTING */ 1113 1114 #endif /* U_SHOW_CPLUSPLUS_API */ 1115 1116 #endif // _MSGFMT 1117 //eof 1118