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