1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/i18n/unicode/msgfmt.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1093 @@ 1.4 +/* 1.5 +* Copyright (C) 2007-2013, International Business Machines Corporation and 1.6 +* others. All Rights Reserved. 1.7 +******************************************************************************** 1.8 +* 1.9 +* File MSGFMT.H 1.10 +* 1.11 +* Modification History: 1.12 +* 1.13 +* Date Name Description 1.14 +* 02/19/97 aliu Converted from java. 1.15 +* 03/20/97 helena Finished first cut of implementation. 1.16 +* 07/22/98 stephen Removed operator!= (defined in Format) 1.17 +* 08/19/2002 srl Removing Javaisms 1.18 +*******************************************************************************/ 1.19 + 1.20 +#ifndef MSGFMT_H 1.21 +#define MSGFMT_H 1.22 + 1.23 +#include "unicode/utypes.h" 1.24 + 1.25 +/** 1.26 + * \file 1.27 + * \brief C++ API: Formats messages in a language-neutral way. 1.28 + */ 1.29 + 1.30 +#if !UCONFIG_NO_FORMATTING 1.31 + 1.32 +#include "unicode/format.h" 1.33 +#include "unicode/locid.h" 1.34 +#include "unicode/messagepattern.h" 1.35 +#include "unicode/parseerr.h" 1.36 +#include "unicode/plurfmt.h" 1.37 +#include "unicode/plurrule.h" 1.38 + 1.39 +U_CDECL_BEGIN 1.40 +// Forward declaration. 1.41 +struct UHashtable; 1.42 +typedef struct UHashtable UHashtable; /**< @internal */ 1.43 +U_CDECL_END 1.44 + 1.45 +U_NAMESPACE_BEGIN 1.46 + 1.47 +class AppendableWrapper; 1.48 +class DateFormat; 1.49 +class NumberFormat; 1.50 + 1.51 +/** 1.52 + * <p>MessageFormat prepares strings for display to users, 1.53 + * with optional arguments (variables/placeholders). 1.54 + * The arguments can occur in any order, which is necessary for translation 1.55 + * into languages with different grammars. 1.56 + * 1.57 + * <p>A MessageFormat is constructed from a <em>pattern</em> string 1.58 + * with arguments in {curly braces} which will be replaced by formatted values. 1.59 + * 1.60 + * <p><code>MessageFormat</code> differs from the other <code>Format</code> 1.61 + * classes in that you create a <code>MessageFormat</code> object with one 1.62 + * of its constructors (not with a <code>createInstance</code> style factory 1.63 + * method). Factory methods aren't necessary because <code>MessageFormat</code> 1.64 + * itself doesn't implement locale-specific behavior. Any locale-specific 1.65 + * behavior is defined by the pattern that you provide and the 1.66 + * subformats used for inserted arguments. 1.67 + * 1.68 + * <p>Arguments can be named (using identifiers) or numbered (using small ASCII-digit integers). 1.69 + * Some of the API methods work only with argument numbers and throw an exception 1.70 + * if the pattern has named arguments (see {@link #usesNamedArguments()}). 1.71 + * 1.72 + * <p>An argument might not specify any format type. In this case, 1.73 + * a Number value is formatted with a default (for the locale) NumberFormat, 1.74 + * a Date value is formatted with a default (for the locale) DateFormat, 1.75 + * and for any other value its toString() value is used. 1.76 + * 1.77 + * <p>An argument might specify a "simple" type for which the specified 1.78 + * Format object is created, cached and used. 1.79 + * 1.80 + * <p>An argument might have a "complex" type with nested MessageFormat sub-patterns. 1.81 + * During formatting, one of these sub-messages is selected according to the argument value 1.82 + * and recursively formatted. 1.83 + * 1.84 + * <p>After construction, a custom Format object can be set for 1.85 + * a top-level argument, overriding the default formatting and parsing behavior 1.86 + * for that argument. 1.87 + * However, custom formatting can be achieved more simply by writing 1.88 + * a typeless argument in the pattern string 1.89 + * and supplying it with a preformatted string value. 1.90 + * 1.91 + * <p>When formatting, MessageFormat takes a collection of argument values 1.92 + * and writes an output string. 1.93 + * The argument values may be passed as an array 1.94 + * (when the pattern contains only numbered arguments) 1.95 + * or as an array of names and and an array of arguments (which works for both named 1.96 + * and numbered arguments). 1.97 + * 1.98 + * <p>Each argument is matched with one of the input values by array index or argument name 1.99 + * and formatted according to its pattern specification 1.100 + * (or using a custom Format object if one was set). 1.101 + * A numbered pattern argument is matched with an argument name that contains that number 1.102 + * as an ASCII-decimal-digit string (without leading zero). 1.103 + * 1.104 + * <h4><a name="patterns">Patterns and Their Interpretation</a></h4> 1.105 + * 1.106 + * <code>MessageFormat</code> uses patterns of the following form: 1.107 + * <pre> 1.108 + * message = messageText (argument messageText)* 1.109 + * argument = noneArg | simpleArg | complexArg 1.110 + * complexArg = choiceArg | pluralArg | selectArg | selectordinalArg 1.111 + * 1.112 + * noneArg = '{' argNameOrNumber '}' 1.113 + * simpleArg = '{' argNameOrNumber ',' argType [',' argStyle] '}' 1.114 + * choiceArg = '{' argNameOrNumber ',' "choice" ',' choiceStyle '}' 1.115 + * pluralArg = '{' argNameOrNumber ',' "plural" ',' pluralStyle '}' 1.116 + * selectArg = '{' argNameOrNumber ',' "select" ',' selectStyle '}' 1.117 + * selectordinalArg = '{' argNameOrNumber ',' "selectordinal" ',' pluralStyle '}' 1.118 + * 1.119 + * choiceStyle: see {@link ChoiceFormat} 1.120 + * pluralStyle: see {@link PluralFormat} 1.121 + * selectStyle: see {@link SelectFormat} 1.122 + * 1.123 + * argNameOrNumber = argName | argNumber 1.124 + * argName = [^[[:Pattern_Syntax:][:Pattern_White_Space:]]]+ 1.125 + * argNumber = '0' | ('1'..'9' ('0'..'9')*) 1.126 + * 1.127 + * argType = "number" | "date" | "time" | "spellout" | "ordinal" | "duration" 1.128 + * argStyle = "short" | "medium" | "long" | "full" | "integer" | "currency" | "percent" | argStyleText 1.129 + * </pre> 1.130 + * 1.131 + * <ul> 1.132 + * <li>messageText can contain quoted literal strings including syntax characters. 1.133 + * A quoted literal string begins with an ASCII apostrophe and a syntax character 1.134 + * (usually a {curly brace}) and continues until the next single apostrophe. 1.135 + * A double ASCII apostrohpe inside or outside of a quoted string represents 1.136 + * one literal apostrophe. 1.137 + * <li>Quotable syntax characters are the {curly braces} in all messageText parts, 1.138 + * plus the '#' sign in a messageText immediately inside a pluralStyle, 1.139 + * and the '|' symbol in a messageText immediately inside a choiceStyle. 1.140 + * <li>See also {@link #UMessagePatternApostropheMode} 1.141 + * <li>In argStyleText, every single ASCII apostrophe begins and ends quoted literal text, 1.142 + * and unquoted {curly braces} must occur in matched pairs. 1.143 + * </ul> 1.144 + * 1.145 + * <p>Recommendation: Use the real apostrophe (single quote) character 1.146 + * \htmlonly’\endhtmlonly (U+2019) for 1.147 + * human-readable text, and use the ASCII apostrophe ' (U+0027) 1.148 + * only in program syntax, like quoting in MessageFormat. 1.149 + * See the annotations for U+0027 Apostrophe in The Unicode Standard. 1.150 + * 1.151 + * <p>The <code>choice</code> argument type is deprecated. 1.152 + * Use <code>plural</code> arguments for proper plural selection, 1.153 + * and <code>select</code> arguments for simple selection among a fixed set of choices. 1.154 + * 1.155 + * <p>The <code>argType</code> and <code>argStyle</code> values are used to create 1.156 + * a <code>Format</code> instance for the format element. The following 1.157 + * table shows how the values map to Format instances. Combinations not 1.158 + * shown in the table are illegal. Any <code>argStyleText</code> must 1.159 + * be a valid pattern string for the Format subclass used. 1.160 + * 1.161 + * <p><table border=1> 1.162 + * <tr> 1.163 + * <th>argType 1.164 + * <th>argStyle 1.165 + * <th>resulting Format object 1.166 + * <tr> 1.167 + * <td colspan=2><i>(none)</i> 1.168 + * <td><code>null</code> 1.169 + * <tr> 1.170 + * <td rowspan=5><code>number</code> 1.171 + * <td><i>(none)</i> 1.172 + * <td><code>NumberFormat.createInstance(getLocale(), status)</code> 1.173 + * <tr> 1.174 + * <td><code>integer</code> 1.175 + * <td><code>NumberFormat.createInstance(getLocale(), kNumberStyle, status)</code> 1.176 + * <tr> 1.177 + * <td><code>currency</code> 1.178 + * <td><code>NumberFormat.createCurrencyInstance(getLocale(), status)</code> 1.179 + * <tr> 1.180 + * <td><code>percent</code> 1.181 + * <td><code>NumberFormat.createPercentInstance(getLocale(), status)</code> 1.182 + * <tr> 1.183 + * <td><i>argStyleText</i> 1.184 + * <td><code>new DecimalFormat(argStyleText, new DecimalFormatSymbols(getLocale(), status), status)</code> 1.185 + * <tr> 1.186 + * <td rowspan=6><code>date</code> 1.187 + * <td><i>(none)</i> 1.188 + * <td><code>DateFormat.createDateInstance(kDefault, getLocale(), status)</code> 1.189 + * <tr> 1.190 + * <td><code>short</code> 1.191 + * <td><code>DateFormat.createDateInstance(kShort, getLocale(), status)</code> 1.192 + * <tr> 1.193 + * <td><code>medium</code> 1.194 + * <td><code>DateFormat.createDateInstance(kDefault, getLocale(), status)</code> 1.195 + * <tr> 1.196 + * <td><code>long</code> 1.197 + * <td><code>DateFormat.createDateInstance(kLong, getLocale(), status)</code> 1.198 + * <tr> 1.199 + * <td><code>full</code> 1.200 + * <td><code>DateFormat.createDateInstance(kFull, getLocale(), status)</code> 1.201 + * <tr> 1.202 + * <td><i>argStyleText</i> 1.203 + * <td><code>new SimpleDateFormat(argStyleText, getLocale(), status) 1.204 + * <tr> 1.205 + * <td rowspan=6><code>time</code> 1.206 + * <td><i>(none)</i> 1.207 + * <td><code>DateFormat.createTimeInstance(kDefault, getLocale(), status)</code> 1.208 + * <tr> 1.209 + * <td><code>short</code> 1.210 + * <td><code>DateFormat.createTimeInstance(kShort, getLocale(), status)</code> 1.211 + * <tr> 1.212 + * <td><code>medium</code> 1.213 + * <td><code>DateFormat.createTimeInstance(kDefault, getLocale(), status)</code> 1.214 + * <tr> 1.215 + * <td><code>long</code> 1.216 + * <td><code>DateFormat.createTimeInstance(kLong, getLocale(), status)</code> 1.217 + * <tr> 1.218 + * <td><code>full</code> 1.219 + * <td><code>DateFormat.createTimeInstance(kFull, getLocale(), status)</code> 1.220 + * <tr> 1.221 + * <td><i>argStyleText</i> 1.222 + * <td><code>new SimpleDateFormat(argStyleText, getLocale(), status) 1.223 + * <tr> 1.224 + * <td><code>spellout</code> 1.225 + * <td><i>argStyleText (optional)</i> 1.226 + * <td><code>new RuleBasedNumberFormat(URBNF_SPELLOUT, getLocale(), status) 1.227 + * <br/> .setDefaultRuleset(argStyleText, status);</code> 1.228 + * <tr> 1.229 + * <td><code>ordinal</code> 1.230 + * <td><i>argStyleText (optional)</i> 1.231 + * <td><code>new RuleBasedNumberFormat(URBNF_ORDINAL, getLocale(), status) 1.232 + * <br/> .setDefaultRuleset(argStyleText, status);</code> 1.233 + * <tr> 1.234 + * <td><code>duration</code> 1.235 + * <td><i>argStyleText (optional)</i> 1.236 + * <td><code>new RuleBasedNumberFormat(URBNF_DURATION, getLocale(), status) 1.237 + * <br/> .setDefaultRuleset(argStyleText, status);</code> 1.238 + * </table> 1.239 + * <p> 1.240 + * 1.241 + * <h4>Usage Information</h4> 1.242 + * 1.243 + * <p>Here are some examples of usage: 1.244 + * Example 1: 1.245 + * 1.246 + * <pre> 1.247 + * \code 1.248 + * UErrorCode success = U_ZERO_ERROR; 1.249 + * GregorianCalendar cal(success); 1.250 + * Formattable arguments[] = { 1.251 + * 7L, 1.252 + * Formattable( (Date) cal.getTime(success), Formattable::kIsDate), 1.253 + * "a disturbance in the Force" 1.254 + * }; 1.255 + * 1.256 + * UnicodeString result; 1.257 + * MessageFormat::format( 1.258 + * "At {1,time} on {1,date}, there was {2} on planet {0,number}.", 1.259 + * arguments, 3, result, success ); 1.260 + * 1.261 + * cout << "result: " << result << endl; 1.262 + * //<output>: At 4:34:20 PM on 23-Mar-98, there was a disturbance 1.263 + * // in the Force on planet 7. 1.264 + * \endcode 1.265 + * </pre> 1.266 + * 1.267 + * Typically, the message format will come from resources, and the 1.268 + * arguments will be dynamically set at runtime. 1.269 + * 1.270 + * <p>Example 2: 1.271 + * 1.272 + * <pre> 1.273 + * \code 1.274 + * success = U_ZERO_ERROR; 1.275 + * Formattable testArgs[] = {3L, "MyDisk"}; 1.276 + * 1.277 + * MessageFormat form( 1.278 + * "The disk \"{1}\" contains {0} file(s).", success ); 1.279 + * 1.280 + * UnicodeString string; 1.281 + * FieldPosition fpos = 0; 1.282 + * cout << "format: " << form.format(testArgs, 2, string, fpos, success ) << endl; 1.283 + * 1.284 + * // output, with different testArgs: 1.285 + * // output: The disk "MyDisk" contains 0 file(s). 1.286 + * // output: The disk "MyDisk" contains 1 file(s). 1.287 + * // output: The disk "MyDisk" contains 1,273 file(s). 1.288 + * \endcode 1.289 + * </pre> 1.290 + * 1.291 + * 1.292 + * <p>For messages that include plural forms, you can use a plural argument: 1.293 + * <pre> 1.294 + * \code 1.295 + * success = U_ZERO_ERROR; 1.296 + * MessageFormat msgFmt( 1.297 + * "{num_files, plural, " 1.298 + * "=0{There are no files on disk \"{disk_name}\".}" 1.299 + * "=1{There is one file on disk \"{disk_name}\".}" 1.300 + * "other{There are # files on disk \"{disk_name}\".}}", 1.301 + * Locale("en"), 1.302 + * success); 1.303 + * FieldPosition fpos = 0; 1.304 + * Formattable testArgs[] = {0L, "MyDisk"}; 1.305 + * UnicodeString testArgsNames[] = {"num_files", "disk_name"}; 1.306 + * UnicodeString result; 1.307 + * cout << msgFmt.format(testArgs, testArgsNames, 2, result, fpos, 0, success); 1.308 + * testArgs[0] = 3L; 1.309 + * cout << msgFmt.format(testArgs, testArgsNames, 2, result, fpos, 0, success); 1.310 + * \endcode 1.311 + * <em>output</em>: 1.312 + * There are no files on disk "MyDisk". 1.313 + * There are 3 files on "MyDisk". 1.314 + * </pre> 1.315 + * See {@link PluralFormat} and {@link PluralRules} for details. 1.316 + * 1.317 + * <h4><a name="synchronization">Synchronization</a></h4> 1.318 + * 1.319 + * <p>MessageFormats are not synchronized. 1.320 + * It is recommended to create separate format instances for each thread. 1.321 + * If multiple threads access a format concurrently, it must be synchronized 1.322 + * externally. 1.323 + * 1.324 + * @stable ICU 2.0 1.325 + */ 1.326 +class U_I18N_API MessageFormat : public Format { 1.327 +public: 1.328 +#ifndef U_HIDE_OBSOLETE_API 1.329 + /** 1.330 + * Enum type for kMaxFormat. 1.331 + * @obsolete ICU 3.0. The 10-argument limit was removed as of ICU 2.6, 1.332 + * rendering this enum type obsolete. 1.333 + */ 1.334 + enum EFormatNumber { 1.335 + /** 1.336 + * The maximum number of arguments. 1.337 + * @obsolete ICU 3.0. The 10-argument limit was removed as of ICU 2.6, 1.338 + * rendering this constant obsolete. 1.339 + */ 1.340 + kMaxFormat = 10 1.341 + }; 1.342 +#endif /* U_HIDE_OBSOLETE_API */ 1.343 + 1.344 + /** 1.345 + * Constructs a new MessageFormat using the given pattern and the 1.346 + * default locale. 1.347 + * 1.348 + * @param pattern Pattern used to construct object. 1.349 + * @param status Input/output error code. If the 1.350 + * pattern cannot be parsed, set to failure code. 1.351 + * @stable ICU 2.0 1.352 + */ 1.353 + MessageFormat(const UnicodeString& pattern, 1.354 + UErrorCode &status); 1.355 + 1.356 + /** 1.357 + * Constructs a new MessageFormat using the given pattern and locale. 1.358 + * @param pattern Pattern used to construct object. 1.359 + * @param newLocale The locale to use for formatting dates and numbers. 1.360 + * @param status Input/output error code. If the 1.361 + * pattern cannot be parsed, set to failure code. 1.362 + * @stable ICU 2.0 1.363 + */ 1.364 + MessageFormat(const UnicodeString& pattern, 1.365 + const Locale& newLocale, 1.366 + UErrorCode& status); 1.367 + /** 1.368 + * Constructs a new MessageFormat using the given pattern and locale. 1.369 + * @param pattern Pattern used to construct object. 1.370 + * @param newLocale The locale to use for formatting dates and numbers. 1.371 + * @param parseError Struct to receive information on the position 1.372 + * of an error within the pattern. 1.373 + * @param status Input/output error code. If the 1.374 + * pattern cannot be parsed, set to failure code. 1.375 + * @stable ICU 2.0 1.376 + */ 1.377 + MessageFormat(const UnicodeString& pattern, 1.378 + const Locale& newLocale, 1.379 + UParseError& parseError, 1.380 + UErrorCode& status); 1.381 + /** 1.382 + * Constructs a new MessageFormat from an existing one. 1.383 + * @stable ICU 2.0 1.384 + */ 1.385 + MessageFormat(const MessageFormat&); 1.386 + 1.387 + /** 1.388 + * Assignment operator. 1.389 + * @stable ICU 2.0 1.390 + */ 1.391 + const MessageFormat& operator=(const MessageFormat&); 1.392 + 1.393 + /** 1.394 + * Destructor. 1.395 + * @stable ICU 2.0 1.396 + */ 1.397 + virtual ~MessageFormat(); 1.398 + 1.399 + /** 1.400 + * Clones this Format object polymorphically. The caller owns the 1.401 + * result and should delete it when done. 1.402 + * @stable ICU 2.0 1.403 + */ 1.404 + virtual Format* clone(void) const; 1.405 + 1.406 + /** 1.407 + * Returns true if the given Format objects are semantically equal. 1.408 + * Objects of different subclasses are considered unequal. 1.409 + * @param other the object to be compared with. 1.410 + * @return true if the given Format objects are semantically equal. 1.411 + * @stable ICU 2.0 1.412 + */ 1.413 + virtual UBool operator==(const Format& other) const; 1.414 + 1.415 + /** 1.416 + * Sets the locale to be used for creating argument Format objects. 1.417 + * @param theLocale the new locale value to be set. 1.418 + * @stable ICU 2.0 1.419 + */ 1.420 + virtual void setLocale(const Locale& theLocale); 1.421 + 1.422 + /** 1.423 + * Gets the locale used for creating argument Format objects. 1.424 + * format information. 1.425 + * @return the locale of the object. 1.426 + * @stable ICU 2.0 1.427 + */ 1.428 + virtual const Locale& getLocale(void) const; 1.429 + 1.430 + /** 1.431 + * Applies the given pattern string to this message format. 1.432 + * 1.433 + * @param pattern The pattern to be applied. 1.434 + * @param status Input/output error code. If the 1.435 + * pattern cannot be parsed, set to failure code. 1.436 + * @stable ICU 2.0 1.437 + */ 1.438 + virtual void applyPattern(const UnicodeString& pattern, 1.439 + UErrorCode& status); 1.440 + /** 1.441 + * Applies the given pattern string to this message format. 1.442 + * 1.443 + * @param pattern The pattern to be applied. 1.444 + * @param parseError Struct to receive information on the position 1.445 + * of an error within the pattern. 1.446 + * @param status Input/output error code. If the 1.447 + * pattern cannot be parsed, set to failure code. 1.448 + * @stable ICU 2.0 1.449 + */ 1.450 + virtual void applyPattern(const UnicodeString& pattern, 1.451 + UParseError& parseError, 1.452 + UErrorCode& status); 1.453 + 1.454 + /** 1.455 + * Sets the UMessagePatternApostropheMode and the pattern used by this message format. 1.456 + * Parses the pattern and caches Format objects for simple argument types. 1.457 + * Patterns and their interpretation are specified in the 1.458 + * <a href="#patterns">class description</a>. 1.459 + * <p> 1.460 + * This method is best used only once on a given object to avoid confusion about the mode, 1.461 + * and after constructing the object with an empty pattern string to minimize overhead. 1.462 + * 1.463 + * @param pattern The pattern to be applied. 1.464 + * @param aposMode The new apostrophe mode. 1.465 + * @param parseError Struct to receive information on the position 1.466 + * of an error within the pattern. 1.467 + * Can be NULL. 1.468 + * @param status Input/output error code. If the 1.469 + * pattern cannot be parsed, set to failure code. 1.470 + * @stable ICU 4.8 1.471 + */ 1.472 + virtual void applyPattern(const UnicodeString& pattern, 1.473 + UMessagePatternApostropheMode aposMode, 1.474 + UParseError* parseError, 1.475 + UErrorCode& status); 1.476 + 1.477 + /** 1.478 + * @return this instance's UMessagePatternApostropheMode. 1.479 + * @stable ICU 4.8 1.480 + */ 1.481 + UMessagePatternApostropheMode getApostropheMode() const { 1.482 + return msgPattern.getApostropheMode(); 1.483 + } 1.484 + 1.485 + /** 1.486 + * Returns a pattern that can be used to recreate this object. 1.487 + * 1.488 + * @param appendTo Output parameter to receive the pattern. 1.489 + * Result is appended to existing contents. 1.490 + * @return Reference to 'appendTo' parameter. 1.491 + * @stable ICU 2.0 1.492 + */ 1.493 + virtual UnicodeString& toPattern(UnicodeString& appendTo) const; 1.494 + 1.495 + /** 1.496 + * Sets subformats. 1.497 + * See the class description about format numbering. 1.498 + * The caller should not delete the Format objects after this call. 1.499 + * <EM>The array formatsToAdopt is not itself adopted.</EM> Its 1.500 + * ownership is retained by the caller. If the call fails because 1.501 + * memory cannot be allocated, then the formats will be deleted 1.502 + * by this method, and this object will remain unchanged. 1.503 + * 1.504 + * <p>If this format uses named arguments, the new formats are discarded 1.505 + * and this format remains unchanged. 1.506 + * 1.507 + * @stable ICU 2.0 1.508 + * @param formatsToAdopt the format to be adopted. 1.509 + * @param count the size of the array. 1.510 + */ 1.511 + virtual void adoptFormats(Format** formatsToAdopt, int32_t count); 1.512 + 1.513 + /** 1.514 + * Sets subformats. 1.515 + * See the class description about format numbering. 1.516 + * Each item in the array is cloned into the internal array. 1.517 + * If the call fails because memory cannot be allocated, then this 1.518 + * object will remain unchanged. 1.519 + * 1.520 + * <p>If this format uses named arguments, the new formats are discarded 1.521 + * and this format remains unchanged. 1.522 + * 1.523 + * @stable ICU 2.0 1.524 + * @param newFormats the new format to be set. 1.525 + * @param cnt the size of the array. 1.526 + */ 1.527 + virtual void setFormats(const Format** newFormats, int32_t cnt); 1.528 + 1.529 + 1.530 + /** 1.531 + * Sets one subformat. 1.532 + * See the class description about format numbering. 1.533 + * The caller should not delete the Format object after this call. 1.534 + * If the number is over the number of formats already set, 1.535 + * the item will be deleted and ignored. 1.536 + * 1.537 + * <p>If this format uses named arguments, the new format is discarded 1.538 + * and this format remains unchanged. 1.539 + * 1.540 + * @stable ICU 2.0 1.541 + * @param formatNumber index of the subformat. 1.542 + * @param formatToAdopt the format to be adopted. 1.543 + */ 1.544 + virtual void adoptFormat(int32_t formatNumber, Format* formatToAdopt); 1.545 + 1.546 + /** 1.547 + * Sets one subformat. 1.548 + * See the class description about format numbering. 1.549 + * If the number is over the number of formats already set, 1.550 + * the item will be ignored. 1.551 + * @param formatNumber index of the subformat. 1.552 + * @param format the format to be set. 1.553 + * @stable ICU 2.0 1.554 + */ 1.555 + virtual void setFormat(int32_t formatNumber, const Format& format); 1.556 + 1.557 + /** 1.558 + * Gets format names. This function returns formatNames in StringEnumerations 1.559 + * which can be used with getFormat() and setFormat() to export formattable 1.560 + * array from current MessageFormat to another. It is the caller's responsibility 1.561 + * to delete the returned formatNames. 1.562 + * @param status output param set to success/failure code. 1.563 + * @stable ICU 4.0 1.564 + */ 1.565 + virtual StringEnumeration* getFormatNames(UErrorCode& status); 1.566 + 1.567 + /** 1.568 + * Gets subformat pointer for given format name. 1.569 + * This function supports both named and numbered 1.570 + * arguments. If numbered, the formatName is the 1.571 + * corresponding UnicodeStrings (e.g. "0", "1", "2"...). 1.572 + * The returned Format object should not be deleted by the caller, 1.573 + * nor should the ponter of other object . The pointer and its 1.574 + * contents remain valid only until the next call to any method 1.575 + * of this class is made with this object. 1.576 + * @param formatName the name or number specifying a format 1.577 + * @param status output param set to success/failure code. 1.578 + * @stable ICU 4.0 1.579 + */ 1.580 + virtual Format* getFormat(const UnicodeString& formatName, UErrorCode& status); 1.581 + 1.582 + /** 1.583 + * Sets one subformat for given format name. 1.584 + * See the class description about format name. 1.585 + * This function supports both named and numbered 1.586 + * arguments-- if numbered, the formatName is the 1.587 + * corresponding UnicodeStrings (e.g. "0", "1", "2"...). 1.588 + * If there is no matched formatName or wrong type, 1.589 + * the item will be ignored. 1.590 + * @param formatName Name of the subformat. 1.591 + * @param format the format to be set. 1.592 + * @param status output param set to success/failure code. 1.593 + * @stable ICU 4.0 1.594 + */ 1.595 + virtual void setFormat(const UnicodeString& formatName, const Format& format, UErrorCode& status); 1.596 + 1.597 + /** 1.598 + * Sets one subformat for given format name. 1.599 + * See the class description about format name. 1.600 + * This function supports both named and numbered 1.601 + * arguments-- if numbered, the formatName is the 1.602 + * corresponding UnicodeStrings (e.g. "0", "1", "2"...). 1.603 + * If there is no matched formatName or wrong type, 1.604 + * the item will be ignored. 1.605 + * The caller should not delete the Format object after this call. 1.606 + * @param formatName Name of the subformat. 1.607 + * @param formatToAdopt Format to be adopted. 1.608 + * @param status output param set to success/failure code. 1.609 + * @stable ICU 4.0 1.610 + */ 1.611 + virtual void adoptFormat(const UnicodeString& formatName, Format* formatToAdopt, UErrorCode& status); 1.612 + 1.613 + /** 1.614 + * Gets an array of subformats of this object. The returned array 1.615 + * should not be deleted by the caller, nor should the pointers 1.616 + * within the array. The array and its contents remain valid only 1.617 + * until the next call to this format. See the class description 1.618 + * about format numbering. 1.619 + * 1.620 + * @param count output parameter to receive the size of the array 1.621 + * @return an array of count Format* objects, or NULL if out of 1.622 + * memory. Any or all of the array elements may be NULL. 1.623 + * @stable ICU 2.0 1.624 + */ 1.625 + virtual const Format** getFormats(int32_t& count) const; 1.626 + 1.627 + 1.628 + using Format::format; 1.629 + 1.630 + /** 1.631 + * Formats the given array of arguments into a user-readable string. 1.632 + * Does not take ownership of the Formattable* array or its contents. 1.633 + * 1.634 + * <p>If this format uses named arguments, appendTo is unchanged and 1.635 + * status is set to U_ILLEGAL_ARGUMENT_ERROR. 1.636 + * 1.637 + * @param source An array of objects to be formatted. 1.638 + * @param count The number of elements of 'source'. 1.639 + * @param appendTo Output parameter to receive result. 1.640 + * Result is appended to existing contents. 1.641 + * @param ignore Not used; inherited from base class API. 1.642 + * @param status Input/output error code. If the 1.643 + * pattern cannot be parsed, set to failure code. 1.644 + * @return Reference to 'appendTo' parameter. 1.645 + * @stable ICU 2.0 1.646 + */ 1.647 + UnicodeString& format(const Formattable* source, 1.648 + int32_t count, 1.649 + UnicodeString& appendTo, 1.650 + FieldPosition& ignore, 1.651 + UErrorCode& status) const; 1.652 + 1.653 + /** 1.654 + * Formats the given array of arguments into a user-readable string 1.655 + * using the given pattern. 1.656 + * 1.657 + * <p>If this format uses named arguments, appendTo is unchanged and 1.658 + * status is set to U_ILLEGAL_ARGUMENT_ERROR. 1.659 + * 1.660 + * @param pattern The pattern. 1.661 + * @param arguments An array of objects to be formatted. 1.662 + * @param count The number of elements of 'source'. 1.663 + * @param appendTo Output parameter to receive result. 1.664 + * Result is appended to existing contents. 1.665 + * @param status Input/output error code. If the 1.666 + * pattern cannot be parsed, set to failure code. 1.667 + * @return Reference to 'appendTo' parameter. 1.668 + * @stable ICU 2.0 1.669 + */ 1.670 + static UnicodeString& format(const UnicodeString& pattern, 1.671 + const Formattable* arguments, 1.672 + int32_t count, 1.673 + UnicodeString& appendTo, 1.674 + UErrorCode& status); 1.675 + 1.676 + /** 1.677 + * Formats the given array of arguments into a user-readable 1.678 + * string. The array must be stored within a single Formattable 1.679 + * object of type kArray. If the Formattable object type is not of 1.680 + * type kArray, then returns a failing UErrorCode. 1.681 + * 1.682 + * <p>If this format uses named arguments, appendTo is unchanged and 1.683 + * status is set to U_ILLEGAL_ARGUMENT_ERROR. 1.684 + * 1.685 + * @param obj A Formattable of type kArray containing 1.686 + * arguments to be formatted. 1.687 + * @param appendTo Output parameter to receive result. 1.688 + * Result is appended to existing contents. 1.689 + * @param pos On input: an alignment field, if desired. 1.690 + * On output: the offsets of the alignment field. 1.691 + * @param status Input/output error code. If the 1.692 + * pattern cannot be parsed, set to failure code. 1.693 + * @return Reference to 'appendTo' parameter. 1.694 + * @stable ICU 2.0 1.695 + */ 1.696 + virtual UnicodeString& format(const Formattable& obj, 1.697 + UnicodeString& appendTo, 1.698 + FieldPosition& pos, 1.699 + UErrorCode& status) const; 1.700 + 1.701 + /** 1.702 + * Formats the given array of arguments into a user-defined argument name 1.703 + * array. This function supports both named and numbered 1.704 + * arguments-- if numbered, the formatName is the 1.705 + * corresponding UnicodeStrings (e.g. "0", "1", "2"...). 1.706 + * 1.707 + * @param argumentNames argument name array 1.708 + * @param arguments An array of objects to be formatted. 1.709 + * @param count The number of elements of 'argumentNames' and 1.710 + * arguments. The number of argumentNames and arguments 1.711 + * must be the same. 1.712 + * @param appendTo Output parameter to receive result. 1.713 + * Result is appended to existing contents. 1.714 + * @param status Input/output error code. If the 1.715 + * pattern cannot be parsed, set to failure code. 1.716 + * @return Reference to 'appendTo' parameter. 1.717 + * @stable ICU 4.0 1.718 + */ 1.719 + UnicodeString& format(const UnicodeString* argumentNames, 1.720 + const Formattable* arguments, 1.721 + int32_t count, 1.722 + UnicodeString& appendTo, 1.723 + UErrorCode& status) const; 1.724 + /** 1.725 + * Parses the given string into an array of output arguments. 1.726 + * 1.727 + * @param source String to be parsed. 1.728 + * @param pos On input, starting position for parse. On output, 1.729 + * final position after parse. Unchanged if parse 1.730 + * fails. 1.731 + * @param count Output parameter to receive the number of arguments 1.732 + * parsed. 1.733 + * @return an array of parsed arguments. The caller owns both 1.734 + * the array and its contents. 1.735 + * @stable ICU 2.0 1.736 + */ 1.737 + virtual Formattable* parse(const UnicodeString& source, 1.738 + ParsePosition& pos, 1.739 + int32_t& count) const; 1.740 + 1.741 + /** 1.742 + * Parses the given string into an array of output arguments. 1.743 + * 1.744 + * <p>If this format uses named arguments, status is set to 1.745 + * U_ARGUMENT_TYPE_MISMATCH. 1.746 + * 1.747 + * @param source String to be parsed. 1.748 + * @param count Output param to receive size of returned array. 1.749 + * @param status Input/output error code. If the 1.750 + * pattern cannot be parsed, set to failure code. 1.751 + * @return an array of parsed arguments. The caller owns both 1.752 + * the array and its contents. Returns NULL if status is not U_ZERO_ERROR. 1.753 + * 1.754 + * @stable ICU 2.0 1.755 + */ 1.756 + virtual Formattable* parse(const UnicodeString& source, 1.757 + int32_t& count, 1.758 + UErrorCode& status) const; 1.759 + 1.760 + /** 1.761 + * Parses the given string into an array of output arguments 1.762 + * stored within a single Formattable of type kArray. 1.763 + * 1.764 + * @param source The string to be parsed into an object. 1.765 + * @param result Formattable to be set to the parse result. 1.766 + * If parse fails, return contents are undefined. 1.767 + * @param pos On input, starting position for parse. On output, 1.768 + * final position after parse. Unchanged if parse 1.769 + * fails. 1.770 + * @stable ICU 2.0 1.771 + */ 1.772 + virtual void parseObject(const UnicodeString& source, 1.773 + Formattable& result, 1.774 + ParsePosition& pos) const; 1.775 + 1.776 + /** 1.777 + * Convert an 'apostrophe-friendly' pattern into a standard 1.778 + * pattern. Standard patterns treat all apostrophes as 1.779 + * quotes, which is problematic in some languages, e.g. 1.780 + * French, where apostrophe is commonly used. This utility 1.781 + * assumes that only an unpaired apostrophe immediately before 1.782 + * a brace is a true quote. Other unpaired apostrophes are paired, 1.783 + * and the resulting standard pattern string is returned. 1.784 + * 1.785 + * <p><b>Note</b> it is not guaranteed that the returned pattern 1.786 + * is indeed a valid pattern. The only effect is to convert 1.787 + * between patterns having different quoting semantics. 1.788 + * 1.789 + * @param pattern the 'apostrophe-friendly' patttern to convert 1.790 + * @param status Input/output error code. If the pattern 1.791 + * cannot be parsed, the failure code is set. 1.792 + * @return the standard equivalent of the original pattern 1.793 + * @stable ICU 3.4 1.794 + */ 1.795 + static UnicodeString autoQuoteApostrophe(const UnicodeString& pattern, 1.796 + UErrorCode& status); 1.797 + 1.798 + 1.799 + /** 1.800 + * Returns true if this MessageFormat uses named arguments, 1.801 + * and false otherwise. See class description. 1.802 + * 1.803 + * @return true if named arguments are used. 1.804 + * @stable ICU 4.0 1.805 + */ 1.806 + UBool usesNamedArguments() const; 1.807 + 1.808 + 1.809 +#ifndef U_HIDE_INTERNAL_API 1.810 + /** 1.811 + * This API is for ICU internal use only. 1.812 + * Please do not use it. 1.813 + * 1.814 + * Returns argument types count in the parsed pattern. 1.815 + * Used to distinguish pattern "{0} d" and "d". 1.816 + * 1.817 + * @return The number of formattable types in the pattern 1.818 + * @internal 1.819 + */ 1.820 + int32_t getArgTypeCount() const; 1.821 +#endif /* U_HIDE_INTERNAL_API */ 1.822 + 1.823 + /** 1.824 + * Returns a unique class ID POLYMORPHICALLY. Pure virtual override. 1.825 + * This method is to implement a simple version of RTTI, since not all 1.826 + * C++ compilers support genuine RTTI. Polymorphic operator==() and 1.827 + * clone() methods call this method. 1.828 + * 1.829 + * @return The class ID for this object. All objects of a 1.830 + * given class have the same class ID. Objects of 1.831 + * other classes have different class IDs. 1.832 + * @stable ICU 2.0 1.833 + */ 1.834 + virtual UClassID getDynamicClassID(void) const; 1.835 + 1.836 + /** 1.837 + * Return the class ID for this class. This is useful only for 1.838 + * comparing to a return value from getDynamicClassID(). For example: 1.839 + * <pre> 1.840 + * . Base* polymorphic_pointer = createPolymorphicObject(); 1.841 + * . if (polymorphic_pointer->getDynamicClassID() == 1.842 + * . Derived::getStaticClassID()) ... 1.843 + * </pre> 1.844 + * @return The class ID for all objects of this class. 1.845 + * @stable ICU 2.0 1.846 + */ 1.847 + static UClassID U_EXPORT2 getStaticClassID(void); 1.848 + 1.849 +#ifndef U_HIDE_INTERNAL_API 1.850 + /** 1.851 + * Compares two Format objects. This is used for constructing the hash 1.852 + * tables. 1.853 + * 1.854 + * @param left pointer to a Format object. Must not be NULL. 1.855 + * @param right pointer to a Format object. Must not be NULL. 1.856 + * 1.857 + * @return whether the two objects are the same 1.858 + * @internal 1.859 + */ 1.860 + static UBool equalFormats(const void* left, const void* right); 1.861 +#endif /* U_HIDE_INTERNAL_API */ 1.862 + 1.863 +private: 1.864 + 1.865 + Locale fLocale; 1.866 + MessagePattern msgPattern; 1.867 + Format** formatAliases; // see getFormats 1.868 + int32_t formatAliasesCapacity; 1.869 + 1.870 + MessageFormat(); // default constructor not implemented 1.871 + 1.872 + /** 1.873 + * This provider helps defer instantiation of a PluralRules object 1.874 + * until we actually need to select a keyword. 1.875 + * For example, if the number matches an explicit-value selector like "=1" 1.876 + * we do not need any PluralRules. 1.877 + */ 1.878 + class U_I18N_API PluralSelectorProvider : public PluralFormat::PluralSelector { 1.879 + public: 1.880 + PluralSelectorProvider(const MessageFormat &mf, UPluralType type); 1.881 + virtual ~PluralSelectorProvider(); 1.882 + virtual UnicodeString select(void *ctx, double number, UErrorCode& ec) const; 1.883 + 1.884 + void reset(); 1.885 + private: 1.886 + const MessageFormat &msgFormat; 1.887 + PluralRules* rules; 1.888 + UPluralType type; 1.889 + }; 1.890 + 1.891 + /** 1.892 + * A MessageFormat formats an array of arguments. Each argument 1.893 + * has an expected type, based on the pattern. For example, if 1.894 + * the pattern contains the subformat "{3,number,integer}", then 1.895 + * we expect argument 3 to have type Formattable::kLong. This 1.896 + * array needs to grow dynamically if the MessageFormat is 1.897 + * modified. 1.898 + */ 1.899 + Formattable::Type* argTypes; 1.900 + int32_t argTypeCount; 1.901 + int32_t argTypeCapacity; 1.902 + 1.903 + /** 1.904 + * TRUE if there are different argTypes for the same argument. 1.905 + * This only matters when the MessageFormat is used in the plain C (umsg_xxx) API 1.906 + * where the pattern argTypes determine how the va_arg list is read. 1.907 + */ 1.908 + UBool hasArgTypeConflicts; 1.909 + 1.910 + // Variable-size array management 1.911 + UBool allocateArgTypes(int32_t capacity, UErrorCode& status); 1.912 + 1.913 + /** 1.914 + * Default Format objects used when no format is specified and a 1.915 + * numeric or date argument is formatted. These are volatile 1.916 + * cache objects maintained only for performance. They do not 1.917 + * participate in operator=(), copy constructor(), nor 1.918 + * operator==(). 1.919 + */ 1.920 + NumberFormat* defaultNumberFormat; 1.921 + DateFormat* defaultDateFormat; 1.922 + 1.923 + UHashtable* cachedFormatters; 1.924 + UHashtable* customFormatArgStarts; 1.925 + 1.926 + PluralSelectorProvider pluralProvider; 1.927 + PluralSelectorProvider ordinalProvider; 1.928 + 1.929 + /** 1.930 + * Method to retrieve default formats (or NULL on failure). 1.931 + * These are semantically const, but may modify *this. 1.932 + */ 1.933 + const NumberFormat* getDefaultNumberFormat(UErrorCode&) const; 1.934 + const DateFormat* getDefaultDateFormat(UErrorCode&) const; 1.935 + 1.936 + /** 1.937 + * Finds the word s, in the keyword list and returns the located index. 1.938 + * @param s the keyword to be searched for. 1.939 + * @param list the list of keywords to be searched with. 1.940 + * @return the index of the list which matches the keyword s. 1.941 + */ 1.942 + static int32_t findKeyword( const UnicodeString& s, 1.943 + const UChar * const *list); 1.944 + 1.945 + /** 1.946 + * Thin wrapper around the format(... AppendableWrapper ...) variant. 1.947 + * Wraps the destination UnicodeString into an AppendableWrapper and 1.948 + * supplies default values for some other parameters. 1.949 + */ 1.950 + UnicodeString& format(const Formattable* arguments, 1.951 + const UnicodeString *argumentNames, 1.952 + int32_t cnt, 1.953 + UnicodeString& appendTo, 1.954 + FieldPosition* pos, 1.955 + UErrorCode& status) const; 1.956 + 1.957 + /** 1.958 + * Formats the arguments and writes the result into the 1.959 + * AppendableWrapper, updates the field position. 1.960 + * 1.961 + * @param msgStart Index to msgPattern part to start formatting from. 1.962 + * @param plNumber NULL except when formatting a plural argument sub-message 1.963 + * where a '#' is replaced by the format string for this number. 1.964 + * @param arguments The formattable objects array. (Must not be NULL.) 1.965 + * @param argumentNames NULL if numbered values are used. Otherwise the same 1.966 + * length as "arguments", and each entry is the name of the 1.967 + * corresponding argument in "arguments". 1.968 + * @param cnt The length of arguments (and of argumentNames if that is not NULL). 1.969 + * @param appendTo Output parameter to receive the result. 1.970 + * The result string is appended to existing contents. 1.971 + * @param pos Field position status. 1.972 + * @param success The error code status. 1.973 + */ 1.974 + void format(int32_t msgStart, 1.975 + const void *plNumber, 1.976 + const Formattable* arguments, 1.977 + const UnicodeString *argumentNames, 1.978 + int32_t cnt, 1.979 + AppendableWrapper& appendTo, 1.980 + FieldPosition* pos, 1.981 + UErrorCode& success) const; 1.982 + 1.983 + UnicodeString getArgName(int32_t partIndex); 1.984 + 1.985 + void setArgStartFormat(int32_t argStart, Format* formatter, UErrorCode& status); 1.986 + 1.987 + void setCustomArgStartFormat(int32_t argStart, Format* formatter, UErrorCode& status); 1.988 + 1.989 + int32_t nextTopLevelArgStart(int32_t partIndex) const; 1.990 + 1.991 + UBool argNameMatches(int32_t partIndex, const UnicodeString& argName, int32_t argNumber); 1.992 + 1.993 + void cacheExplicitFormats(UErrorCode& status); 1.994 + 1.995 + Format* createAppropriateFormat(UnicodeString& type, 1.996 + UnicodeString& style, 1.997 + Formattable::Type& formattableType, 1.998 + UParseError& parseError, 1.999 + UErrorCode& ec); 1.1000 + 1.1001 + const Formattable* getArgFromListByName(const Formattable* arguments, 1.1002 + const UnicodeString *argumentNames, 1.1003 + int32_t cnt, UnicodeString& name) const; 1.1004 + 1.1005 + Formattable* parse(int32_t msgStart, 1.1006 + const UnicodeString& source, 1.1007 + ParsePosition& pos, 1.1008 + int32_t& count, 1.1009 + UErrorCode& ec) const; 1.1010 + 1.1011 + FieldPosition* updateMetaData(AppendableWrapper& dest, int32_t prevLength, 1.1012 + FieldPosition* fp, const Formattable* argId) const; 1.1013 + 1.1014 + /** 1.1015 + * Finds the "other" sub-message. 1.1016 + * @param partIndex the index of the first PluralFormat argument style part. 1.1017 + * @return the "other" sub-message start part index. 1.1018 + */ 1.1019 + int32_t findOtherSubMessage(int32_t partIndex) const; 1.1020 + 1.1021 + /** 1.1022 + * Returns the ARG_START index of the first occurrence of the plural number in a sub-message. 1.1023 + * Returns -1 if it is a REPLACE_NUMBER. 1.1024 + * Returns 0 if there is neither. 1.1025 + */ 1.1026 + int32_t findFirstPluralNumberArg(int32_t msgStart, const UnicodeString &argName) const; 1.1027 + 1.1028 + Format* getCachedFormatter(int32_t argumentNumber) const; 1.1029 + 1.1030 + UnicodeString getLiteralStringUntilNextArgument(int32_t from) const; 1.1031 + 1.1032 + void copyObjects(const MessageFormat& that, UErrorCode& ec); 1.1033 + 1.1034 + void formatComplexSubMessage(int32_t msgStart, 1.1035 + const void *plNumber, 1.1036 + const Formattable* arguments, 1.1037 + const UnicodeString *argumentNames, 1.1038 + int32_t cnt, 1.1039 + AppendableWrapper& appendTo, 1.1040 + UErrorCode& success) const; 1.1041 + 1.1042 + /** 1.1043 + * Convenience method that ought to be in NumberFormat 1.1044 + */ 1.1045 + NumberFormat* createIntegerFormat(const Locale& locale, UErrorCode& status) const; 1.1046 + 1.1047 + /** 1.1048 + * Returns array of argument types in the parsed pattern 1.1049 + * for use in C API. Only for the use of umsg_vformat(). Not 1.1050 + * for public consumption. 1.1051 + * @param listCount Output parameter to receive the size of array 1.1052 + * @return The array of formattable types in the pattern 1.1053 + */ 1.1054 + const Formattable::Type* getArgTypeList(int32_t& listCount) const { 1.1055 + listCount = argTypeCount; 1.1056 + return argTypes; 1.1057 + } 1.1058 + 1.1059 + /** 1.1060 + * Resets the internal MessagePattern, and other associated caches. 1.1061 + */ 1.1062 + void resetPattern(); 1.1063 + 1.1064 + /** 1.1065 + * A DummyFormatter that we use solely to store a NULL value. UHash does 1.1066 + * not support storing NULL values. 1.1067 + */ 1.1068 + class U_I18N_API DummyFormat : public Format { 1.1069 + public: 1.1070 + virtual UBool operator==(const Format&) const; 1.1071 + virtual Format* clone() const; 1.1072 + virtual UnicodeString& format(const Formattable& obj, 1.1073 + UnicodeString& appendTo, 1.1074 + UErrorCode& status) const; 1.1075 + virtual UnicodeString& format(const Formattable&, 1.1076 + UnicodeString& appendTo, 1.1077 + FieldPosition&, 1.1078 + UErrorCode& status) const; 1.1079 + virtual UnicodeString& format(const Formattable& obj, 1.1080 + UnicodeString& appendTo, 1.1081 + FieldPositionIterator* posIter, 1.1082 + UErrorCode& status) const; 1.1083 + virtual void parseObject(const UnicodeString&, 1.1084 + Formattable&, 1.1085 + ParsePosition&) const; 1.1086 + }; 1.1087 + 1.1088 + friend class MessageFormatAdapter; // getFormatTypeList() access 1.1089 +}; 1.1090 + 1.1091 +U_NAMESPACE_END 1.1092 + 1.1093 +#endif /* #if !UCONFIG_NO_FORMATTING */ 1.1094 + 1.1095 +#endif // _MSGFMT 1.1096 +//eof