1 /* 2 ********************************************************************** 3 * Copyright (c) 2004-2015, International Business Machines 4 * Corporation and others. All Rights Reserved. 5 ********************************************************************** 6 * Author: Alan Liu 7 * Created: April 20, 2004 8 * Since: ICU 3.0 9 ********************************************************************** 10 */ 11 #ifndef MEASUREFORMAT_H 12 #define MEASUREFORMAT_H 13 14 #include "unicode/utypes.h" 15 16 #if !UCONFIG_NO_FORMATTING 17 18 #include "unicode/format.h" 19 #include "unicode/udat.h" 20 21 /** 22 * \file 23 * \brief C++ API: Formatter for measure objects. 24 */ 25 26 /** 27 * Constants for various widths. 28 * There are 4 widths: Wide, Short, Narrow, Numeric. 29 * For example, for English, when formatting "3 hours" 30 * Wide is "3 hours"; short is "3 hrs"; narrow is "3h"; 31 * formatting "3 hours 17 minutes" as numeric give "3:17" 32 * @stable ICU 53 33 */ 34 enum UMeasureFormatWidth { 35 36 // Wide, short, and narrow must be first and in this order. 37 /** 38 * Spell out measure units. 39 * @stable ICU 53 40 */ 41 UMEASFMT_WIDTH_WIDE, 42 43 /** 44 * Abbreviate measure units. 45 * @stable ICU 53 46 */ 47 UMEASFMT_WIDTH_SHORT, 48 49 /** 50 * Use symbols for measure units when possible. 51 * @stable ICU 53 52 */ 53 UMEASFMT_WIDTH_NARROW, 54 55 /** 56 * Completely omit measure units when possible. For example, format 57 * '5 hours, 37 minutes' as '5:37' 58 * @stable ICU 53 59 */ 60 UMEASFMT_WIDTH_NUMERIC, 61 62 /** 63 * Count of values in this enum. 64 * @stable ICU 53 65 */ 66 UMEASFMT_WIDTH_COUNT = 4 67 }; 68 /** @stable ICU 53 */ 69 typedef enum UMeasureFormatWidth UMeasureFormatWidth; 70 71 U_NAMESPACE_BEGIN 72 73 class Measure; 74 class MeasureUnit; 75 class NumberFormat; 76 class PluralRules; 77 class MeasureFormatCacheData; 78 class SharedNumberFormat; 79 class SharedPluralRules; 80 class QuantityFormatter; 81 class SimplePatternFormatter; 82 class ListFormatter; 83 class DateFormat; 84 85 /** 86 * 87 * A formatter for measure objects. 88 * 89 * @see Format 90 * @author Alan Liu 91 * @stable ICU 3.0 92 */ 93 class U_I18N_API MeasureFormat : public Format { 94 public: 95 using Format::parseObject; 96 using Format::format; 97 98 /** 99 * Constructor. 100 * @stable ICU 53 101 */ 102 MeasureFormat( 103 const Locale &locale, UMeasureFormatWidth width, UErrorCode &status); 104 105 /** 106 * Constructor. 107 * @stable ICU 53 108 */ 109 MeasureFormat( 110 const Locale &locale, 111 UMeasureFormatWidth width, 112 NumberFormat *nfToAdopt, 113 UErrorCode &status); 114 115 /** 116 * Copy constructor. 117 * @stable ICU 3.0 118 */ 119 MeasureFormat(const MeasureFormat &other); 120 121 /** 122 * Assignment operator. 123 * @stable ICU 3.0 124 */ 125 MeasureFormat &operator=(const MeasureFormat &rhs); 126 127 /** 128 * Destructor. 129 * @stable ICU 3.0 130 */ 131 virtual ~MeasureFormat(); 132 133 /** 134 * Return true if given Format objects are semantically equal. 135 * @stable ICU 53 136 */ 137 virtual UBool operator==(const Format &other) const; 138 139 /** 140 * Clones this object polymorphically. 141 * @stable ICU 53 142 */ 143 virtual Format *clone() const; 144 145 /** 146 * Formats object to produce a string. 147 * @stable ICU 53 148 */ 149 virtual UnicodeString &format( 150 const Formattable &obj, 151 UnicodeString &appendTo, 152 FieldPosition &pos, 153 UErrorCode &status) const; 154 155 /** 156 * Parse a string to produce an object. This implementation sets 157 * status to U_UNSUPPORTED_ERROR. 158 * 159 * @draft ICU 53 160 */ 161 virtual void parseObject( 162 const UnicodeString &source, 163 Formattable &reslt, 164 ParsePosition &pos) const; 165 166 /** 167 * Formats measure objects to produce a string. An example of such a 168 * formatted string is 3 meters, 3.5 centimeters. Measure objects appear 169 * in the formatted string in the same order they appear in the "measures" 170 * array. The NumberFormat of this object is used only to format the amount 171 * of the very last measure. The other amounts are formatted with zero 172 * decimal places while rounding toward zero. 173 * @param measures array of measure objects. 174 * @param measureCount the number of measure objects. 175 * @param appendTo formatted string appended here. 176 * @param pos the field position. 177 * @param status the error. 178 * @return appendTo reference 179 * 180 * @stable ICU 53 181 */ 182 UnicodeString &formatMeasures( 183 const Measure *measures, 184 int32_t measureCount, 185 UnicodeString &appendTo, 186 FieldPosition &pos, 187 UErrorCode &status) const; 188 189 #ifndef U_HIDE_DRAFT_API 190 /** 191 * Formats a single measure per unit. An example of such a 192 * formatted string is 3.5 meters per second. 193 * @param measure The measure object. In above example, 3.5 meters. 194 * @param perUnit The per unit. In above example, it is 195 * *MeasureUnit::createSecond(status). 196 * @param appendTo formatted string appended here. 197 * @param pos the field position. 198 * @param status the error. 199 * @return appendTo reference 200 * 201 * @draft ICU 55 202 */ 203 UnicodeString &formatMeasurePerUnit( 204 const Measure &measure, 205 const MeasureUnit &perUnit, 206 UnicodeString &appendTo, 207 FieldPosition &pos, 208 UErrorCode &status) const; 209 210 #endif /* U_HIDE_DRAFT_API */ 211 212 /** 213 * Return a formatter for CurrencyAmount objects in the given 214 * locale. 215 * @param locale desired locale 216 * @param ec input-output error code 217 * @return a formatter object, or NULL upon error 218 * @stable ICU 3.0 219 */ 220 static MeasureFormat* U_EXPORT2 createCurrencyFormat(const Locale& locale, 221 UErrorCode& ec); 222 223 /** 224 * Return a formatter for CurrencyAmount objects in the default 225 * locale. 226 * @param ec input-output error code 227 * @return a formatter object, or NULL upon error 228 * @stable ICU 3.0 229 */ 230 static MeasureFormat* U_EXPORT2 createCurrencyFormat(UErrorCode& ec); 231 232 /** 233 * Return the class ID for this class. This is useful only for comparing to 234 * a return value from getDynamicClassID(). For example: 235 * <pre> 236 * . Base* polymorphic_pointer = createPolymorphicObject(); 237 * . if (polymorphic_pointer->getDynamicClassID() == 238 * . erived::getStaticClassID()) ... 239 * </pre> 240 * @return The class ID for all objects of this class. 241 * @stable ICU 53 242 */ 243 static UClassID U_EXPORT2 getStaticClassID(void); 244 245 /** 246 * Returns a unique class ID POLYMORPHICALLY. Pure virtual override. This 247 * method is to implement a simple version of RTTI, since not all C++ 248 * compilers support genuine RTTI. Polymorphic operator==() and clone() 249 * methods call this method. 250 * 251 * @return The class ID for this object. All objects of a 252 * given class have the same class ID. Objects of 253 * other classes have different class IDs. 254 * @stable ICU 53 255 */ 256 virtual UClassID getDynamicClassID(void) const; 257 258 protected: 259 /** 260 * Default constructor. 261 * @stable ICU 3.0 262 */ 263 MeasureFormat(); 264 265 #ifndef U_HIDE_INTERNAL_API 266 267 /** 268 * ICU use only. 269 * Initialize or change MeasureFormat class from subclass. 270 * @internal. 271 */ 272 void initMeasureFormat( 273 const Locale &locale, 274 UMeasureFormatWidth width, 275 NumberFormat *nfToAdopt, 276 UErrorCode &status); 277 /** 278 * ICU use only. 279 * Allows subclass to change locale. Note that this method also changes 280 * the NumberFormat object. Returns TRUE if locale changed; FALSE if no 281 * change was made. 282 * @internal. 283 */ 284 UBool setMeasureFormatLocale(const Locale &locale, UErrorCode &status); 285 286 /** 287 * ICU use only. 288 * Let subclass change NumberFormat. 289 * @internal. 290 */ 291 void adoptNumberFormat(NumberFormat *nfToAdopt, UErrorCode &status); 292 293 /** 294 * ICU use only. 295 * @internal. 296 */ 297 const NumberFormat &getNumberFormat() const; 298 299 /** 300 * ICU use only. 301 * @internal. 302 */ 303 const PluralRules &getPluralRules() const; 304 305 /** 306 * ICU use only. 307 * @internal. 308 */ 309 Locale getLocale(UErrorCode &status) const; 310 311 /** 312 * ICU use only. 313 * @internal. 314 */ 315 const char *getLocaleID(UErrorCode &status) const; 316 317 #endif /* U_HIDE_INTERNAL_API */ 318 319 private: 320 const MeasureFormatCacheData *cache; 321 const SharedNumberFormat *numberFormat; 322 const SharedPluralRules *pluralRules; 323 UMeasureFormatWidth width; 324 325 // Declared outside of MeasureFormatSharedData because ListFormatter 326 // objects are relatively cheap to copy; therefore, they don't need to be 327 // shared across instances. 328 ListFormatter *listFormatter; 329 330 const SimplePatternFormatter *getFormatterOrNull( 331 const MeasureUnit &unit, UMeasureFormatWidth width, int32_t index) const; 332 333 const SimplePatternFormatter *getFormatter( 334 const MeasureUnit &unit, UMeasureFormatWidth width, int32_t index, 335 UErrorCode &errorCode) const; 336 337 const SimplePatternFormatter *getPluralFormatter( 338 const MeasureUnit &unit, UMeasureFormatWidth width, int32_t index, 339 UErrorCode &errorCode) const; 340 341 const SimplePatternFormatter *getPerFormatter( 342 UMeasureFormatWidth width, 343 UErrorCode &status) const; 344 345 int32_t withPerUnitAndAppend( 346 const UnicodeString &formatted, 347 const MeasureUnit &perUnit, 348 UnicodeString &appendTo, 349 UErrorCode &status) const; 350 351 UnicodeString &formatMeasure( 352 const Measure &measure, 353 const NumberFormat &nf, 354 UnicodeString &appendTo, 355 FieldPosition &pos, 356 UErrorCode &status) const; 357 358 UnicodeString &formatMeasuresSlowTrack( 359 const Measure *measures, 360 int32_t measureCount, 361 UnicodeString& appendTo, 362 FieldPosition& pos, 363 UErrorCode& status) const; 364 365 UnicodeString &formatNumeric( 366 const Formattable *hms, // always length 3: [0] is hour; [1] is 367 // minute; [2] is second. 368 int32_t bitMap, // 1=hour set, 2=minute set, 4=second set 369 UnicodeString &appendTo, 370 UErrorCode &status) const; 371 372 UnicodeString &formatNumeric( 373 UDate date, 374 const DateFormat &dateFmt, 375 UDateFormatField smallestField, 376 const Formattable &smallestAmount, 377 UnicodeString &appendTo, 378 UErrorCode &status) const; 379 }; 380 381 U_NAMESPACE_END 382 383 #endif // #if !UCONFIG_NO_FORMATTING 384 #endif // #ifndef MEASUREFORMAT_H 385