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